From 5a7073b66d6212ba4f58959e47b20835fa6380a9 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 19 Apr 2021 08:56:43 +0100 Subject: [PATCH 01/31] (feat) initial uniswap v3 commit --- package-lock.json | 5821 +++++++++++++++++++++- package.json | 6 +- src/app.js | 2 + src/routes/uniswap_v3.route.js | 681 +++ src/services/uniswap_v3.js | 276 + src/static/uniswap-v3/encodePriceSqrt.js | 16 + src/static/uniswap_v3_router_abi.json | 1195 +++++ 7 files changed, 7989 insertions(+), 8 deletions(-) create mode 100644 src/routes/uniswap_v3.route.js create mode 100644 src/services/uniswap_v3.js create mode 100644 src/static/uniswap-v3/encodePriceSqrt.js create mode 100644 src/static/uniswap_v3_router_abi.json diff --git a/package-lock.json b/package-lock.json index 8a94b52..bdf182d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,5824 @@ { "name": "gateway-api", - "version": "0.0.1", + "version": "0.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { - "yarn": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.10.tgz", - "integrity": "sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==" + "@babel/code-frame": { + "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.12.13" + } + }, + "@babel/compat-data": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", + "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==", + "dev": true + }, + "@babel/core": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.15.tgz", + "integrity": "sha512-6GXmNYeNjS2Uz+uls5jalOemgIhnTMeaXo+yBUA72kC2uX/8VW6XyhVIo2L8/q0goKQA3EVKx0KOQpVKSeWadQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.15", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.15", + "@babel/types": "^7.13.14", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.13.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", + "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", + "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", + "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.12", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", + "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.13.0", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", + "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "regexpu-core": "^4.7.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz", + "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", + "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz", + "integrity": "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==", + "dev": true, + "requires": { + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", + "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", + "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-wrap-function": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", + "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", + "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helpers": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", + "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", + "dev": true, + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/highlight": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/node": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.13.13.tgz", + "integrity": "sha512-gElSPunpriXoBGQxDkd5h9L13SVTyzFLTPv9jN1aXJNLR10iNs+MsfhYL/WGJGCJQFddHAdThY7CkmGVz2KPag==", + "dev": true, + "requires": { + "@babel/register": "^7.13.8", + "commander": "^4.0.1", + "core-js": "^3.2.1", + "node-environment-flags": "^1.0.5", + "regenerator-runtime": "^0.13.4", + "v8flags": "^3.1.1" + } + }, + "@babel/parser": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz", + "integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==", + "dev": true + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", + "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.13.12" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz", + "integrity": "sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", + "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", + "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", + "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", + "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", + "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", + "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", + "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", + "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.8", + "@babel/helper-compilation-targets": "^7.13.8", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.13.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", + "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", + "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", + "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", + "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", + "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", + "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", + "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", + "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz", + "integrity": "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", + "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", + "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz", + "integrity": "sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", + "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", + "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", + "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", + "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", + "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", + "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", + "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", + "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", + "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-simple-access": "^7.12.13", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", + "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.13.0", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-identifier": "^7.12.11", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", + "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", + "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", + "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", + "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", + "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", + "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz", + "integrity": "sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", + "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", + "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", + "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", + "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", + "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", + "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", + "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", + "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/preset-env": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.15.tgz", + "integrity": "sha512-D4JAPMXcxk69PKe81jRJ21/fP/uYdcTZ3hJDF5QX2HSI9bBxxYw/dumdR6dGumhjxlprHPE4XWoPaqzZUVy2MA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-async-generator-functions": "^7.13.15", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-dynamic-import": "^7.13.8", + "@babel/plugin-proposal-export-namespace-from": "^7.12.13", + "@babel/plugin-proposal-json-strings": "^7.13.8", + "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-numeric-separator": "^7.12.13", + "@babel/plugin-proposal-object-rest-spread": "^7.13.8", + "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-private-methods": "^7.13.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.12.13", + "@babel/plugin-transform-arrow-functions": "^7.13.0", + "@babel/plugin-transform-async-to-generator": "^7.13.0", + "@babel/plugin-transform-block-scoped-functions": "^7.12.13", + "@babel/plugin-transform-block-scoping": "^7.12.13", + "@babel/plugin-transform-classes": "^7.13.0", + "@babel/plugin-transform-computed-properties": "^7.13.0", + "@babel/plugin-transform-destructuring": "^7.13.0", + "@babel/plugin-transform-dotall-regex": "^7.12.13", + "@babel/plugin-transform-duplicate-keys": "^7.12.13", + "@babel/plugin-transform-exponentiation-operator": "^7.12.13", + "@babel/plugin-transform-for-of": "^7.13.0", + "@babel/plugin-transform-function-name": "^7.12.13", + "@babel/plugin-transform-literals": "^7.12.13", + "@babel/plugin-transform-member-expression-literals": "^7.12.13", + "@babel/plugin-transform-modules-amd": "^7.13.0", + "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/plugin-transform-modules-systemjs": "^7.13.8", + "@babel/plugin-transform-modules-umd": "^7.13.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", + "@babel/plugin-transform-new-target": "^7.12.13", + "@babel/plugin-transform-object-super": "^7.12.13", + "@babel/plugin-transform-parameters": "^7.13.0", + "@babel/plugin-transform-property-literals": "^7.12.13", + "@babel/plugin-transform-regenerator": "^7.13.15", + "@babel/plugin-transform-reserved-words": "^7.12.13", + "@babel/plugin-transform-shorthand-properties": "^7.12.13", + "@babel/plugin-transform-spread": "^7.13.0", + "@babel/plugin-transform-sticky-regex": "^7.12.13", + "@babel/plugin-transform-template-literals": "^7.13.0", + "@babel/plugin-transform-typeof-symbol": "^7.12.13", + "@babel/plugin-transform-unicode-escapes": "^7.12.13", + "@babel/plugin-transform-unicode-regex": "^7.12.13", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.13.14", + "babel-plugin-polyfill-corejs2": "^0.2.0", + "babel-plugin-polyfill-corejs3": "^0.2.0", + "babel-plugin-polyfill-regenerator": "^0.2.0", + "core-js-compat": "^3.9.0", + "semver": "^6.3.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/register": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.13.14.tgz", + "integrity": "sha512-iyw0hUwjh/fzN8qklVqZodbyWjEBOG0KdDnBOpv3zzIgK3NmuRXBmIXH39ZBdspkn8LTHvSboN+oYb4MT43+9Q==", + "dev": true, + "requires": { + "find-cache-dir": "^2.0.0", + "lodash": "^4.17.19", + "make-dir": "^2.1.0", + "pirates": "^4.0.0", + "source-map-support": "^0.5.16" + } + }, + "@babel/runtime": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz", + "integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.15", + "@babel/types": "^7.13.14", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", + "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@balancer-labs/sor": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@balancer-labs/sor/-/sor-0.3.3.tgz", + "integrity": "sha512-hdPp55A2Hw+Koq81nhqTy15jNRCDW1k5ZT47nk2uEx7N5D9GiAx4BCNDzTiuJLErj6QHJTbEKK7Y5jei702c4g==", + "requires": { + "bignumber.js": "^9.0.0", + "isomorphic-fetch": "^2.2.1" + } + }, + "@dabh/diagnostics": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", + "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + } + } + }, + "@ethersproject/abi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.0.tgz", + "integrity": "sha512-N/W9Sbn1/C6Kh2kuHRjf/hX6euMK4+9zdJRBB8sDWmihVntjUAfxbusGZKzDQD8i3szAHhTz8K7XADV5iFNfJw==", + "requires": { + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz", + "integrity": "sha512-8dJUnT8VNvPwWhYIau4dwp7qe1g+KgdRm4XTWvjkI9gAT2zZa90WF5ApdZ3vl1r6NDmnn6vUVvyphClRZRteTQ==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/networks": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/web": "^5.1.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.1.0.tgz", + "integrity": "sha512-qQDMkjGZSSJSKl6AnfTgmz9FSnzq3iEoEbHTYwjDlEAv+LNP7zd4ixCcVWlWyk+2siud856M5CRhAmPdupeN9w==", + "requires": { + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0" + } + }, + "@ethersproject/address": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.1.0.tgz", + "integrity": "sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/rlp": "^5.1.0" + } + }, + "@ethersproject/base64": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.1.0.tgz", + "integrity": "sha512-npD1bLvK4Bcxz+m4EMkx+F8Rd7CnqS9DYnhNu0/GlQBXhWjvfoAZzk5HJ0f1qeyp8d+A86PTuzLOGOXf4/CN8g==", + "requires": { + "@ethersproject/bytes": "^5.1.0" + } + }, + "@ethersproject/basex": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.1.0.tgz", + "integrity": "sha512-vBKr39bum7DDbOvkr1Sj19bRMEPA4FnST6Utt6xhDzI7o7L6QNkDn2yrCfP+hnvJGhZFKtLygWwqlTBZoBXYLg==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/properties": "^5.1.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.0.tgz", + "integrity": "sha512-wUvQlhTjPjFXIdLPOuTrFeQmSa6Wvls1bGXQNQWvB/SEn1NsTCE8PmumIEZxmOPjSHl1eV2uyHP5jBm5Cgj92Q==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", + "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/constants": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", + "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", + "requires": { + "@ethersproject/bignumber": "^5.1.0" + } + }, + "@ethersproject/contracts": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.1.1.tgz", + "integrity": "sha512-6WwktLJ0DFWU8pDkgH4IGttQHhQN4SnwKFu9h+QYVe48VGWtbDu4W8/q/7QA1u/HWlWMrKxqawPiZUJj0UMvOw==", + "requires": { + "@ethersproject/abi": "^5.1.0", + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/transactions": "^5.1.0" + } + }, + "@ethersproject/hash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz", + "integrity": "sha512-fNwry20yLLPpnRRwm3fBL+2ksgO+KMadxM44WJmRIoTKzy4269+rbq9KFoe2LTqq2CXJM2CE70beGaNrpuqflQ==", + "requires": { + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/hdnode": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.1.0.tgz", + "integrity": "sha512-obIWdlujloExPHWJGmhJO/sETOOo7SEb6qemV4f8kyFoXg+cJK+Ta9SvBrj7hsUK85n3LZeZJZRjjM7oez3Clg==", + "requires": { + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/basex": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/pbkdf2": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/sha2": "^5.1.0", + "@ethersproject/signing-key": "^5.1.0", + "@ethersproject/strings": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/wordlists": "^5.1.0" + } + }, + "@ethersproject/json-wallets": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.1.0.tgz", + "integrity": "sha512-00n2iBy27w8zrGZSiU762UOVuzCQZxUZxopsZC47++js6xUFuI74DHcJ5K/2pddlF1YBskvmMuboEu1geK8mnA==", + "requires": { + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/hdnode": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/pbkdf2": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/random": "^5.1.0", + "@ethersproject/strings": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "@ethersproject/keccak256": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.1.0.tgz", + "integrity": "sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "js-sha3": "0.5.7" + } + }, + "@ethersproject/logger": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", + "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" + }, + "@ethersproject/networks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.1.0.tgz", + "integrity": "sha512-A/NIrIED/G/IgU1XUukOA3WcFRxn2I4O5GxsYGA5nFlIi+UZWdGojs85I1VXkR1gX9eFnDXzjE6OtbgZHjFhIA==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/pbkdf2": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.1.0.tgz", + "integrity": "sha512-B8cUbHHTgs8OtgJIafrRcz/YPDobVd5Ru8gTnShOiM9EBuFpYHQpq3+8iQJ6pyczDu6HP/oc/njAsIBhwFZYew==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/sha2": "^5.1.0" + } + }, + "@ethersproject/properties": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.1.0.tgz", + "integrity": "sha512-519KKTwgmH42AQL3+GFV3SX6khYEfHsvI6v8HYejlkigSDuqttdgVygFTDsGlofNFchhDwuclrxQnD5B0YLNMg==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/providers": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.1.tgz", + "integrity": "sha512-+xWqQh4eLnAePRR5CHSySCVke//NxGSuQEUzGTdDtt0yCbizwlKGm7CrsU0zF8JUcKDrDh36ezzTicOMd5sl9w==", + "requires": { + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/basex": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/networks": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/random": "^5.1.0", + "@ethersproject/rlp": "^5.1.0", + "@ethersproject/sha2": "^5.1.0", + "@ethersproject/strings": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/web": "^5.1.0", + "bech32": "1.1.4", + "ws": "7.2.3" + }, + "dependencies": { + "ws": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" + } + } + }, + "@ethersproject/random": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.1.0.tgz", + "integrity": "sha512-+uuczLQZ4+no9cP6TCoCktXx0u2YbNaRT7lRkSt12d8263e702f0u+4JnnRO8Qmv5nylWJebnqCHzyxP+6mLqw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/rlp": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.1.0.tgz", + "integrity": "sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/sha2": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.1.0.tgz", + "integrity": "sha512-+fNSeZRstOpdRJpdGUkRONFCaiAqWkc91zXgg76Nlp5ndBQE25Kk5yK8gCPG1aGnCrbariiPr5j9DmrYH78JCA==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "hash.js": "1.1.3" + }, + "dependencies": { + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + } + } + }, + "@ethersproject/signing-key": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.1.0.tgz", + "integrity": "sha512-tE5LFlbmdObG8bY04NpuwPWSRPgEswfxweAI1sH7TbP0ml1elNfqcq7ii/3AvIN05i5U0Pkm3Tf8bramt8MmLw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "bn.js": "^4.4.0", + "elliptic": "6.5.4" + } + }, + "@ethersproject/solidity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.1.0.tgz", + "integrity": "sha512-kPodsGyo9zg1g9XSXp1lGhFaezBAUUsAUB1Vf6OkppE5Wksg4Et+x3kG4m7J/uShDMP2upkJtHNsIBK2XkVpKQ==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/sha2": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/strings": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.1.0.tgz", + "integrity": "sha512-perBZy0RrmmL0ejiFGUOlBVjMsUceqLut3OBP3zP96LhiJWWbS8u1NqQVgN4/Gyrbziuda66DxiQocXhsvx+Sw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/transactions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.1.1.tgz", + "integrity": "sha512-Nwgbp09ttIVN0OoUBatCXaHxR7grWPHbozJN8v7AXDLrl6nnOIBEMDh+yJTnosSQlFhcyjfTGGN+Mx6R8HdvMw==", + "requires": { + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/rlp": "^5.1.0", + "@ethersproject/signing-key": "^5.1.0" + } + }, + "@ethersproject/units": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.1.0.tgz", + "integrity": "sha512-isvJrx6qG0nKWfxsGORNjmOq/nh175fStfvRTA2xEKrGqx8JNJY83fswu4GkILowfriEM/eYpretfJnfzi7YhA==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/wallet": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.1.0.tgz", + "integrity": "sha512-ULmUtiYQLTUS+y3DgkLzRhFEK10zMwmjOthnjiZxee3Q/MVwr3rnmuAnXIUZrPjna6hvUPnyRIdW5XuF0Ld0YQ==", + "requires": { + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/hdnode": "^5.1.0", + "@ethersproject/json-wallets": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/random": "^5.1.0", + "@ethersproject/signing-key": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/wordlists": "^5.1.0" + } + }, + "@ethersproject/web": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.1.0.tgz", + "integrity": "sha512-LTeluWgTq04+RNqAkVhpydPcRZK/kKxD2Vy7PYGrAD27ABO9kTqTBKwiOuzTyAHKUQHfnvZbXmxBXJAGViSDcA==", + "requires": { + "@ethersproject/base64": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/wordlists": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.1.0.tgz", + "integrity": "sha512-NsUCi/TpBb+oTFvMSccUkJGtp5o/84eOyqp5q5aBeiNBSLkYyw21znRn9mAmxZgySpxgruVgKbaapnYPgvctPQ==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@perp/contract": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@perp/contract/-/contract-1.1.0.tgz", + "integrity": "sha512-79O3DoGYtC6Nu9TnzC6aUTwCuEfe3+CIZr9a27Uh26MQ0jHkCq2Rc4sz35k3ChuN9zL2ZmrsAR+mO785QGZFpw==" + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@terra-money/terra.js": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-0.5.13.tgz", + "integrity": "sha512-v2B+VqVar6gryTfpHsusmDn2WIRT23xnTKsxFn6G20WIN5XCeRQa84cnAlZHuNP9w5ejuvRmoHX0Wg6g1DJo3g==", + "requires": { + "axios": "^0.20.0", + "bech32": "^1.1.4", + "bip32": "^2.0.6", + "bip39": "^3.0.2", + "bufferutil": "^4.0.1", + "crypto-js": "3.3.0", + "decimal.js": "^10.2.1", + "post-message-stream": "^3.0.0", + "secp256k1": "^4.0.2", + "tmp": "^0.2.1", + "utf-8-validate": "^5.0.2", + "ws": "^7.3.1" + }, + "dependencies": { + "axios": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", + "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", + "requires": { + "follow-redirects": "^1.10.0" + } + } + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/node": { + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" + }, + "@uniswap/sdk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@uniswap/sdk/-/sdk-3.0.3.tgz", + "integrity": "sha512-t4s8bvzaCFSiqD2qfXIm3rWhbdnXp+QjD3/mRaeVDHK7zWevs6RGEb1ohMiNgOCTZANvBayb4j8p+XFdnMBadQ==", + "requires": { + "@uniswap/v2-core": "^1.0.0", + "big.js": "^5.2.2", + "decimal.js-light": "^2.5.0", + "jsbi": "^3.1.1", + "tiny-invariant": "^1.1.0", + "tiny-warning": "^1.0.3", + "toformat": "^2.0.0" + } + }, + "@uniswap/v2-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v2-core/-/v2-core-1.0.1.tgz", + "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "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", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "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.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==" + }, + "argle": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/argle/-/argle-1.1.1.tgz", + "integrity": "sha1-DP47wDLDay9IukK5wX+J9wYH6ZQ=", + "requires": { + "lodash.isfunction": "^3.0.8", + "lodash.isnumber": "^3.0.3" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + } + }, + "array-uniq": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz", + "integrity": "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0=" + }, + "array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "available-typed-arrays": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", + "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", + "requires": { + "array-filter": "^1.0.0" + } + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz", + "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.0", + "semver": "^6.1.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz", + "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.0", + "core-js-compat": "^3.9.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz", + "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip32": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", + "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", + "requires": { + "@types/node": "10.12.18", + "bs58check": "^2.1.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "tiny-secp256k1": "^1.1.3", + "typeforce": "^1.11.5", + "wif": "^2.0.6" + } + }, + "bip39": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.3.tgz", + "integrity": "sha512-P0dKrz4g0V0BjXfx7d9QNkJ/Txcz/k+hM9TnjqjUaXtuOfAvxXSw2rJw8DX0e3ZPwnK/IgDxoRqf0bvoVCqbMg==", + "requires": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + }, + "dependencies": { + "@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + } + } + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserslist": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", + "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001208", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.712", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001211", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001211.tgz", + "integrity": "sha512-v3GXWKofIkN3PkSidLI5d1oqeKNsam9nQkqieoMhP87nxOY0RPDC8X2+jcv8pjV4dRozPLSoMqNii9sDViOlIg==", + "dev": true + }, + "capture-console": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-console/-/capture-console-1.0.1.tgz", + "integrity": "sha1-22PDmscyOQGbrdf7sQFD7aOA/3E=", + "requires": { + "argle": "~1.1.1", + "lodash.isfunction": "~3.0.8", + "randomstring": "~1.1.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "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.1", + "color-string": "^1.5.2" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + } + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.10.1.tgz", + "integrity": "sha512-pwCxEXnj27XG47mu7SXAwhLP3L5CrlvCB91ANUkIz40P27kUcvNfSdvyZJ9CLHiVoKSp+TTChMQMSKQEH/IQxA==", + "dev": true + }, + "core-js-compat": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.10.1.tgz", + "integrity": "sha512-ZHQTdTPkqvw2CeHiZC970NNJcnwzT6YIueDMASKt+p3WbZsLXOcoD392SkcWhkC0wBBHhlfhqGKKsNCQUozYtg==", + "dev": true, + "requires": { + "browserslist": "^4.16.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "requires": { + "node-fetch": "2.6.1" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + } + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", + "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" + }, + "decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron-to-chromium": { + "version": "1.3.717", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz", + "integrity": "sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ==", + "dev": true + }, + "elliptic": { + "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.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } + } + }, + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "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 + }, + "eslint": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", + "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "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==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "globals": { + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", + "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "eslint-config-standard": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", + "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", + "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", + "dev": true + }, + "eslint-plugin-standard": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", + "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "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" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "ethers": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.2.tgz", + "integrity": "sha512-yM+2bINj7Li9jeKX+hGZ/rFTo6kXcCwZTcCBmAwS+J3bLfyGX/o21fcssuPb9kfR26suCV+98XTWIuTuGiDO5A==", + "requires": { + "@ethersproject/abi": "5.1.0", + "@ethersproject/abstract-provider": "5.1.0", + "@ethersproject/abstract-signer": "5.1.0", + "@ethersproject/address": "5.1.0", + "@ethersproject/base64": "5.1.0", + "@ethersproject/basex": "5.1.0", + "@ethersproject/bignumber": "5.1.0", + "@ethersproject/bytes": "5.1.0", + "@ethersproject/constants": "5.1.0", + "@ethersproject/contracts": "5.1.1", + "@ethersproject/hash": "5.1.0", + "@ethersproject/hdnode": "5.1.0", + "@ethersproject/json-wallets": "5.1.0", + "@ethersproject/keccak256": "5.1.0", + "@ethersproject/logger": "5.1.0", + "@ethersproject/networks": "5.1.0", + "@ethersproject/pbkdf2": "5.1.0", + "@ethersproject/properties": "5.1.0", + "@ethersproject/providers": "5.1.1", + "@ethersproject/random": "5.1.0", + "@ethersproject/rlp": "5.1.0", + "@ethersproject/sha2": "5.1.0", + "@ethersproject/signing-key": "5.1.0", + "@ethersproject/solidity": "5.1.0", + "@ethersproject/strings": "5.1.0", + "@ethersproject/transactions": "5.1.1", + "@ethersproject/units": "5.1.0", + "@ethersproject/wallet": "5.1.0", + "@ethersproject/web": "5.1.0", + "@ethersproject/wordlists": "5.1.0" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "express-ipfilter": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/express-ipfilter/-/express-ipfilter-1.2.0.tgz", + "integrity": "sha512-nPXKMuhqVjX7+Vny4XsrpdqlX4YAGcanE0gh5xzpfmNTsINGAgPnpk67kb0No3p1m4vGQQLU6hdaXRxsuGNlTA==", + "requires": { + "ip": "~1.1.0", + "lodash": "^4.17.11", + "proxy-addr": "^2.0.4", + "range_check": "^1.2.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, + "fecha": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", + "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-stream-rotator": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.5.7.tgz", + "integrity": "sha512-VYb3HZ/GiAGUCrfeakO8Mp54YGswNUHvL7P09WQcXAJNSj3iQ5QraYSp3cIn1MUyw6uzfgN/EFOarCNa4JvUHQ==", + "requires": { + "moment": "^2.11.2" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, + "follow-redirects": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", + "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dev": true, + "requires": { + "ini": "1.3.7" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "helmet": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.5.0.tgz", + "integrity": "sha512-GfxdTaKarneWOpxmiVb/1YsY+fIwDOxVUGrvNEM1MC8W6Z2PREfkXiWF4XHQdvkyXwUTHuY4DRwB0uH/Q6BVyQ==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "http-status-codes": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.1.4.tgz", + "integrity": "sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg==" + }, + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ip6": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/ip6/-/ip6-0.0.4.tgz", + "integrity": "sha1-RMWp23njnUBSAbTXjROzhw5I2zE=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "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==" + }, + "is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typed-array": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbi": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", + "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "logform": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", + "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "triple-beam": "^1.3.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "requires": { + "mime-db": "1.47.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "dev": true + }, + "nodemon": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", + "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", + "dev": true, + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "object-hash": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz", + "integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==" + }, + "object-inspect": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", + "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "object.values": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "requires": { + "fn.name": "1.x.x" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "post-message-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/post-message-stream/-/post-message-stream-3.0.0.tgz", + "integrity": "sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg=", + "requires": { + "readable-stream": "^2.1.4" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomstring": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.1.5.tgz", + "integrity": "sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM=", + "requires": { + "array-uniq": "1.0.2" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "range_check": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/range_check/-/range_check-1.4.0.tgz", + "integrity": "sha1-zYfHrGLEC6nfabhwPGBPYMN0hjU=", + "requires": { + "ip6": "0.0.4", + "ipaddr.js": "1.2" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.2.0.tgz", + "integrity": "sha1-irpJyRknmVhb3WQ+DMtQ6K53e6Q=" + } + } + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "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==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "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.1" + } + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "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=" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "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" + } + }, + "table": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.2.0.tgz", + "integrity": "sha512-WMBBLuauiLXJjth35K4vOnd/xkaZ/dxEcyoZ+YhxSwfxFqvh+av06+oRqIwbR14m1lENB1egSWOFv/bNEt2D8A==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ajv": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", + "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, + "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", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-secp256k1": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", + "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==", + "requires": { + "bindings": "^1.3.0", + "bn.js": "^4.11.8", + "create-hmac": "^1.1.7", + "elliptic": "^6.4.0", + "nan": "^2.13.2" + } + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", + "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typeforce": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", + "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dev": true, + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "utf-8-validate": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", + "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "util": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", + "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "wif": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", + "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", + "requires": { + "bs58check": "<3.0.0" + } + }, + "winston": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", + "requires": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + }, + "dependencies": { + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + } + } + }, + "winston-daily-rotate-file": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.2.tgz", + "integrity": "sha512-DpAz9djExzFGVGRIKCKzsjOQaIINbjOUJ8CRsZGz0SQOMMcO1kM7jqTdzQAM9CRTEksZV9bBw9TT0ddQBGxs9g==", + "requires": { + "file-stream-rotator": "^0.5.7", + "object-hash": "^2.0.1", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + } + }, + "winston-transport": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", + "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", + "requires": { + "readable-stream": "^2.3.7", + "triple-beam": "^1.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } } diff --git a/package.json b/package.json index e1efda5..1691477 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "@perp/contract": "^1.0.6", "@balancer-labs/sor": "^0.3.3", + "@perp/contract": "^1.0.6", "@terra-money/terra.js": "^0.5.8", "@uniswap/sdk": "^3.0.3", "app-root-path": "^3.0.0", @@ -21,6 +21,7 @@ "bignumber.js": "^9.0.0", "body-parser": "^1.19.0", "capture-console": "^1.0.1", + "cross-fetch": "^3.0.6", "debug": "^4.2.0", "dotenv": "^8.2.0", "ethers": "^5.0.14", @@ -32,8 +33,7 @@ "moment": "^2.29.1", "util": "^0.12.3", "winston": "^3.3.3", - "winston-daily-rotate-file": "^4.5.0", - "cross-fetch": "^3.0.6" + "winston-daily-rotate-file": "^4.5.0" }, "devDependencies": { "@babel/core": "^7.11.6", diff --git a/src/app.js b/src/app.js index 6b2e7a0..779b022 100644 --- a/src/app.js +++ b/src/app.js @@ -14,6 +14,7 @@ import balancerRoutes from './routes/balancer.route' import ethRoutes from './routes/eth.route' import terraRoutes from './routes/terra.route' import uniswapRoutes from './routes/uniswap.route' +import uniswapV3Routes from './routes/uniswap_v3.route' import perpFiRoutes from './routes/perpetual_finance.route' // terminate if environment not found @@ -42,6 +43,7 @@ app.use(validateAccess) // mount all routes to this path app.use('/uniswap', uniswapRoutes); +app.use('/uniswap/v3', uniswapV3Routes); app.use('/api', apiRoutes); app.use('/eth', ethRoutes); // app.use('/celo', celoRoutes); diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js new file mode 100644 index 0000000..3f0df74 --- /dev/null +++ b/src/routes/uniswap_v3.route.js @@ -0,0 +1,681 @@ +import { ethers } from 'ethers'; +import express from 'express'; + +import { getParamData, latency, statusMessages } from '../services/utils'; +import { logger } from '../services/logger'; +import Ethereum from '../services/eth'; +import UniswapV3 from '../services/uniswap_v3'; +import Fees from '../services/fees'; + +require('dotenv').config() + +const debug = require('debug')('router') +const router = express.Router() +const eth = new Ethereum(process.env.ETHEREUM_CHAIN) +const uniswap = new UniswapV3(process.env.ETHEREUM_CHAIN) +// uniswap.generate_tokens() +// setTimeout(uniswap.update_pairs.bind(uniswap), 2000) +const fees = new Fees() + +const swapMoreThanMaxPriceError = 'Price too high' +const swapLessThanMaxPriceError = 'Price too low' + +const estimateGasLimit = () => { + return uniswap.gasLimit +} + +const getErrorMessage = (err) => { + /* + [WIP] Custom error message based-on string match + */ + let message = err + if (err.includes('failed to meet quorum')) { + message = 'Failed to meet quorum in Uniswap' + } else if (err.includes('Invariant failed: ADDRESSES')) { + message = 'Invariant failed: ADDRESSES' + } else if (err.includes('"call revert exception')) { + message = statusMessages.no_pool_available + } else if (err.includes('"trade" is read-only')) { + message = statusMessages.no_pool_available + } + return message +} + +router.post('/', async (req, res) => { + /* + POST / + */ + res.status(200).json({ + network: uniswap.network, + provider: uniswap.provider.connection.url, + uniswap_router: uniswap.router, + connection: true, + timestamp: Date.now(), + }) +}) + +router.post('/gas-limit', async (req, res) => { + /* + POST: /buy-price + */ + const gasLimit = estimateGasLimit() + + try { + res.status(200).json({ + network: uniswap.network, + gasLimit: gasLimit, + timestamp: Date.now(), + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.get('/start', async (req, res) => { + /* + POST: /eth/uniswap/start + x-www-form-urlencoded: { + "pairs":"[ETH-USDT, ...]" + "gasPrice":30 + } + */ + const initTime = Date.now() + const paramData = getParamData(req.query) + const pairs = JSON.parse(paramData.pairs) + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + + // get token contract address and cache paths + for (let pair of pairs){ + pair = pair.split("-") + const baseTokenSymbol = pair[0] + const quoteTokenSymbol = pair[1] + const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) + + // check for valid token symbols + if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { + const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol + res.status(500).json({ + error: `Token ${undefinedToken} contract address not found`, + message: `Token contract address not found for ${undefinedToken}. Check token list source`, + }) + return + } + await Promise.allSettled([uniswap.extend_update_pairs([baseTokenContractInfo.address, quoteTokenContractInfo.address])]) + } + + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + + const result = { + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + success: true, + pairs: pairs, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + } + res.status(200).json(result) +}) + +router.post('/trade', async (req, res) => { + /* + POST: /trade + x-www-form-urlencoded: { + "quote":"BAT" + "base":"DAI" + "amount":0.1 + "limitPrice":1 + "gasPrice":10 + "privateKey":{{privateKey}} + "side":{buy|sell} + } + */ + const initTime = Date.now() + // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, uniswap.provider) + const amount = paramData.amount + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const side = paramData.side.toUpperCase() + + let limitPrice + if (paramData.limitPrice) { + limitPrice = parseFloat(paramData.limitPrice) + } + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + try { + // fetch the optimal pool mix from uniswap + const { trade, expectedAmount } = side === 'BUY' + ? await uniswap.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount + ) + : await uniswap.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount + ) + + if (side === 'BUY') { + const price = trade.executionPrice.invert().toSignificant(8) + logger.info(`uniswap.route - Price: ${price.toString()}`) + if (!limitPrice || price <= limitPrice) { + // pass swaps to exchange-proxy to complete trade + const tx = await uniswap.swapExactOut( + wallet, + trade, + baseTokenAddress, + gasPrice, + ) + // submit response + res.status(200).json({ + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenAddress, + quote: quoteTokenAddress, + amount: amount, + expectedIn: expectedAmount.toSignificant(8), + price: price, + gasPrice: gasPrice, + gasLimit, gasLimit, + gasCost, gasCost, + txHash: tx.hash, + }) + } else { + res.status(200).json({ + error: swapMoreThanMaxPriceError, + message: `Swap price ${price} exceeds limitPrice ${limitPrice}` + }) + logger.info(`uniswap.route - Swap price ${price} exceeds limitPrice ${limitPrice}`) + } + } else { + // sell + const price = trade.executionPrice.toSignificant(8) + logger.info(`Price: ${price.toString()}`) + if (!limitPrice || price >= limitPrice) { + // pass swaps to exchange-proxy to complete trade + const tx = await uniswap.swapExactIn( + wallet, + trade, + baseTokenAddress, + gasPrice, + ) + // submit response + res.status(200).json({ + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenAddress, + quote: quoteTokenAddress, + amount: parseFloat(paramData.amount), + expectedOut: expectedAmount.toSignificant(8), + price: parseFloat(price), + gasPrice: gasPrice, + gasLimit, gasLimit, + gasCost: gasCost, + txHash: tx.hash, + }) + } else { + res.status(200).json({ + error: swapLessThanMaxPriceError, + message: `Swap price ${price} lower than limitPrice ${limitPrice}` + }) + logger.info(`uniswap.route - Swap price ${price} lower than limitPrice ${limitPrice}`) + } + } + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/price', async (req, res) => { + /* + POST: /price + x-www-form-urlencoded: { + "quote":"BAT" + "base":"DAI" + "amount":1 + } + */ + const initTime = Date.now() + // params: base (required), quote (required), amount (required) + const paramData = getParamData(req.body) + const amount = paramData.amount + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const side = paramData.side.toUpperCase() + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + + try { + // fetch the optimal pool mix from uniswap + const { trade, expectedAmount } = side === 'BUY' + ? await uniswap.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount + ) + : await uniswap.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount + ) + + if (trade !== null && expectedAmount !== null) { + const price = side === 'BUY' + ? trade.executionPrice.invert().toSignificant(8) + : trade.executionPrice.toSignificant(8) + + const tradeAmount = parseFloat(amount) + const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)) + const tradePrice = parseFloat(price) + + const result = { + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenAddress, + quote: quoteTokenAddress, + amount: tradeAmount, + expectedAmount: expectedTradeAmount, + price: tradePrice, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + trade: trade, + } + debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) + res.status(200).json(result) + } else { // no pool available + res.status(200).json({ + info: statusMessages.no_pool_available, + message: '' + }) + } + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + let errCode = 500 + if (Object.keys(err).includes('isInsufficientReservesError')) { + errCode = 200 + reason = statusMessages.insufficient_reserves + ' in ' + side + ' at Uniswap' + } else if (Object.getOwnPropertyNames(err).includes('message')) { + reason = getErrorMessage(err.message) + if (reason === statusMessages.no_pool_available) { + errCode = 200 + res.status(errCode).json({ + info: reason, + message: err + }) + } + } else { + err.reason ? reason = err.reason : reason = statusMessages.operation_error + } + res.status(errCode).json({ + error: reason, + message: err + }) + } +}) + +// LP section + +router.post('/position', async (req, res) => { + /* + POST: /position + x-www-form-urlencoded: { + "tokenId":"tokenId" + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, uniswap.provider) + const tokenId = paramData.tokenId + + try { + // fetch position data + const positionData = await uniswap.getPosition(wallet, tokenId); + + const result = { + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + position: positionData + } + debug(`Position data: ${positionData} `) + res.status(200).json(result) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + res.status(200).json({ + info: statusMessages.operation_error, + message: err + }) + } +}) + +router.post('/add-position', async (req, res) => { + /* + POST: /add-position + x-www-form-urlencoded: { + "token0":"BAT" + "token1":"DAI" + "fee":1 + "tickLower": 1 + "tickUpper": 2 + "amount0": amount0 + "amount1": amount1 + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, uniswap.provider) + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const fee = paramData.fee + const tickLower = paramData.tickLower + const tickUpper = paramData.tickUpper + const amount0 = paramData.amount0 + const amount1 = paramData.amount1 + + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + + try { + // add position to pool + const newPosition = await uniswap.addPosition(wallet, baseTokenAddress, quoteTokenAddress, amount0, amount1, fee, tickLower, tickUpper); + + const result = { + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + token0: token0, + token1: token1, + fee: fee, + amount0: newPosition.amount0, + amount1: newPosition.amount1, + tickLower: tickLower, + tickUpper: tickUpper, + tokenId: newPosition.tokenId, + liquidity: newPosition.liquidity, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost + } + debug(`New Position: ${newPosition}`) + res.status(200).json(result) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + res.status(200).json({ + info: statusMessages.operation_error, + message: err + }) + } +}) + +router.post('/remove-position', async (req, res) => { + /* + POST: /position + x-www-form-urlencoded: { + "quote":"BAT" + "base":"DAI" + "amount":1 + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, uniswap.provider) + const amount = paramData.amount + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const side = paramData.side.toUpperCase() + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + + try { + // fetch the optimal pool mix from uniswap + const { trade, expectedAmount } = side === 'BUY' + ? await uniswap.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount + ) + : await uniswap.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount + ) + + if (trade !== null && expectedAmount !== null) { + const price = side === 'BUY' + ? trade.executionPrice.invert().toSignificant(8) + : trade.executionPrice.toSignificant(8) + + const tradeAmount = parseFloat(amount) + const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)) + const tradePrice = parseFloat(price) + + const result = { + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenAddress, + quote: quoteTokenAddress, + amount: tradeAmount, + expectedAmount: expectedTradeAmount, + price: tradePrice, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + trade: trade, + } + debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) + res.status(200).json(result) + } else { // no pool available + res.status(200).json({ + info: statusMessages.no_pool_available, + message: '' + }) + } + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + let errCode = 500 + if (Object.keys(err).includes('isInsufficientReservesError')) { + errCode = 200 + reason = statusMessages.insufficient_reserves + ' in ' + side + ' at Uniswap' + } else if (Object.getOwnPropertyNames(err).includes('message')) { + reason = getErrorMessage(err.message) + if (reason === statusMessages.no_pool_available) { + errCode = 200 + res.status(errCode).json({ + info: reason, + message: err + }) + } + } else { + err.reason ? reason = err.reason : reason = statusMessages.operation_error + } + res.status(errCode).json({ + error: reason, + message: err + }) + } +}) + +router.post('/adjust-liquidity', async (req, res) => { + /* + POST: /position + x-www-form-urlencoded: { + "action":"BUY"/"SELL" + "tokenId":"tokenId" + "amount0": amount0 + "amount1": amount1 + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, uniswap.provider) + const action = paramData.action.toUpperCase() + const tokenId = paramData.tokenId + const amount0 = paramData.amount0 + const amount1 = paramData.amount1 + + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + + try { + // fetch the optimal pool mix from uniswap + const positionChange = uniswap.adjustLiquidity(wallet, action, tokenId, amount0, amount1); + + const result = { + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + tokenId: tokenId, + amount0: positionChange.amount0, + amount1: positionChange.amount1, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + } + debug(`Position change ${positionChange}`) + res.status(200).json(result) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + res.status(200).json({ + info: statusMessages.operation_error, + message: err + }) + } +}) + +router.post('/collect-fees', async (req, res) => { + /* + POST: /position + x-www-form-urlencoded: { + "tokenId":"tokenId" + "amount0": amount0 + "amount1": amount1 + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, uniswap.provider) + const tokenId = paramData.tokenId + const amount0 = paramData.amount0 + const amount1 = paramData.amount1 + + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + + try { + // withdraw fees + const collect = uniswap.collectFees (wallet, tokenId, amount0, amount1); + + const result = { + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + tokenId: tokenId, + amount0: collect.amount0, + amount1: collect.amount1, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + } + debug(`Fees: ${collect}`) + res.status(200).json(result) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + res.status(200).json({ + info: statusMessages.operation_error, + message: err + }) + } +}) +export default router; diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js new file mode 100644 index 0000000..a9ed2b8 --- /dev/null +++ b/src/services/uniswap_v3.js @@ -0,0 +1,276 @@ +import { logger } from './logger'; + +const debug = require('debug')('router') +const math = require('mathjs') +const uni = require('@uniswap/sdk') +const ethers = require('ethers') +const routerArtifact = require('../static/uniswap_v3_router_abi.json') +// const routeTokens = require('../static/uniswap_route_tokens.json') + +// constants +const FeeAmount = { LOW: 500, MEDIUM: 3000, HIGH: 10000 }; +const ROUTER = process.env.UNISWAP_V3_ROUTER +const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 150688; +const TTL = process.env.UNISWAP_TTL || 300; +const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request + +export default class UniswapV3 { + constructor (network = 'mainnet') { + this.providerUrl = process.env.ETHEREUM_RPC_URL + this.network = process.env.ETHEREUM_CHAIN + this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) + this.router = ROUTER; + this.slippage = math.fraction(process.env.UNISWAP_ALLOWED_SLIPPAGE) + this.allowedSlippage = new uni.Percent(this.slippage.n, (this.slippage.d * 100)) + this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME + this.gasLimit = GAS_LIMIT + this.expireTokenPairUpdate = UPDATE_PERIOD + this.zeroReserveCheckInterval = process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL + this.zeroReservePairs = {} // No reserve pairs + this.tokenList = {} + this.pairs = [] + this.tokenSwapList = {} + this.cachedRoutes = {} + + switch (network) { + case 'mainnet': + this.chainID = uni.ChainId.MAINNET; + break; + case 'kovan': + this.chainID = uni.ChainId.KOVAN; + break; + default: + const err = `Invalid network ${network}` + logger.error(err) + throw Error(err) + } + } + + async fetch_route(tIn, tOut){ + var route, pair, pairOne, pairTwo + + try { + pair = await uni.Fetcher.fetchPairData(tIn, tOut); + route = new uni.Route([pair], tIn, tOut); + } + catch(err) { + logger.error(err); + } + return route; + } + + + generate_tokens(){ + for (let token of routeTokens[this.network]){ + this.tokenList[token["address"]] = new uni.Token(this.chainID, token["address"], token["decimals"], token["symbol"], token["name"]); + } + } + + async extend_update_pairs(tokens=[]){ + for (let token of tokens){ + if (!this.tokenList.hasOwnProperty(token)){ + this.tokenList[token] = await uni.Fetcher.fetchTokenData(this.chainID, token); + } + this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate; + } + } + + async update_pairs(){ + // Remove banned pairs after ban period + if (Object.keys(this.zeroReservePairs).length > 0){ + for (let pair in this.zeroReservePairs){ + if (this.zeroReservePairs[pair] <= Date.now()) { + delete this.zeroReservePairs[pair]; + // delete this.tokenList[token]; + } + } + } + // Generate all possible pair combinations of tokens + // This is done by generating an upper triangular matrix or right triangular matrix + if (Object.keys(this.tokenSwapList).length > 0){ + for (let token in this.tokenSwapList){ + if (this.tokenSwapList[token] <= Date.now()) { + delete this.tokenSwapList[token]; + // delete this.tokenList[token]; + } + } + + let tokens = Object.keys(this.tokenList); + var firstToken, secondToken, position; + let length = tokens.length; + let pairs = []; + let pairAddressRequests = []; + let pairAddressResponses = []; + for (firstToken = 0; firstToken < length; firstToken++){ + for (secondToken = firstToken + 1; secondToken < length; secondToken++){ + try{ + let pairString = this.tokenList[tokens[firstToken]].address + '-' + this.tokenList[tokens[secondToken]].address; + if (!this.zeroReservePairs.hasOwnProperty(pairString)){ + pairs.push(pairString); + pairAddressRequests.push(uni.Fetcher.fetchPairData(this.tokenList[tokens[firstToken]], this.tokenList[tokens[secondToken]])); + } + } + catch(err) { + logger.error(err); + } + } + } + + await Promise.allSettled(pairAddressRequests).then(values => { for (position = 0; position < pairAddressRequests.length; position++) { + if (values[position].status === "fulfilled"){pairAddressResponses.push(values[position].value)} + else {this.zeroReservePairs[pairs[position]] = Date.now() + this.zeroReserveCheckInterval;}}}) + this.pairs = pairAddressResponses; + } + setTimeout(this.update_pairs.bind(this), 1000); + } + + async priceSwapIn (tokenIn, tokenOut, tokenInAmount) { + await this.extend_update_pairs([tokenIn, tokenOut]); + const tIn = this.tokenList[tokenIn]; + const tOut = this.tokenList[tokenOut]; + const tokenAmountIn = new uni.TokenAmount(tIn, ethers.utils.parseUnits(tokenInAmount, tIn.decimals)); + if (this.pairs.length === 0){ + const route = await this.fetch_route(tIn, tOut); + const trade = uni.Trade.exactIn(route, tokenAmountIn); + if ( trade !== undefined ){ + const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; + return { trade, expectedAmount } + } + return "Can't find route to swap, kindly update " + } + const trade = uni.Trade.bestTradeExactIn(this.pairs, tokenAmountIn, this.tokenList[tokenOut], { maxHops: 5 })[0]; + if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} + else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} + const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); + return { trade, expectedAmount } + } + + async priceSwapOut (tokenIn, tokenOut, tokenOutAmount) { + await this.extend_update_pairs([tokenIn, tokenOut]); + const tOut = this.tokenList[tokenOut]; + const tIn = this.tokenList[tokenIn]; + const tokenAmountOut = new uni.TokenAmount(tOut, ethers.utils.parseUnits(tokenOutAmount, tOut.decimals)); + if (this.pairs.length === 0){ + const route = await this.fetch_route(tIn, tOut); + const trade = uni.Trade.exactOut(route, tokenAmountOut); + if ( trade !== undefined ){ + const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; + return { trade, expectedAmount } + } + return + } + const trade = uni.Trade.bestTradeExactOut(this.pairs, this.tokenList[tokenIn], tokenAmountOut, { maxHops: 5 })[0]; + if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} + else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} + const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); + return { trade, expectedAmount } + } + + async swapExactIn (wallet, trade, tokenAddress, gasPrice) { + const result = uni.Router.swapCallParameters( + trade, + { + ttl: TTL, + recipient: wallet.address, + allowedSlippage: this.allowedSlippage + } + ) + + const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet) + const tx = await contract.[result.methodName]( + ...result.args, + { + gasPrice: gasPrice * 1e9, + gasLimit: GAS_LIMIT, + value: result.value + } + ) + + debug(`Tx Hash: ${tx.hash}`); + return tx + } + + async swapExactOut (wallet, trade, tokenAddress, gasPrice) { + const result = uni.Router.swapCallParameters( + trade, + { + ttl: TTL, + recipient: wallet.address, + allowedSlippage: this.allowedSlippage + } + ) + + const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet) + const tx = await contract.[result.methodName]( + ...result.args, + { + gasPrice: gasPrice * 1e9, + gasLimit: GAS_LIMIT, + value: result.value + } + ) + + debug(`Tx Hash: ${tx.hash}`); + return tx + } + + // LP section + + async getPosition (wallet, tokenId) { + const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet); + return await contract.positions(tokenId); + } + + async addPosition (wallet, token0, token1, amount0, amount1, fee, tick0, tick1) { + const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet); + const priceSqrt = require('./uniswap-v3/encodePriceSqrt'); + const initPool = await contract.createAndInitializePoolIfNecessary( + token0.address, + token1.address, + FeeAmount.MEDIUM, + encodePriceSqrt(1, 1) + ); + console.log(initPool); + const mintTx = await contract.mint({ + token0: token0.address, + token1: token1.address, + tickLower: tick0, + tickUpper: tick1, + amount0Desired: amount0, + amount1Desired: amount1, + amount0Min: 0, + amount1Min: 0, + recipient: wallet.address, + deadline: TTL, + fee: fee + }); + return mintTx; + } + + async removePosition (wallet, tokenId) { + // Reduce position and burn + let positionData = this.getPosition(wallet, tokenId); + let amount0, amount1; + // calulate amount of token0 and token1 from position liquidity + + let decreaseTx = await contract.decreaseLiquidity(tokenId, amount0, amount1, amount0, amount1, TTL); + // To-Do: check success of decrease before burn + positionData = this.getPosition(wallet, tokenId); + return await contract.collect(tokenId, wallet.address, positionData.tokensOwed0, positionData.tokensOwed1); + } + + async adjustLiquidity (wallet, action, tokenId, amount0, amount1) { + const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet); + if (action === "INCREASE") { + return await contract.increaseLiquidity(tokenId, amount0, amount1, amount0Min, amount1Min, TTL); + } else { + return await contract.decreaseLiquidity(tokenId, amount0, amount1, amount0Min, amount1Min, TTL); + } + } + + async collectFees (wallet, tokenId, amount0, amount1) { + const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet); + return await contract.collect(tokenId, wallet.address, amount0, amount1); +} diff --git a/src/static/uniswap-v3/encodePriceSqrt.js b/src/static/uniswap-v3/encodePriceSqrt.js new file mode 100644 index 0000000..f95cd23 --- /dev/null +++ b/src/static/uniswap-v3/encodePriceSqrt.js @@ -0,0 +1,16 @@ +import bn from 'bignumber.js' +import { BigNumber, BigNumberish } from 'ethers' + +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }) + +// returns the sqrt price as a 64x96 +export function encodePriceSqrt(reserve1: BigNumberish, reserve0: BigNumberish): BigNumber { + return BigNumber.from( + new bn(reserve1.toString()) + .div(reserve0.toString()) + .sqrt() + .multipliedBy(new bn(2).pow(96)) + .integerValue(3) + .toString() + ) +} diff --git a/src/static/uniswap_v3_router_abi.json b/src/static/uniswap_v3_router_abi.json new file mode 100644 index 0000000..c5acf59 --- /dev/null +++ b/src/static/uniswap_v3_router_abi.json @@ -0,0 +1,1195 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_WETH9", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenDescriptor_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "DecreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "IncreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH9", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Max", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Max", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "createAndInitializePoolIfNecessary", + "outputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "decreaseLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "increaseLiquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct INonfungiblePositionManager.MintParams", + "name": "params", + "type": "tuple" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint96", + "name": "nonce", + "type": "uint96" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowedIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Owed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Owed", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] +} From 5e4b9743b572769e12b67253c2a2cb397490f68d Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 19 Apr 2021 09:05:11 +0100 Subject: [PATCH 02/31] Update package-lock --- package-lock.json | 5871 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 5866 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8a94b52..199add5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,5874 @@ { "name": "gateway-api", - "version": "0.0.1", + "version": "0.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { - "yarn": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.10.tgz", - "integrity": "sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==" + "@babel/code-frame": { + "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.12.13" + } + }, + "@babel/compat-data": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", + "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==", + "dev": true + }, + "@babel/core": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.15.tgz", + "integrity": "sha512-6GXmNYeNjS2Uz+uls5jalOemgIhnTMeaXo+yBUA72kC2uX/8VW6XyhVIo2L8/q0goKQA3EVKx0KOQpVKSeWadQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.15", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.15", + "@babel/types": "^7.13.14", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.13.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", + "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", + "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", + "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.12", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", + "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.13.0", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", + "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "regexpu-core": "^4.7.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz", + "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", + "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz", + "integrity": "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==", + "dev": true, + "requires": { + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", + "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", + "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-wrap-function": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", + "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", + "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helpers": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", + "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", + "dev": true, + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/highlight": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/node": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.13.13.tgz", + "integrity": "sha512-gElSPunpriXoBGQxDkd5h9L13SVTyzFLTPv9jN1aXJNLR10iNs+MsfhYL/WGJGCJQFddHAdThY7CkmGVz2KPag==", + "dev": true, + "requires": { + "@babel/register": "^7.13.8", + "commander": "^4.0.1", + "core-js": "^3.2.1", + "node-environment-flags": "^1.0.5", + "regenerator-runtime": "^0.13.4", + "v8flags": "^3.1.1" + } + }, + "@babel/parser": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz", + "integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==", + "dev": true + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", + "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.13.12" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz", + "integrity": "sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", + "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", + "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", + "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", + "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", + "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", + "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", + "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", + "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.8", + "@babel/helper-compilation-targets": "^7.13.8", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.13.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", + "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", + "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", + "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", + "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", + "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", + "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", + "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", + "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz", + "integrity": "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", + "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", + "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz", + "integrity": "sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", + "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", + "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", + "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", + "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", + "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", + "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", + "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", + "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", + "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-simple-access": "^7.12.13", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", + "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.13.0", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-identifier": "^7.12.11", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", + "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", + "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", + "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", + "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", + "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", + "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz", + "integrity": "sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", + "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", + "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", + "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", + "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", + "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", + "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", + "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", + "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/preset-env": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.15.tgz", + "integrity": "sha512-D4JAPMXcxk69PKe81jRJ21/fP/uYdcTZ3hJDF5QX2HSI9bBxxYw/dumdR6dGumhjxlprHPE4XWoPaqzZUVy2MA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-async-generator-functions": "^7.13.15", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-dynamic-import": "^7.13.8", + "@babel/plugin-proposal-export-namespace-from": "^7.12.13", + "@babel/plugin-proposal-json-strings": "^7.13.8", + "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-numeric-separator": "^7.12.13", + "@babel/plugin-proposal-object-rest-spread": "^7.13.8", + "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-private-methods": "^7.13.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.12.13", + "@babel/plugin-transform-arrow-functions": "^7.13.0", + "@babel/plugin-transform-async-to-generator": "^7.13.0", + "@babel/plugin-transform-block-scoped-functions": "^7.12.13", + "@babel/plugin-transform-block-scoping": "^7.12.13", + "@babel/plugin-transform-classes": "^7.13.0", + "@babel/plugin-transform-computed-properties": "^7.13.0", + "@babel/plugin-transform-destructuring": "^7.13.0", + "@babel/plugin-transform-dotall-regex": "^7.12.13", + "@babel/plugin-transform-duplicate-keys": "^7.12.13", + "@babel/plugin-transform-exponentiation-operator": "^7.12.13", + "@babel/plugin-transform-for-of": "^7.13.0", + "@babel/plugin-transform-function-name": "^7.12.13", + "@babel/plugin-transform-literals": "^7.12.13", + "@babel/plugin-transform-member-expression-literals": "^7.12.13", + "@babel/plugin-transform-modules-amd": "^7.13.0", + "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/plugin-transform-modules-systemjs": "^7.13.8", + "@babel/plugin-transform-modules-umd": "^7.13.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", + "@babel/plugin-transform-new-target": "^7.12.13", + "@babel/plugin-transform-object-super": "^7.12.13", + "@babel/plugin-transform-parameters": "^7.13.0", + "@babel/plugin-transform-property-literals": "^7.12.13", + "@babel/plugin-transform-regenerator": "^7.13.15", + "@babel/plugin-transform-reserved-words": "^7.12.13", + "@babel/plugin-transform-shorthand-properties": "^7.12.13", + "@babel/plugin-transform-spread": "^7.13.0", + "@babel/plugin-transform-sticky-regex": "^7.12.13", + "@babel/plugin-transform-template-literals": "^7.13.0", + "@babel/plugin-transform-typeof-symbol": "^7.12.13", + "@babel/plugin-transform-unicode-escapes": "^7.12.13", + "@babel/plugin-transform-unicode-regex": "^7.12.13", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.13.14", + "babel-plugin-polyfill-corejs2": "^0.2.0", + "babel-plugin-polyfill-corejs3": "^0.2.0", + "babel-plugin-polyfill-regenerator": "^0.2.0", + "core-js-compat": "^3.9.0", + "semver": "^6.3.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/register": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.13.14.tgz", + "integrity": "sha512-iyw0hUwjh/fzN8qklVqZodbyWjEBOG0KdDnBOpv3zzIgK3NmuRXBmIXH39ZBdspkn8LTHvSboN+oYb4MT43+9Q==", + "dev": true, + "requires": { + "find-cache-dir": "^2.0.0", + "lodash": "^4.17.19", + "make-dir": "^2.1.0", + "pirates": "^4.0.0", + "source-map-support": "^0.5.16" + } + }, + "@babel/runtime": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz", + "integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.15", + "@babel/types": "^7.13.14", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", + "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@balancer-labs/sor": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@balancer-labs/sor/-/sor-0.3.3.tgz", + "integrity": "sha512-hdPp55A2Hw+Koq81nhqTy15jNRCDW1k5ZT47nk2uEx7N5D9GiAx4BCNDzTiuJLErj6QHJTbEKK7Y5jei702c4g==", + "requires": { + "bignumber.js": "^9.0.0", + "isomorphic-fetch": "^2.2.1" + } + }, + "@dabh/diagnostics": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", + "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + } + } + }, + "@ethersproject/abi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.0.tgz", + "integrity": "sha512-N/W9Sbn1/C6Kh2kuHRjf/hX6euMK4+9zdJRBB8sDWmihVntjUAfxbusGZKzDQD8i3szAHhTz8K7XADV5iFNfJw==", + "requires": { + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz", + "integrity": "sha512-8dJUnT8VNvPwWhYIau4dwp7qe1g+KgdRm4XTWvjkI9gAT2zZa90WF5ApdZ3vl1r6NDmnn6vUVvyphClRZRteTQ==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/networks": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/web": "^5.1.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.1.0.tgz", + "integrity": "sha512-qQDMkjGZSSJSKl6AnfTgmz9FSnzq3iEoEbHTYwjDlEAv+LNP7zd4ixCcVWlWyk+2siud856M5CRhAmPdupeN9w==", + "requires": { + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0" + } + }, + "@ethersproject/address": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.1.0.tgz", + "integrity": "sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/rlp": "^5.1.0" + } + }, + "@ethersproject/base64": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.1.0.tgz", + "integrity": "sha512-npD1bLvK4Bcxz+m4EMkx+F8Rd7CnqS9DYnhNu0/GlQBXhWjvfoAZzk5HJ0f1qeyp8d+A86PTuzLOGOXf4/CN8g==", + "requires": { + "@ethersproject/bytes": "^5.1.0" + } + }, + "@ethersproject/basex": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.1.0.tgz", + "integrity": "sha512-vBKr39bum7DDbOvkr1Sj19bRMEPA4FnST6Utt6xhDzI7o7L6QNkDn2yrCfP+hnvJGhZFKtLygWwqlTBZoBXYLg==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/properties": "^5.1.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.0.tgz", + "integrity": "sha512-wUvQlhTjPjFXIdLPOuTrFeQmSa6Wvls1bGXQNQWvB/SEn1NsTCE8PmumIEZxmOPjSHl1eV2uyHP5jBm5Cgj92Q==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", + "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/constants": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", + "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", + "requires": { + "@ethersproject/bignumber": "^5.1.0" + } + }, + "@ethersproject/contracts": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.1.1.tgz", + "integrity": "sha512-6WwktLJ0DFWU8pDkgH4IGttQHhQN4SnwKFu9h+QYVe48VGWtbDu4W8/q/7QA1u/HWlWMrKxqawPiZUJj0UMvOw==", + "requires": { + "@ethersproject/abi": "^5.1.0", + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/transactions": "^5.1.0" + } + }, + "@ethersproject/hash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz", + "integrity": "sha512-fNwry20yLLPpnRRwm3fBL+2ksgO+KMadxM44WJmRIoTKzy4269+rbq9KFoe2LTqq2CXJM2CE70beGaNrpuqflQ==", + "requires": { + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/hdnode": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.1.0.tgz", + "integrity": "sha512-obIWdlujloExPHWJGmhJO/sETOOo7SEb6qemV4f8kyFoXg+cJK+Ta9SvBrj7hsUK85n3LZeZJZRjjM7oez3Clg==", + "requires": { + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/basex": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/pbkdf2": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/sha2": "^5.1.0", + "@ethersproject/signing-key": "^5.1.0", + "@ethersproject/strings": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/wordlists": "^5.1.0" + } + }, + "@ethersproject/json-wallets": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.1.0.tgz", + "integrity": "sha512-00n2iBy27w8zrGZSiU762UOVuzCQZxUZxopsZC47++js6xUFuI74DHcJ5K/2pddlF1YBskvmMuboEu1geK8mnA==", + "requires": { + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/hdnode": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/pbkdf2": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/random": "^5.1.0", + "@ethersproject/strings": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "@ethersproject/keccak256": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.1.0.tgz", + "integrity": "sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "js-sha3": "0.5.7" + } + }, + "@ethersproject/logger": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", + "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" + }, + "@ethersproject/networks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.1.0.tgz", + "integrity": "sha512-A/NIrIED/G/IgU1XUukOA3WcFRxn2I4O5GxsYGA5nFlIi+UZWdGojs85I1VXkR1gX9eFnDXzjE6OtbgZHjFhIA==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/pbkdf2": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.1.0.tgz", + "integrity": "sha512-B8cUbHHTgs8OtgJIafrRcz/YPDobVd5Ru8gTnShOiM9EBuFpYHQpq3+8iQJ6pyczDu6HP/oc/njAsIBhwFZYew==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/sha2": "^5.1.0" + } + }, + "@ethersproject/properties": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.1.0.tgz", + "integrity": "sha512-519KKTwgmH42AQL3+GFV3SX6khYEfHsvI6v8HYejlkigSDuqttdgVygFTDsGlofNFchhDwuclrxQnD5B0YLNMg==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/providers": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.1.tgz", + "integrity": "sha512-+xWqQh4eLnAePRR5CHSySCVke//NxGSuQEUzGTdDtt0yCbizwlKGm7CrsU0zF8JUcKDrDh36ezzTicOMd5sl9w==", + "requires": { + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/basex": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/networks": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/random": "^5.1.0", + "@ethersproject/rlp": "^5.1.0", + "@ethersproject/sha2": "^5.1.0", + "@ethersproject/strings": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/web": "^5.1.0", + "bech32": "1.1.4", + "ws": "7.2.3" + }, + "dependencies": { + "ws": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" + } + } + }, + "@ethersproject/random": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.1.0.tgz", + "integrity": "sha512-+uuczLQZ4+no9cP6TCoCktXx0u2YbNaRT7lRkSt12d8263e702f0u+4JnnRO8Qmv5nylWJebnqCHzyxP+6mLqw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/rlp": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.1.0.tgz", + "integrity": "sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/sha2": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.1.0.tgz", + "integrity": "sha512-+fNSeZRstOpdRJpdGUkRONFCaiAqWkc91zXgg76Nlp5ndBQE25Kk5yK8gCPG1aGnCrbariiPr5j9DmrYH78JCA==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "hash.js": "1.1.3" + }, + "dependencies": { + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + } + } + }, + "@ethersproject/signing-key": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.1.0.tgz", + "integrity": "sha512-tE5LFlbmdObG8bY04NpuwPWSRPgEswfxweAI1sH7TbP0ml1elNfqcq7ii/3AvIN05i5U0Pkm3Tf8bramt8MmLw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "bn.js": "^4.4.0", + "elliptic": "6.5.4" + } + }, + "@ethersproject/solidity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.1.0.tgz", + "integrity": "sha512-kPodsGyo9zg1g9XSXp1lGhFaezBAUUsAUB1Vf6OkppE5Wksg4Et+x3kG4m7J/uShDMP2upkJtHNsIBK2XkVpKQ==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/sha2": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/strings": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.1.0.tgz", + "integrity": "sha512-perBZy0RrmmL0ejiFGUOlBVjMsUceqLut3OBP3zP96LhiJWWbS8u1NqQVgN4/Gyrbziuda66DxiQocXhsvx+Sw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/transactions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.1.1.tgz", + "integrity": "sha512-Nwgbp09ttIVN0OoUBatCXaHxR7grWPHbozJN8v7AXDLrl6nnOIBEMDh+yJTnosSQlFhcyjfTGGN+Mx6R8HdvMw==", + "requires": { + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/rlp": "^5.1.0", + "@ethersproject/signing-key": "^5.1.0" + } + }, + "@ethersproject/units": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.1.0.tgz", + "integrity": "sha512-isvJrx6qG0nKWfxsGORNjmOq/nh175fStfvRTA2xEKrGqx8JNJY83fswu4GkILowfriEM/eYpretfJnfzi7YhA==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/wallet": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.1.0.tgz", + "integrity": "sha512-ULmUtiYQLTUS+y3DgkLzRhFEK10zMwmjOthnjiZxee3Q/MVwr3rnmuAnXIUZrPjna6hvUPnyRIdW5XuF0Ld0YQ==", + "requires": { + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/hdnode": "^5.1.0", + "@ethersproject/json-wallets": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/random": "^5.1.0", + "@ethersproject/signing-key": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/wordlists": "^5.1.0" + } + }, + "@ethersproject/web": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.1.0.tgz", + "integrity": "sha512-LTeluWgTq04+RNqAkVhpydPcRZK/kKxD2Vy7PYGrAD27ABO9kTqTBKwiOuzTyAHKUQHfnvZbXmxBXJAGViSDcA==", + "requires": { + "@ethersproject/base64": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/wordlists": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.1.0.tgz", + "integrity": "sha512-NsUCi/TpBb+oTFvMSccUkJGtp5o/84eOyqp5q5aBeiNBSLkYyw21znRn9mAmxZgySpxgruVgKbaapnYPgvctPQ==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@perp/contract": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@perp/contract/-/contract-1.1.0.tgz", + "integrity": "sha512-79O3DoGYtC6Nu9TnzC6aUTwCuEfe3+CIZr9a27Uh26MQ0jHkCq2Rc4sz35k3ChuN9zL2ZmrsAR+mO785QGZFpw==" + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@terra-money/terra.js": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-0.5.13.tgz", + "integrity": "sha512-v2B+VqVar6gryTfpHsusmDn2WIRT23xnTKsxFn6G20WIN5XCeRQa84cnAlZHuNP9w5ejuvRmoHX0Wg6g1DJo3g==", + "requires": { + "axios": "^0.20.0", + "bech32": "^1.1.4", + "bip32": "^2.0.6", + "bip39": "^3.0.2", + "bufferutil": "^4.0.1", + "crypto-js": "3.3.0", + "decimal.js": "^10.2.1", + "post-message-stream": "^3.0.0", + "secp256k1": "^4.0.2", + "tmp": "^0.2.1", + "utf-8-validate": "^5.0.2", + "ws": "^7.3.1" + }, + "dependencies": { + "axios": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", + "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", + "requires": { + "follow-redirects": "^1.10.0" + } + } + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/node": { + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" + }, + "@uniswap/sdk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@uniswap/sdk/-/sdk-3.0.3.tgz", + "integrity": "sha512-t4s8bvzaCFSiqD2qfXIm3rWhbdnXp+QjD3/mRaeVDHK7zWevs6RGEb1ohMiNgOCTZANvBayb4j8p+XFdnMBadQ==", + "requires": { + "@uniswap/v2-core": "^1.0.0", + "big.js": "^5.2.2", + "decimal.js-light": "^2.5.0", + "jsbi": "^3.1.1", + "tiny-invariant": "^1.1.0", + "tiny-warning": "^1.0.3", + "toformat": "^2.0.0" + } + }, + "@uniswap/v2-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v2-core/-/v2-core-1.0.1.tgz", + "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "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", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "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.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==" + }, + "argle": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/argle/-/argle-1.1.1.tgz", + "integrity": "sha1-DP47wDLDay9IukK5wX+J9wYH6ZQ=", + "requires": { + "lodash.isfunction": "^3.0.8", + "lodash.isnumber": "^3.0.3" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + } + }, + "array-uniq": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz", + "integrity": "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0=" + }, + "array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "available-typed-arrays": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", + "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", + "requires": { + "array-filter": "^1.0.0" + } + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz", + "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.0", + "semver": "^6.1.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz", + "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.0", + "core-js-compat": "^3.9.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz", + "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip32": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", + "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", + "requires": { + "@types/node": "10.12.18", + "bs58check": "^2.1.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "tiny-secp256k1": "^1.1.3", + "typeforce": "^1.11.5", + "wif": "^2.0.6" + } + }, + "bip39": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.3.tgz", + "integrity": "sha512-P0dKrz4g0V0BjXfx7d9QNkJ/Txcz/k+hM9TnjqjUaXtuOfAvxXSw2rJw8DX0e3ZPwnK/IgDxoRqf0bvoVCqbMg==", + "requires": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + }, + "dependencies": { + "@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + } + } + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserslist": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", + "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001208", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.712", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001211", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001211.tgz", + "integrity": "sha512-v3GXWKofIkN3PkSidLI5d1oqeKNsam9nQkqieoMhP87nxOY0RPDC8X2+jcv8pjV4dRozPLSoMqNii9sDViOlIg==", + "dev": true + }, + "capture-console": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-console/-/capture-console-1.0.1.tgz", + "integrity": "sha1-22PDmscyOQGbrdf7sQFD7aOA/3E=", + "requires": { + "argle": "~1.1.1", + "lodash.isfunction": "~3.0.8", + "randomstring": "~1.1.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "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.1", + "color-string": "^1.5.2" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "complex.js": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.12.tgz", + "integrity": "sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + } + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.10.1.tgz", + "integrity": "sha512-pwCxEXnj27XG47mu7SXAwhLP3L5CrlvCB91ANUkIz40P27kUcvNfSdvyZJ9CLHiVoKSp+TTChMQMSKQEH/IQxA==", + "dev": true + }, + "core-js-compat": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.10.1.tgz", + "integrity": "sha512-ZHQTdTPkqvw2CeHiZC970NNJcnwzT6YIueDMASKt+p3WbZsLXOcoD392SkcWhkC0wBBHhlfhqGKKsNCQUozYtg==", + "dev": true, + "requires": { + "browserslist": "^4.16.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "requires": { + "node-fetch": "2.6.1" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + } + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", + "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" + }, + "decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron-to-chromium": { + "version": "1.3.717", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz", + "integrity": "sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ==", + "dev": true + }, + "elliptic": { + "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.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } + } + }, + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" + }, + "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 + }, + "eslint": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", + "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "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==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "globals": { + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", + "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "eslint-config-standard": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", + "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", + "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", + "dev": true + }, + "eslint-plugin-standard": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", + "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "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" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "ethers": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.2.tgz", + "integrity": "sha512-yM+2bINj7Li9jeKX+hGZ/rFTo6kXcCwZTcCBmAwS+J3bLfyGX/o21fcssuPb9kfR26suCV+98XTWIuTuGiDO5A==", + "requires": { + "@ethersproject/abi": "5.1.0", + "@ethersproject/abstract-provider": "5.1.0", + "@ethersproject/abstract-signer": "5.1.0", + "@ethersproject/address": "5.1.0", + "@ethersproject/base64": "5.1.0", + "@ethersproject/basex": "5.1.0", + "@ethersproject/bignumber": "5.1.0", + "@ethersproject/bytes": "5.1.0", + "@ethersproject/constants": "5.1.0", + "@ethersproject/contracts": "5.1.1", + "@ethersproject/hash": "5.1.0", + "@ethersproject/hdnode": "5.1.0", + "@ethersproject/json-wallets": "5.1.0", + "@ethersproject/keccak256": "5.1.0", + "@ethersproject/logger": "5.1.0", + "@ethersproject/networks": "5.1.0", + "@ethersproject/pbkdf2": "5.1.0", + "@ethersproject/properties": "5.1.0", + "@ethersproject/providers": "5.1.1", + "@ethersproject/random": "5.1.0", + "@ethersproject/rlp": "5.1.0", + "@ethersproject/sha2": "5.1.0", + "@ethersproject/signing-key": "5.1.0", + "@ethersproject/solidity": "5.1.0", + "@ethersproject/strings": "5.1.0", + "@ethersproject/transactions": "5.1.1", + "@ethersproject/units": "5.1.0", + "@ethersproject/wallet": "5.1.0", + "@ethersproject/web": "5.1.0", + "@ethersproject/wordlists": "5.1.0" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "express-ipfilter": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/express-ipfilter/-/express-ipfilter-1.2.0.tgz", + "integrity": "sha512-nPXKMuhqVjX7+Vny4XsrpdqlX4YAGcanE0gh5xzpfmNTsINGAgPnpk67kb0No3p1m4vGQQLU6hdaXRxsuGNlTA==", + "requires": { + "ip": "~1.1.0", + "lodash": "^4.17.11", + "proxy-addr": "^2.0.4", + "range_check": "^1.2.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, + "fecha": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", + "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-stream-rotator": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.5.7.tgz", + "integrity": "sha512-VYb3HZ/GiAGUCrfeakO8Mp54YGswNUHvL7P09WQcXAJNSj3iQ5QraYSp3cIn1MUyw6uzfgN/EFOarCNa4JvUHQ==", + "requires": { + "moment": "^2.11.2" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, + "follow-redirects": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", + "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fraction.js": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz", + "integrity": "sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dev": true, + "requires": { + "ini": "1.3.7" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "helmet": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.5.0.tgz", + "integrity": "sha512-GfxdTaKarneWOpxmiVb/1YsY+fIwDOxVUGrvNEM1MC8W6Z2PREfkXiWF4XHQdvkyXwUTHuY4DRwB0uH/Q6BVyQ==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "http-status-codes": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.1.4.tgz", + "integrity": "sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg==" + }, + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ip6": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/ip6/-/ip6-0.0.4.tgz", + "integrity": "sha1-RMWp23njnUBSAbTXjROzhw5I2zE=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "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==" + }, + "is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typed-array": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" + }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbi": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", + "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "logform": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", + "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "triple-beam": "^1.3.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "mathjs": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-9.3.2.tgz", + "integrity": "sha512-0YKSKAeN9OkbIQrxfxnBT4kk/KlH71piWOsvVvAasyRIj/Xd/zlpc5VP/aFxwr+llOq2F3f6booPEu2fWv3yjQ==", + "requires": { + "complex.js": "^2.0.11", + "decimal.js": "^10.2.1", + "escape-latex": "^1.2.0", + "fraction.js": "^4.0.13", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^2.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "requires": { + "mime-db": "1.47.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "dev": true + }, + "nodemon": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", + "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", + "dev": true, + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "object-hash": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz", + "integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==" + }, + "object-inspect": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", + "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "object.values": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "requires": { + "fn.name": "1.x.x" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "post-message-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/post-message-stream/-/post-message-stream-3.0.0.tgz", + "integrity": "sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg=", + "requires": { + "readable-stream": "^2.1.4" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomstring": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.1.5.tgz", + "integrity": "sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM=", + "requires": { + "array-uniq": "1.0.2" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "range_check": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/range_check/-/range_check-1.4.0.tgz", + "integrity": "sha1-zYfHrGLEC6nfabhwPGBPYMN0hjU=", + "requires": { + "ip6": "0.0.4", + "ipaddr.js": "1.2" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.2.0.tgz", + "integrity": "sha1-irpJyRknmVhb3WQ+DMtQ6K53e6Q=" + } + } + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "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==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "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.1" + } + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "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=" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "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" + } + }, + "table": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.2.0.tgz", + "integrity": "sha512-WMBBLuauiLXJjth35K4vOnd/xkaZ/dxEcyoZ+YhxSwfxFqvh+av06+oRqIwbR14m1lENB1egSWOFv/bNEt2D8A==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ajv": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", + "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, + "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", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-secp256k1": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", + "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==", + "requires": { + "bindings": "^1.3.0", + "bn.js": "^4.11.8", + "create-hmac": "^1.1.7", + "elliptic": "^6.4.0", + "nan": "^2.13.2" + } + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", + "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typed-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-2.0.0.tgz", + "integrity": "sha512-Hhy1Iwo/e4AtLZNK10ewVVcP2UEs408DS35ubP825w/YgSBK1KVLwALvvIG4yX75QJrxjCpcWkzkVRB0BwwYlA==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typeforce": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", + "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dev": true, + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "utf-8-validate": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", + "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "util": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", + "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "wif": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", + "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", + "requires": { + "bs58check": "<3.0.0" + } + }, + "winston": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", + "requires": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + }, + "dependencies": { + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + } + } + }, + "winston-daily-rotate-file": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.2.tgz", + "integrity": "sha512-DpAz9djExzFGVGRIKCKzsjOQaIINbjOUJ8CRsZGz0SQOMMcO1kM7jqTdzQAM9CRTEksZV9bBw9TT0ddQBGxs9g==", + "requires": { + "file-stream-rotator": "^0.5.7", + "object-hash": "^2.0.1", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + } + }, + "winston-transport": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", + "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", + "requires": { + "readable-stream": "^2.3.7", + "triple-beam": "^1.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } } From ae5ca06e8d4af098ce306f55056fe0df85eb5eb3 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 19 Apr 2021 10:20:59 +0100 Subject: [PATCH 03/31] (feat) add new ropsten tokens to kovan file --- src/static/erc20_tokens_kovan.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/static/erc20_tokens_kovan.json b/src/static/erc20_tokens_kovan.json index d4bb4e5..f12f7a3 100644 --- a/src/static/erc20_tokens_kovan.json +++ b/src/static/erc20_tokens_kovan.json @@ -50,6 +50,16 @@ "symbol": "ZRX", "address": "0xccb0F4Cf5D3F97f4a55bb5f5cA321C3ED033f244", "decimals": 18 + }, + { + "symbol": "COIN1", + "address": "0xf7699696b7d92d9b4735bf1ddfdd92577b5869b0", + "decimals": 18 + }, + { + "symbol": "COIN2", + "address": "0xbab297ff0d366d9c2639cf291e5be4b2c7ca5ce2", + "decimals": 8 } ] } From 9cb5c5daafc2bd61f4d1ed7c891c12d091552651 Mon Sep 17 00:00:00 2001 From: vic-en Date: Thu, 29 Apr 2021 21:56:01 +0100 Subject: [PATCH 04/31] (feat) add uniswap v3 --- package-lock.json | 622 ++++++++++++++++++---- package.json | 12 +- src/routes/eth.route.js | 6 +- src/routes/uniswap_v3.route.js | 307 +++-------- src/services/eth.js | 11 +- src/services/uniswap_v3.js | 388 +++++++------- src/static/uniswap-v3/encodePriceSqrt.js | 16 - src/static/uniswap-v3/helper_functions.js | 132 +++++ yarn.lock | 27 +- 9 files changed, 989 insertions(+), 532 deletions(-) delete mode 100644 src/static/uniswap-v3/encodePriceSqrt.js create mode 100644 src/static/uniswap-v3/helper_functions.js diff --git a/package-lock.json b/package-lock.json index bdf182d..0a29fac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,26 +20,67 @@ "dev": true }, "@babel/core": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.15.tgz", - "integrity": "sha512-6GXmNYeNjS2Uz+uls5jalOemgIhnTMeaXo+yBUA72kC2uX/8VW6XyhVIo2L8/q0goKQA3EVKx0KOQpVKSeWadQ==", + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", + "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-compilation-targets": "^7.13.13", + "@babel/generator": "^7.13.16", + "@babel/helper-compilation-targets": "^7.13.16", "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.10", - "@babel/parser": "^7.13.15", + "@babel/helpers": "^7.13.16", + "@babel/parser": "^7.13.16", "@babel/template": "^7.12.13", "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.14", + "@babel/types": "^7.13.16", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", "semver": "^6.3.0", "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", + "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", + "dev": true, + "requires": { + "@babel/types": "^7.13.16", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", + "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + } + }, + "@babel/parser": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", + "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==", + "dev": true + }, + "@babel/types": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", + "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/generator": { @@ -286,14 +327,59 @@ } }, "@babel/helpers": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", - "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", + "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", "dev": true, "requires": { "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/traverse": "^7.13.17", + "@babel/types": "^7.13.17" + }, + "dependencies": { + "@babel/generator": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", + "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", + "dev": true, + "requires": { + "@babel/types": "^7.13.16", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/parser": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", + "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==", + "dev": true + }, + "@babel/traverse": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", + "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.16", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.16", + "@babel/types": "^7.13.17", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", + "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/highlight": { @@ -1091,9 +1177,9 @@ } }, "@ethersproject/abi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.0.tgz", - "integrity": "sha512-N/W9Sbn1/C6Kh2kuHRjf/hX6euMK4+9zdJRBB8sDWmihVntjUAfxbusGZKzDQD8i3szAHhTz8K7XADV5iFNfJw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.2.tgz", + "integrity": "sha512-uMhoQVPX0UtfzTpekYQSEUcJGDgsJ25ifz+SV6PDETWaUFhcR8RNgb1QPTASP13inW8r6iy0/Xdq9D5hK2pNvA==", "requires": { "@ethersproject/address": "^5.1.0", "@ethersproject/bignumber": "^5.1.0", @@ -1298,9 +1384,9 @@ } }, "@ethersproject/providers": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.1.tgz", - "integrity": "sha512-+xWqQh4eLnAePRR5CHSySCVke//NxGSuQEUzGTdDtt0yCbizwlKGm7CrsU0zF8JUcKDrDh36ezzTicOMd5sl9w==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.2.tgz", + "integrity": "sha512-GqsS8rd+eyd4eNkcNgzZ4l9IRULBPUZa7JPnv22k4MHflMobUseyhfbVnmoN5bVNNkOxjV1IPTw9i0sV1hwdpg==", "requires": { "@ethersproject/abstract-provider": "^5.1.0", "@ethersproject/abstract-signer": "^5.1.0", @@ -1475,6 +1561,11 @@ "@ethersproject/strings": "^5.1.0" } }, + "@openzeppelin/contracts": { + "version": "3.4.1-solc-0.7-2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz", + "integrity": "sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q==" + }, "@perp/contract": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@perp/contract/-/contract-1.1.0.tgz", @@ -1496,31 +1587,28 @@ } }, "@terra-money/terra.js": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-0.5.13.tgz", - "integrity": "sha512-v2B+VqVar6gryTfpHsusmDn2WIRT23xnTKsxFn6G20WIN5XCeRQa84cnAlZHuNP9w5ejuvRmoHX0Wg6g1DJo3g==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-1.7.0.tgz", + "integrity": "sha512-VlBgDihBVEqI32i+jk2j56iOJGvv8InY+Qktg9Hjj7kzCgJTbzI7sI5zQU1OEZdRIQ9c5Vm+oPFBJuCFu6i8ag==", "requires": { - "axios": "^0.20.0", - "bech32": "^1.1.4", + "axios": "^0.21.1", + "bech32": "^2.0.0", "bip32": "^2.0.6", - "bip39": "^3.0.2", + "bip39": "^3.0.3", "bufferutil": "^4.0.1", "crypto-js": "3.3.0", "decimal.js": "^10.2.1", - "post-message-stream": "^3.0.0", + "readable-stream": "^3.6.0", "secp256k1": "^4.0.2", "tmp": "^0.2.1", "utf-8-validate": "^5.0.2", - "ws": "^7.3.1" + "ws": "^7.4.2" }, "dependencies": { - "axios": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", - "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", - "requires": { - "follow-redirects": "^1.10.0" - } + "bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" } } }, @@ -1535,6 +1623,11 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" }, + "@uniswap/lib": { + "version": "4.0.1-alpha", + "resolved": "https://registry.npmjs.org/@uniswap/lib/-/lib-4.0.1-alpha.tgz", + "integrity": "sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==" + }, "@uniswap/sdk": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@uniswap/sdk/-/sdk-3.0.3.tgz", @@ -1549,17 +1642,69 @@ "toformat": "^2.0.0" } }, + "@uniswap/sdk-core": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@uniswap/sdk-core/-/sdk-core-1.0.10.tgz", + "integrity": "sha512-8aD3xkzNDI3Ffh7PdLIcmraZr/6knqQuamVOv96EN8lhouEYH2ZuRbBWb7eZa/W7NwOLjlXM7XHi5gWJKzvbkg==", + "requires": { + "@ethersproject/address": "^5.0.2", + "big.js": "^5.2.2", + "decimal.js-light": "^2.5.0", + "jsbi": "^3.1.4", + "tiny-invariant": "^1.1.0", + "toformat": "^2.0.0" + } + }, "@uniswap/v2-core": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@uniswap/v2-core/-/v2-core-1.0.1.tgz", "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==" }, + "@uniswap/v3-core": { + "version": "1.0.0-rc.2", + "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0-rc.2.tgz", + "integrity": "sha512-vsqkqAHPCKsVi0nWwWeX+mHnSTJ8ZUdu1zAVXB9Mj9A+aeBQGV9foRKs9ufDGJq7S1nqmz+7FdjSOcVoeiUqgQ==" + }, + "@uniswap/v3-periphery": { + "version": "1.0.0-beta.23", + "resolved": "https://registry.npmjs.org/@uniswap/v3-periphery/-/v3-periphery-1.0.0-beta.23.tgz", + "integrity": "sha512-5cvK8/ITIVql+iZdPd0TR5EiNNm55ejAspjIxcsnGKyflaeQb+ePw6X4HTruTPGvPoaFvk+UirYeezUspXhlcg==", + "requires": { + "@openzeppelin/contracts": "3.4.1-solc-0.7-2", + "@uniswap/lib": "^4.0.1-alpha", + "@uniswap/v2-core": "1.0.1", + "@uniswap/v3-core": "1.0.0-rc.2", + "base64-sol": "1.0.1" + } + }, + "@uniswap/v3-sdk": { + "version": "1.0.0-alpha.29", + "resolved": "https://registry.npmjs.org/@uniswap/v3-sdk/-/v3-sdk-1.0.0-alpha.29.tgz", + "integrity": "sha512-fGwCin5VRzvv605I4vjt1erT9BmJJk/T7UD9GxjCs9NZTVzoJ0mqvTacGvg3EXbzmXD1PtlNmUgfYUvN4uq4bg==", + "requires": { + "@ethersproject/abi": "^5.0.12", + "@ethersproject/solidity": "^5.0.9", + "@uniswap/sdk-core": "^1.0.10", + "@uniswap/v3-periphery": "^1.0.0-beta.23", + "tiny-invariant": "^1.1.0", + "tiny-warning": "^1.0.3" + } + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, + "abi-decoder": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/abi-decoder/-/abi-decoder-2.4.0.tgz", + "integrity": "sha512-TOLU2q1HgYOjs1GKGtVzaqrYkar6I2fT9a80rzx6/9EJ/5crb4nCGuro0grZayixem93T7omrajYmLiMkYDLDA==", + "requires": { + "web3-eth-abi": "^1.2.1", + "web3-utils": "^1.2.1" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -1819,6 +1964,11 @@ "safe-buffer": "^5.0.1" } }, + "base64-sol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/base64-sol/-/base64-sol-1.0.1.tgz", + "integrity": "sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg==" + }, "bech32": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", @@ -2047,6 +2197,11 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" + }, "bufferutil": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", @@ -2114,9 +2269,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001211", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001211.tgz", - "integrity": "sha512-v3GXWKofIkN3PkSidLI5d1oqeKNsam9nQkqieoMhP87nxOY0RPDC8X2+jcv8pjV4dRozPLSoMqNii9sDViOlIg==", + "version": "1.0.30001214", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz", + "integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==", "dev": true }, "capture-console": { @@ -2249,6 +2404,11 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "complex.js": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.12.tgz", + "integrity": "sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2448,11 +2608,15 @@ "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -2502,6 +2666,11 @@ "esutils": "^2.0.2" } }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -2656,6 +2825,11 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, + "escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -2663,9 +2837,9 @@ "dev": true }, "eslint": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", - "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.25.0.tgz", + "integrity": "sha512-TVpSovpvCNpLURIScDRB6g5CYu/ZFq9GfX2hLNIV4dSBKxIWojeDODvYl3t0k0VtMxYeR8OXPCFE5+oHMlGfhw==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", @@ -2726,9 +2900,9 @@ } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -3086,18 +3260,43 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "ethereum-bloom-filters": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.9.tgz", + "integrity": "sha512-GiK/RQkAkcVaEdxKVkPcG07PQ5vD7v2MFSHgZmBJSfMzNRHimntdBithsHAT89tAXnIpzVDWt8iaCD1DvkaxGg==", + "requires": { + "js-sha3": "^0.8.0" + }, + "dependencies": { + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + } + } + }, "ethers": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.2.tgz", - "integrity": "sha512-yM+2bINj7Li9jeKX+hGZ/rFTo6kXcCwZTcCBmAwS+J3bLfyGX/o21fcssuPb9kfR26suCV+98XTWIuTuGiDO5A==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.4.tgz", + "integrity": "sha512-EAPQ/fgGRu0PoR/VNFnHTMOtG/IZ0AItdW55C9T8ffmVu0rnyllZL404eBF66elJehOLz2kxnUrhXpE7TCpW7g==", "requires": { - "@ethersproject/abi": "5.1.0", + "@ethersproject/abi": "5.1.2", "@ethersproject/abstract-provider": "5.1.0", "@ethersproject/abstract-signer": "5.1.0", "@ethersproject/address": "5.1.0", "@ethersproject/base64": "5.1.0", "@ethersproject/basex": "5.1.0", - "@ethersproject/bignumber": "5.1.0", + "@ethersproject/bignumber": "5.1.1", "@ethersproject/bytes": "5.1.0", "@ethersproject/constants": "5.1.0", "@ethersproject/contracts": "5.1.1", @@ -3109,7 +3308,7 @@ "@ethersproject/networks": "5.1.0", "@ethersproject/pbkdf2": "5.1.0", "@ethersproject/properties": "5.1.0", - "@ethersproject/providers": "5.1.1", + "@ethersproject/providers": "5.1.2", "@ethersproject/random": "5.1.0", "@ethersproject/rlp": "5.1.0", "@ethersproject/sha2": "5.1.0", @@ -3121,6 +3320,34 @@ "@ethersproject/wallet": "5.1.0", "@ethersproject/web": "5.1.0", "@ethersproject/wordlists": "5.1.0" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.1.tgz", + "integrity": "sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "bn.js": "^4.4.0" + } + } + } + }, + "ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "requires": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + } } }, "express": { @@ -3325,6 +3552,11 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, + "fraction.js": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz", + "integrity": "sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==" + }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -3400,6 +3632,15 @@ "is-glob": "^4.0.1" } }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, "global-dirs": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", @@ -3701,6 +3942,11 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + }, "is-generator-function": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", @@ -3715,6 +3961,11 @@ "is-extglob": "^2.1.1" } }, + "is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" + }, "is-installed-globally": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", @@ -3830,6 +4081,11 @@ "whatwg-fetch": ">=0.10.0" } }, + "javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" + }, "js-sha3": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", @@ -4043,6 +4299,21 @@ } } }, + "mathjs": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-9.3.2.tgz", + "integrity": "sha512-0YKSKAeN9OkbIQrxfxnBT4kk/KlH71piWOsvVvAasyRIj/Xd/zlpc5VP/aFxwr+llOq2F3f6booPEu2fWv3yjQ==", + "requires": { + "complex.js": "^2.0.11", + "decimal.js": "^10.2.1", + "escape-latex": "^1.2.0", + "fraction.js": "^4.0.13", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^2.0.0" + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -4089,8 +4360,15 @@ "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "^0.1.0" + } }, "minimalistic-assert": { "version": "1.0.1", @@ -4273,6 +4551,27 @@ "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", "dev": true }, + "number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "requires": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, "object-hash": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz", @@ -4411,6 +4710,11 @@ "callsites": "^3.0.0" } }, + "parse-headers": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", + "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==" + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -4518,43 +4822,6 @@ "find-up": "^3.0.0" } }, - "post-message-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/post-message-stream/-/post-message-stream-3.0.0.tgz", - "integrity": "sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg=", - "requires": { - "readable-stream": "^2.1.4" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4567,6 +4834,11 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -4623,6 +4895,16 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -4950,6 +5232,11 @@ "node-gyp-build": "^4.2.0" } }, + "seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -5053,6 +5340,21 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", + "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -5170,6 +5472,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", @@ -5222,6 +5529,14 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -5238,26 +5553,24 @@ } }, "table": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.2.0.tgz", - "integrity": "sha512-WMBBLuauiLXJjth35K4vOnd/xkaZ/dxEcyoZ+YhxSwfxFqvh+av06+oRqIwbR14m1lENB1egSWOFv/bNEt2D8A==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.6.0.tgz", + "integrity": "sha512-iZMtp5tUvcnAdtHpZTWLPF0M7AgiQsURR2DwmxnJwSy8I3+cY+ozzVvYha3BOLG2TB+L0CqjIz+91htuj6yCXg==", "dev": true, "requires": { "ajv": "^8.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", "lodash.clonedeep": "^4.5.0", "lodash.flatten": "^4.4.0", "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "dependencies": { "ajv": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", - "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", + "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -5291,6 +5604,16 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, "tiny-invariant": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", @@ -5413,6 +5736,11 @@ "mime-types": "~2.1.24" } }, + "typed-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-2.0.0.tgz", + "integrity": "sha512-Hhy1Iwo/e4AtLZNK10ewVVcP2UEs408DS35ubP825w/YgSBK1KVLwALvvIG4yX75QJrxjCpcWkzkVRB0BwwYlA==" + }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -5458,6 +5786,11 @@ } } }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", @@ -5590,6 +5923,11 @@ "prepend-http": "^2.0.0" } }, + "url-set-query": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" + }, "utf-8-validate": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", @@ -5598,6 +5936,11 @@ "node-gyp-build": "^4.2.0" } }, + "utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + }, "util": { "version": "0.12.3", "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", @@ -5651,6 +5994,49 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "web3-eth-abi": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.3.5.tgz", + "integrity": "sha512-bkbG2v/mOW5DH6rF/SEgqunusjYoEi2IBw+fkmD3rzWDaEY7+/i1xY94AeO257d06QMgld75GtV/N+aEs7A6vQ==", + "requires": { + "@ethersproject/abi": "5.0.7", + "underscore": "1.9.1", + "web3-utils": "1.3.5" + }, + "dependencies": { + "@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "requires": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + } + } + }, + "web3-utils": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.5.tgz", + "integrity": "sha512-5apMRm8ElYjI/92GHqijmaLC+s+d5lgjpjHft+rJSs/dsnX8I8tQreqev0dmU+wzU+2EEe4Sx9a/OwGWHhQv3A==", + "requires": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "underscore": "1.9.1", + "utf8": "3.0.0" + } + }, "whatwg-fetch": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", @@ -5814,6 +6200,44 @@ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, + "xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "requires": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "requires": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "xhr-request-promise": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", + "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", + "requires": { + "xhr-request": "^1.1.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index 817ee0d..64cd551 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,12 @@ "dependencies": { "@balancer-labs/sor": "^0.3.3", "@perp/contract": "^1.0.6", - "@terra-money/terra.js": "^0.5.8", + "@terra-money/terra.js": "^1.7.0", "@uniswap/sdk": "^3.0.3", + "@uniswap/v3-core": "^1.0.0-rc.2", + "@uniswap/v3-periphery": "^1.0.0-beta.23", + "@uniswap/v3-sdk": "^1.0.0-alpha.29", + "abi-decoder": "^2.4.0", "app-root-path": "^3.0.0", "axios": "^0.21.1", "bignumber.js": "^9.0.0", @@ -24,7 +28,7 @@ "cross-fetch": "^3.0.6", "debug": "^4.2.0", "dotenv": "^8.2.0", - "ethers": "^5.0.14", + "ethers": "^5.1.4", "express": "^4.17.1", "express-ipfilter": "^1.1.2", "helmet": "^4.1.1", @@ -37,10 +41,10 @@ "winston-daily-rotate-file": "^4.5.0" }, "devDependencies": { - "@babel/core": "^7.11.6", + "@babel/core": "^7.13.16", "@babel/node": "^7.10.5", "@babel/preset-env": "^7.11.5", - "eslint": "^7.10.0", + "eslint": "^7.25.0", "eslint-config-standard": "^14.1.1", "eslint-plugin-import": "^2.22.1", "eslint-plugin-node": "^11.1.0", diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index 53dfe79..dbc1a23 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -11,7 +11,9 @@ const router = express.Router() const eth = new Ethereum(process.env.ETHEREUM_CHAIN) const spenders = { balancer: process.env.EXCHANGE_PROXY, - uniswap: process.env.UNISWAP_ROUTER + uniswap: process.env.UNISWAP_ROUTER, + uniswapV3Router: process.env.UNISWAP_V3_ROUTER, + uniswapV3NFTManager: process.env.UNISWAP_V3_NFT_MANAGER } const fees = new Fees() @@ -350,6 +352,7 @@ router.post('/poll', async (req, res) => { const paramData = getParamData(req.body) const txHash = paramData.txHash const txReceipt = await eth.provider.getTransactionReceipt(txHash) + console.log(txReceipt) const receipt = {} const confirmed = txReceipt && txReceipt.blockNumber ? true : false if (confirmed) { @@ -357,6 +360,7 @@ router.post('/poll', async (req, res) => { receipt.blockNumber = txReceipt.blockNumber receipt.confirmations = txReceipt.confirmations receipt.status = txReceipt.status + receipt.logs = txReceipt.logs } logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }) res.status(200).json({ diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js index 3f0df74..6c86cc3 100644 --- a/src/routes/uniswap_v3.route.js +++ b/src/routes/uniswap_v3.route.js @@ -13,12 +13,11 @@ const debug = require('debug')('router') const router = express.Router() const eth = new Ethereum(process.env.ETHEREUM_CHAIN) const uniswap = new UniswapV3(process.env.ETHEREUM_CHAIN) -// uniswap.generate_tokens() -// setTimeout(uniswap.update_pairs.bind(uniswap), 2000) + const fees = new Fees() -const swapMoreThanMaxPriceError = 'Price too high' -const swapLessThanMaxPriceError = 'Price too low' +//const swapMoreThanMaxPriceError = 'Price too high' +//const swapLessThanMaxPriceError = 'Price too low' const estimateGasLimit = () => { return uniswap.gasLimit @@ -56,7 +55,7 @@ router.post('/', async (req, res) => { router.post('/gas-limit', async (req, res) => { /* - POST: /buy-price + POST: /gas-limit */ const gasLimit = estimateGasLimit() @@ -77,74 +76,40 @@ router.post('/gas-limit', async (req, res) => { } }) -router.get('/start', async (req, res) => { +router.get('/result', async (req, res) => { /* - POST: /eth/uniswap/start + POST: /eth/uniswap/v3/result x-www-form-urlencoded: { - "pairs":"[ETH-USDT, ...]" - "gasPrice":30 + "logs":"[...]" } */ const initTime = Date.now() const paramData = getParamData(req.query) - const pairs = JSON.parse(paramData.pairs) - let gasPrice - if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) - } else { - gasPrice = fees.ethGasPrice - } - - // get token contract address and cache paths - for (let pair of pairs){ - pair = pair.split("-") - const baseTokenSymbol = pair[0] - const quoteTokenSymbol = pair[1] - const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) - - // check for valid token symbols - if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { - const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol - res.status(500).json({ - error: `Token ${undefinedToken} contract address not found`, - message: `Token contract address not found for ${undefinedToken}. Check token list source`, - }) - return - } - await Promise.allSettled([uniswap.extend_update_pairs([baseTokenContractInfo.address, quoteTokenContractInfo.address])]) - } - - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) - + const logs = JSON.parse(paramData.logs) const result = { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - success: true, - pairs: pairs, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, + info: uniswap.abiDecoder.decodeLogs(logs) } res.status(200).json(result) }) router.post('/trade', async (req, res) => { - /* +/* POST: /trade x-www-form-urlencoded: { "quote":"BAT" "base":"DAI" "amount":0.1 "limitPrice":1 + "tier": {low|medium|high} "gasPrice":10 "privateKey":{{privateKey}} "side":{buy|sell} } - */ +*/ const initTime = Date.now() // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) const paramData = getParamData(req.body) @@ -157,11 +122,12 @@ router.post('/trade', async (req, res) => { const baseTokenAddress = baseTokenContractInfo.address const quoteTokenAddress = quoteTokenContractInfo.address const side = paramData.side.toUpperCase() + const tier = paramData.tier.toUpperCase() let limitPrice if (paramData.limitPrice) { limitPrice = parseFloat(paramData.limitPrice) - } + } else { limitPrice = 0} let gasPrice if (paramData.gasPrice) { gasPrice = parseFloat(paramData.gasPrice) @@ -172,30 +138,18 @@ router.post('/trade', async (req, res) => { const gasCost = await fees.getGasCost(gasPrice, gasLimit) try { - // fetch the optimal pool mix from uniswap - const { trade, expectedAmount } = side === 'BUY' - ? await uniswap.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount - ) - : await uniswap.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount - ) - if (side === 'BUY') { - const price = trade.executionPrice.invert().toSignificant(8) - logger.info(`uniswap.route - Price: ${price.toString()}`) - if (!limitPrice || price <= limitPrice) { - // pass swaps to exchange-proxy to complete trade const tx = await uniswap.swapExactOut( wallet, - trade, - baseTokenAddress, - gasPrice, + baseTokenContractInfo, // tokenIn is quote asset + quoteTokenContractInfo, // tokenOut is base asset + amount, + limitPrice, + tier, + gasPrice ) + console.log(tx) + console.log(tx.expectedAmount) // submit response res.status(200).json({ network: uniswap.network, @@ -204,32 +158,26 @@ router.post('/trade', async (req, res) => { base: baseTokenAddress, quote: quoteTokenAddress, amount: amount, - expectedIn: expectedAmount.toSignificant(8), - price: price, + expectedIn: tx.expectedAmount, + price: limitPrice, gasPrice: gasPrice, - gasLimit, gasLimit, - gasCost, gasCost, - txHash: tx.hash, - }) - } else { - res.status(200).json({ - error: swapMoreThanMaxPriceError, - message: `Swap price ${price} exceeds limitPrice ${limitPrice}` + gasLimit: gasLimit, + gasCost: gasCost, + txHash: tx.hash }) - logger.info(`uniswap.route - Swap price ${price} exceeds limitPrice ${limitPrice}`) - } + } else { // sell - const price = trade.executionPrice.toSignificant(8) - logger.info(`Price: ${price.toString()}`) - if (!limitPrice || price >= limitPrice) { - // pass swaps to exchange-proxy to complete trade const tx = await uniswap.swapExactIn( wallet, - trade, - baseTokenAddress, - gasPrice, + baseTokenContractInfo, // tokenIn is quote asset + quoteTokenContractInfo, // tokenOut is base asset + amount, + limitPrice, + tier, + gasPrice ) + // submit response res.status(200).json({ network: uniswap.network, @@ -238,20 +186,13 @@ router.post('/trade', async (req, res) => { base: baseTokenAddress, quote: quoteTokenAddress, amount: parseFloat(paramData.amount), - expectedOut: expectedAmount.toSignificant(8), - price: parseFloat(price), + expectedOut: tx.expectedAmount, + price: limitPrice, gasPrice: gasPrice, - gasLimit, gasLimit, + gasLimit: gasLimit, gasCost: gasCost, txHash: tx.hash, }) - } else { - res.status(200).json({ - error: swapLessThanMaxPriceError, - message: `Swap price ${price} lower than limitPrice ${limitPrice}` - }) - logger.info(`uniswap.route - Swap price ${price} lower than limitPrice ${limitPrice}`) - } } } catch (err) { logger.error(req.originalUrl, { message: err }) @@ -270,19 +211,20 @@ router.post('/price', async (req, res) => { x-www-form-urlencoded: { "quote":"BAT" "base":"DAI" - "amount":1 } - */ + */ const initTime = Date.now() // params: base (required), quote (required), amount (required) const paramData = getParamData(req.body) - const amount = paramData.amount + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, uniswap.provider) const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) const baseTokenAddress = baseTokenContractInfo.address const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() + + //const side = paramData.side.toUpperCase() // not used for now let gasPrice if (paramData.gasPrice) { gasPrice = parseFloat(paramData.gasPrice) @@ -294,50 +236,22 @@ router.post('/price', async (req, res) => { try { - // fetch the optimal pool mix from uniswap - const { trade, expectedAmount } = side === 'BUY' - ? await uniswap.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount - ) - : await uniswap.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount - ) - - if (trade !== null && expectedAmount !== null) { - const price = side === 'BUY' - ? trade.executionPrice.invert().toSignificant(8) - : trade.executionPrice.toSignificant(8) - - const tradeAmount = parseFloat(amount) - const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)) - const tradePrice = parseFloat(price) + // fetch pools for all tiers + const prices = await uniswap.currentPrice(wallet, baseTokenAddress, quoteTokenAddress) - const result = { - network: uniswap.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseTokenAddress, - quote: quoteTokenAddress, - amount: tradeAmount, - expectedAmount: expectedTradeAmount, - price: tradePrice, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - trade: trade, - } - debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) - res.status(200).json(result) - } else { // no pool available - res.status(200).json({ - info: statusMessages.no_pool_available, - message: '' - }) + const result = { + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenAddress, + quote: quoteTokenAddress, + prices: prices, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, } + debug(`Mid Price ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | (rate:${JSON.stringify(prices)}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) + res.status(200).json(result) } catch (err) { logger.error(req.originalUrl, { message: err }) let reason @@ -420,8 +334,6 @@ router.post('/add-position', async (req, res) => { const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0) const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address const fee = paramData.fee const tickLower = paramData.tickLower const tickUpper = paramData.tickUpper @@ -440,26 +352,25 @@ router.post('/add-position', async (req, res) => { try { // add position to pool - const newPosition = await uniswap.addPosition(wallet, baseTokenAddress, quoteTokenAddress, amount0, amount1, fee, tickLower, tickUpper); + const newPosition = await uniswap.addPosition(wallet, baseTokenContractInfo, quoteTokenContractInfo, amount0, amount1, fee, tickLower, tickUpper); const result = { network: uniswap.network, timestamp: initTime, latency: latency(initTime, Date.now()), - token0: token0, - token1: token1, + token0: paramData.token0, + token1: paramData.token1, fee: fee, - amount0: newPosition.amount0, - amount1: newPosition.amount1, + amount0: amount0, + amount1: amount1, tickLower: tickLower, tickUpper: tickUpper, - tokenId: newPosition.tokenId, - liquidity: newPosition.liquidity, + hash: newPosition.hash, gasPrice: gasPrice, gasLimit: gasLimit, gasCost: gasCost } - debug(`New Position: ${newPosition}`) + debug(`New Position: ${newPosition.hash}`) res.status(200).json(result) } catch (err) { logger.error(req.originalUrl, { message: err }) @@ -474,22 +385,16 @@ router.post('/remove-position', async (req, res) => { /* POST: /position x-www-form-urlencoded: { - "quote":"BAT" - "base":"DAI" - "amount":1 + "tokenId":"12" } */ const initTime = Date.now() const paramData = getParamData(req.body) const privateKey = paramData.privateKey const wallet = new ethers.Wallet(privateKey, uniswap.provider) - const amount = paramData.amount + const tokenId = paramData.tokenId + - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() let gasPrice if (paramData.gasPrice) { gasPrice = parseFloat(paramData.gasPrice) @@ -501,69 +406,24 @@ router.post('/remove-position', async (req, res) => { try { - // fetch the optimal pool mix from uniswap - const { trade, expectedAmount } = side === 'BUY' - ? await uniswap.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount - ) - : await uniswap.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount - ) - - if (trade !== null && expectedAmount !== null) { - const price = side === 'BUY' - ? trade.executionPrice.invert().toSignificant(8) - : trade.executionPrice.toSignificant(8) - - const tradeAmount = parseFloat(amount) - const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)) - const tradePrice = parseFloat(price) + const removelp = await uniswap.removePosition(wallet, tokenId) const result = { network: uniswap.network, timestamp: initTime, latency: latency(initTime, Date.now()), - base: baseTokenAddress, - quote: quoteTokenAddress, - amount: tradeAmount, - expectedAmount: expectedTradeAmount, - price: tradePrice, + hash: removelp.hash, gasPrice: gasPrice, gasLimit: gasLimit, gasCost: gasCost, - trade: trade, } - debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) + debug(`Remove lp: ${removelp.hash}`) res.status(200).json(result) - } else { // no pool available - res.status(200).json({ - info: statusMessages.no_pool_available, - message: '' - }) - } } catch (err) { logger.error(req.originalUrl, { message: err }) let reason let errCode = 500 - if (Object.keys(err).includes('isInsufficientReservesError')) { - errCode = 200 - reason = statusMessages.insufficient_reserves + ' in ' + side + ' at Uniswap' - } else if (Object.getOwnPropertyNames(err).includes('message')) { - reason = getErrorMessage(err.message) - if (reason === statusMessages.no_pool_available) { - errCode = 200 - res.status(errCode).json({ - info: reason, - message: err - }) - } - } else { - err.reason ? reason = err.reason : reason = statusMessages.operation_error - } + err.reason ? reason = err.reason : reason = statusMessages.operation_error res.status(errCode).json({ error: reason, message: err @@ -575,7 +435,7 @@ router.post('/adjust-liquidity', async (req, res) => { /* POST: /position x-www-form-urlencoded: { - "action":"BUY"/"SELL" + "action":"INCREASE"/"DECREASE" "tokenId":"tokenId" "amount0": amount0 "amount1": amount1 @@ -601,21 +461,24 @@ router.post('/adjust-liquidity', async (req, res) => { try { - // fetch the optimal pool mix from uniswap - const positionChange = uniswap.adjustLiquidity(wallet, action, tokenId, amount0, amount1); + const position = await uniswap.getPosition(wallet, tokenId) + const token0 = eth.getERC20TokenByAddress(position.token0) + const token1 = eth.getERC20TokenByAddress(position.token1) + const positionChange = await uniswap.adjustLiquidity(wallet, action, tokenId, token0, token1, amount0, amount1); const result = { network: uniswap.network, timestamp: initTime, latency: latency(initTime, Date.now()), tokenId: tokenId, - amount0: positionChange.amount0, - amount1: positionChange.amount1, + amount0: amount0, + amount1: amount1, + hash: positionChange.hash, gasPrice: gasPrice, gasLimit: gasLimit, gasCost: gasCost, } - debug(`Position change ${positionChange}`) + debug(`Position change ${positionChange.hash}`) res.status(200).json(result) } catch (err) { logger.error(req.originalUrl, { message: err }) @@ -640,8 +503,6 @@ router.post('/collect-fees', async (req, res) => { const privateKey = paramData.privateKey const wallet = new ethers.Wallet(privateKey, uniswap.provider) const tokenId = paramData.tokenId - const amount0 = paramData.amount0 - const amount1 = paramData.amount1 let gasPrice if (paramData.gasPrice) { @@ -655,20 +516,19 @@ router.post('/collect-fees', async (req, res) => { try { // withdraw fees - const collect = uniswap.collectFees (wallet, tokenId, amount0, amount1); + const collect = await uniswap.collectFees(wallet, tokenId); const result = { network: uniswap.network, timestamp: initTime, latency: latency(initTime, Date.now()), tokenId: tokenId, - amount0: collect.amount0, - amount1: collect.amount1, + hash: collect.hash, gasPrice: gasPrice, gasLimit: gasLimit, gasCost: gasCost, } - debug(`Fees: ${collect}`) + debug(`Fees: ${collect.hash}`) res.status(200).json(result) } catch (err) { logger.error(req.originalUrl, { message: err }) @@ -678,4 +538,5 @@ router.post('/collect-fees', async (req, res) => { }) } }) + export default router; diff --git a/src/services/eth.js b/src/services/eth.js index 61a51cd..bc85016 100644 --- a/src/services/eth.js +++ b/src/services/eth.js @@ -19,7 +19,8 @@ export default class Ethereum { this.network = network this.spenders = { balancer: process.env.EXCHANGE_PROXY, - uniswap: process.env.UNISWAP_ROUTER + uniswap: process.env.UNISWAP_ROUTER, + uniswapV3: process.UNISWAP_V3_ROUTER } // update token list this.getERC20TokenList() // erc20TokenList @@ -157,10 +158,18 @@ export default class Ethereum { } } + // Refactor name to getERC20TokenByName getERC20TokenAddresses (tokenSymbol) { const tokenContractAddress = this.erc20TokenList.tokens.filter(obj => { return obj.symbol === tokenSymbol.toUpperCase() }) return tokenContractAddress[0] } + + getERC20TokenByAddress (tokenAddress) { + const tokenContract = this.erc20TokenList.tokens.filter(obj => { + return obj.address.toUpperCase() === tokenAddress.toUpperCase() + }) + return tokenContract[0] + } } diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js index a9ed2b8..abe905c 100644 --- a/src/services/uniswap_v3.js +++ b/src/services/uniswap_v3.js @@ -1,27 +1,38 @@ import { logger } from './logger'; +import { encodePriceSqrt, getLiquidity, getTickAtSqrtRatio } from '../static/uniswap-v3/helper_functions'; const debug = require('debug')('router') const math = require('mathjs') const uni = require('@uniswap/sdk') const ethers = require('ethers') -const routerArtifact = require('../static/uniswap_v3_router_abi.json') -// const routeTokens = require('../static/uniswap_route_tokens.json') +const coreArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json') +const nftArtifact = require('@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json') +const routerArtifact = require('@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json') +const poolArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json') +//const routeTokens = require('../static/uniswap_route_tokens.json') +const abiDecoder = require('abi-decoder'); + // constants const FeeAmount = { LOW: 500, MEDIUM: 3000, HIGH: 10000 }; const ROUTER = process.env.UNISWAP_V3_ROUTER -const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 150688; +const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 5506880; const TTL = process.env.UNISWAP_TTL || 300; const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request +const MaxUint128 = ethers.BigNumber.from(2).pow(128).sub(1) + +abiDecoder.addABI(nftArtifact.abi); +abiDecoder.addABI(routerArtifact.abi); export default class UniswapV3 { constructor (network = 'mainnet') { this.providerUrl = process.env.ETHEREUM_RPC_URL this.network = process.env.ETHEREUM_CHAIN this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) - this.router = ROUTER; - this.slippage = math.fraction(process.env.UNISWAP_ALLOWED_SLIPPAGE) - this.allowedSlippage = new uni.Percent(this.slippage.n, (this.slippage.d * 100)) + this.router = process.env.UNISWAP_V3_ROUTER; + this.nftManager = process.env.UNISWAP_V3_NFT_MANAGER; + this.core = process.env.UNISWAP_V3_CORE; + this.slippage = process.env.UNISWAP_ALLOWED_SLIPPAGE this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME this.gasLimit = GAS_LIMIT this.expireTokenPairUpdate = UPDATE_PERIOD @@ -46,231 +57,234 @@ export default class UniswapV3 { } } - async fetch_route(tIn, tOut){ - var route, pair, pairOne, pairTwo - - try { - pair = await uni.Fetcher.fetchPairData(tIn, tOut); - route = new uni.Route([pair], tIn, tOut); - } - catch(err) { - logger.error(err); - } - return route; + get_contract( contract, wallet ){ + if (contract === "core") { return new ethers.Contract(this.core, coreArtifact.abi, wallet) } + else if ( contract === "router" ) { return new ethers.Contract(this.router, routerArtifact.abi, wallet) } + else { return new ethers.Contract(this.nftManager, nftArtifact.abi, wallet) } } + async currentPrice (wallet, tokenIn, tokenOut) { + let pool, poolContract; + let poolPrices = []; + let poolLiquidity = []; + const keys = ["LOW", "MEDIUM", "HIGH"]; + const coreContract = this.get_contract("core", wallet); - generate_tokens(){ - for (let token of routeTokens[this.network]){ - this.tokenList[token["address"]] = new uni.Token(this.chainID, token["address"], token["decimals"], token["symbol"], token["name"]); - } - } - - async extend_update_pairs(tokens=[]){ - for (let token of tokens){ - if (!this.tokenList.hasOwnProperty(token)){ - this.tokenList[token] = await uni.Fetcher.fetchTokenData(this.chainID, token); - } - this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate; - } + const poolAddressRequests = [coreContract.getPool(tokenIn, tokenOut, FeeAmount.LOW), + coreContract.getPool(tokenIn, tokenOut, FeeAmount.MEDIUM), + coreContract.getPool(tokenIn, tokenOut, FeeAmount.HIGH)]; + await Promise.allSettled(poolAddressRequests).then(values => { + for (pool=0; pool<3; pool++){ + if (values[pool].value === ethers.constants.AddressZero) { poolPrices[pool] = 0 } + else { + poolContract = new ethers.Contract(values[pool].value, poolArtifact.abi, wallet) + poolPrices[pool] = poolContract.observe([13]); + } + } + }) + await Promise.allSettled(poolPrices).then(values => { + for (pool=0; pool<3; pool++){ + poolPrices[pool] = poolLiquidity[pool] = 0; + if (values[pool].value) { + for (let tick of values[pool].value.tickCumulatives) { + poolPrices[pool] = tick.toNumber() - poolPrices[pool]; + } + poolPrices[pool] /= 13; + poolPrices[pool] = math.pow(1.0001, poolPrices[pool]) + } + } + }) + return Object.assign(...keys.map((k, i) => ({[k]: poolPrices[i]}))) } - async update_pairs(){ - // Remove banned pairs after ban period - if (Object.keys(this.zeroReservePairs).length > 0){ - for (let pair in this.zeroReservePairs){ - if (this.zeroReservePairs[pair] <= Date.now()) { - delete this.zeroReservePairs[pair]; - // delete this.tokenList[token]; - } - } - } - // Generate all possible pair combinations of tokens - // This is done by generating an upper triangular matrix or right triangular matrix - if (Object.keys(this.tokenSwapList).length > 0){ - for (let token in this.tokenSwapList){ - if (this.tokenSwapList[token] <= Date.now()) { - delete this.tokenSwapList[token]; - // delete this.tokenList[token]; - } - } - - let tokens = Object.keys(this.tokenList); - var firstToken, secondToken, position; - let length = tokens.length; - let pairs = []; - let pairAddressRequests = []; - let pairAddressResponses = []; - for (firstToken = 0; firstToken < length; firstToken++){ - for (secondToken = firstToken + 1; secondToken < length; secondToken++){ - try{ - let pairString = this.tokenList[tokens[firstToken]].address + '-' + this.tokenList[tokens[secondToken]].address; - if (!this.zeroReservePairs.hasOwnProperty(pairString)){ - pairs.push(pairString); - pairAddressRequests.push(uni.Fetcher.fetchPairData(this.tokenList[tokens[firstToken]], this.tokenList[tokens[secondToken]])); - } - } - catch(err) { - logger.error(err); - } - } - } - - await Promise.allSettled(pairAddressRequests).then(values => { for (position = 0; position < pairAddressRequests.length; position++) { - if (values[position].status === "fulfilled"){pairAddressResponses.push(values[position].value)} - else {this.zeroReservePairs[pairs[position]] = Date.now() + this.zeroReserveCheckInterval;}}}) - this.pairs = pairAddressResponses; - } - setTimeout(this.update_pairs.bind(this), 1000); - } - - async priceSwapIn (tokenIn, tokenOut, tokenInAmount) { - await this.extend_update_pairs([tokenIn, tokenOut]); - const tIn = this.tokenList[tokenIn]; - const tOut = this.tokenList[tokenOut]; - const tokenAmountIn = new uni.TokenAmount(tIn, ethers.utils.parseUnits(tokenInAmount, tIn.decimals)); - if (this.pairs.length === 0){ - const route = await this.fetch_route(tIn, tOut); - const trade = uni.Trade.exactIn(route, tokenAmountIn); - if ( trade !== undefined ){ - const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; - return { trade, expectedAmount } - } - return "Can't find route to swap, kindly update " - } - const trade = uni.Trade.bestTradeExactIn(this.pairs, tokenAmountIn, this.tokenList[tokenOut], { maxHops: 5 })[0]; - if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} - else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} - const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); - return { trade, expectedAmount } - } - - async priceSwapOut (tokenIn, tokenOut, tokenOutAmount) { - await this.extend_update_pairs([tokenIn, tokenOut]); - const tOut = this.tokenList[tokenOut]; - const tIn = this.tokenList[tokenIn]; - const tokenAmountOut = new uni.TokenAmount(tOut, ethers.utils.parseUnits(tokenOutAmount, tOut.decimals)); - if (this.pairs.length === 0){ - const route = await this.fetch_route(tIn, tOut); - const trade = uni.Trade.exactOut(route, tokenAmountOut); - if ( trade !== undefined ){ - const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; - return { trade, expectedAmount } - } - return - } - const trade = uni.Trade.bestTradeExactOut(this.pairs, this.tokenList[tokenIn], tokenAmountOut, { maxHops: 5 })[0]; - if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} - else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} - const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); - return { trade, expectedAmount } - } - async swapExactIn (wallet, trade, tokenAddress, gasPrice) { - const result = uni.Router.swapCallParameters( - trade, - { - ttl: TTL, + async swapExactIn (wallet, baseTokenContractInfo, quoteTokenContractInfo, baseAmount, limitPrice, tier, gasPrice) { + //sell, In => base, Out => quote + const minPercentOut = (1 - (this.slippage / 100)) + const amountOutMinimum = math.floor(baseAmount * limitPrice * minPercentOut, quoteTokenContractInfo.decimals) + //const priceFraction = math.fraction(limitPrice) + const contract = this.get_contract("router", wallet); + const tx = await contract.exactInputSingle({ + tokenIn: baseTokenContractInfo.address, + tokenOut: quoteTokenContractInfo.address, + fee: FeeAmount[tier], recipient: wallet.address, - allowedSlippage: this.allowedSlippage - } - ) - - const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet) - const tx = await contract.[result.methodName]( - ...result.args, + deadline: Date.now() + TTL, + amountIn: ethers.utils.parseUnits(baseAmount, baseTokenContractInfo.decimals), + amountOutMinimum: ethers.utils.parseUnits(amountOutMinimum.toString(), quoteTokenContractInfo.decimals), + //sqrtPriceLimitX96: encodePriceSqrt(priceFraction.d, priceFraction.n) + sqrtPriceLimitX96: 0 + }, { - gasPrice: gasPrice * 1e9, - gasLimit: GAS_LIMIT, - value: result.value + //gasPrice: gasPrice * 1e9, + gasLimit: GAS_LIMIT } ) debug(`Tx Hash: ${tx.hash}`); + tx.expectedAmount = amountOutMinimum return tx } - async swapExactOut (wallet, trade, tokenAddress, gasPrice) { - const result = uni.Router.swapCallParameters( - trade, - { - ttl: TTL, + async swapExactOut (wallet, baseTokenContractInfo, quoteTokenContractInfo, baseAmount, limitPrice, tier, gasPrice) { + //buy, In => quote, Out => base + const maxPercentIn = (1 + (this.slippage / 100)) + const amountInMaximum = math.ceil(baseAmount * limitPrice * maxPercentIn, quoteTokenContractInfo.decimals) + //const priceFraction = math.fraction(limitPrice) + const contract = this.get_contract("router", wallet); + const tx = await contract.exactOutputSingle({ + tokenIn: quoteTokenContractInfo.address, + tokenOut: baseTokenContractInfo.address, + fee: FeeAmount[tier], recipient: wallet.address, - allowedSlippage: this.allowedSlippage - } - ) - - const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet) - const tx = await contract.[result.methodName]( - ...result.args, + deadline: Date.now() + TTL, + amountOut: ethers.utils.parseUnits(baseAmount, baseTokenContractInfo.decimals), + amountInMaximum: ethers.utils.parseUnits(amountInMaximum.toString(), quoteTokenContractInfo.decimals), + //sqrtPriceLimitX96: encodePriceSqrt(priceFraction.d, priceFraction.n) + sqrtPriceLimitX96: 0 + }, { - gasPrice: gasPrice * 1e9, - gasLimit: GAS_LIMIT, - value: result.value + //gasPrice: gasPrice * 1e9, + gasLimit: GAS_LIMIT } ) debug(`Tx Hash: ${tx.hash}`); + tx.expectedAmount = amountInMaximum return tx } // LP section async getPosition (wallet, tokenId) { - const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet); - return await contract.positions(tokenId); + const contract = this.get_contract("nft", wallet); + const position = await contract.positions(tokenId); + return { + nonce: position[0].toString(), + operator: position[1], + token0: position[2], + token1: position[3], + fee: position[4], + tickLower: position[5], + tickUpper: position[6], + liquidity: position[7].toString(), + feeGrowthInside0LastX128: position[8].toString(), + feeGrowthInside1LastX128: position[9].toString(), + tokensOwed0: position[10].toString(), + tokensOwed1: position[11].toString() + } + + return position } - async addPosition (wallet, token0, token1, amount0, amount1, fee, tick0, tick1) { - const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet); - const priceSqrt = require('./uniswap-v3/encodePriceSqrt'); - const initPool = await contract.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ); - console.log(initPool); - const mintTx = await contract.mint({ + //getMinTick (tickSpacing){ return Math.ceil(-887272 / tickSpacing) * tickSpacing} + + //getMaxTick (tickSpacing){ return Math.floor(887272 / tickSpacing) * tickSpacing} + + async addPosition (wallet, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice) { + const nftContract = this.get_contract("nft", wallet); + const coreContract = this.get_contract("core", wallet); + //const pool = await coreContract.getPool(token0.address, token1.address, FeeAmount[fee]); + const midPrice = math.fraction((lowerPrice + upperPrice) / 2) // Use mid price to initialize uninitialized pool + + /* TO-DO: Accept price for upper and lower tick from client then convert to ticks + try{ + const lowerPriceFraction = math.fraction(lowerPrice) + const upperPriceFraction = math.fraction(upperPrice) + console.log(lowerPriceFraction) + console.log(upperPriceFraction) + console.log(getTickAtSqrtRatio(encodePriceSqrt(lowerPriceFraction.n, lowerPriceFraction.d))) + console.log(getTickAtSqrtRatio(encodePriceSqrt(upperPriceFraction.n, upperPriceFraction.d))) + }catch(err){console.log(err)} + */ + + const initPoolData = nftContract.interface.encodeFunctionData('createAndInitializePoolIfNecessary', [ + token0.address, + token1.address, + FeeAmount[fee], + encodePriceSqrt(midPrice.n, midPrice.d)]); + const mintData = nftContract.interface.encodeFunctionData('mint', [{ token0: token0.address, token1: token1.address, - tickLower: tick0, - tickUpper: tick1, - amount0Desired: amount0, - amount1Desired: amount1, + tickLower: lowerPrice, + tickUpper: upperPrice, + amount0Desired: ethers.utils.parseUnits(amount0, token0.decimals), + amount1Desired: ethers.utils.parseUnits(amount1, token1.decimals), + // slippage isn't applied for now amount0Min: 0, amount1Min: 0, recipient: wallet.address, - deadline: TTL, - fee: fee - }); - return mintTx; + deadline: Date.now() + TTL, + fee: FeeAmount[fee] + }]); + + let calls = [mintData] + + if (pool === ethers.constants.AddressZero) { const calls = [initPoolData, mintData] } + + const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }); + + return tx; } async removePosition (wallet, tokenId) { // Reduce position and burn - let positionData = this.getPosition(wallet, tokenId); - let amount0, amount1; - // calulate amount of token0 and token1 from position liquidity + let positionData = await this.getPosition(wallet, tokenId); + const contract = this.get_contract("nft", wallet); + const decreaseLiquidityData = contract.interface.encodeFunctionData('decreaseLiquidity', [{ + tokenId: tokenId, + liquidity: positionData.liquidity, + amount0Min: 0, + amount1Min: 0, + deadline: Date.now() + TTL}]); + const collectFeesData = contract.interface.encodeFunctionData('collect', [{ + tokenId: tokenId, + recipient: wallet.address, + amount0Max: MaxUint128, + amount1Max: MaxUint128}]); + const burnData = contract.interface.encodeFunctionData('burn', [tokenId]); - let decreaseTx = await contract.decreaseLiquidity(tokenId, amount0, amount1, amount0, amount1, TTL); - // To-Do: check success of decrease before burn - positionData = this.getPosition(wallet, tokenId); - return await contract.collect(tokenId, wallet.address, positionData.tokensOwed0, positionData.tokensOwed1); + return await contract.multicall([decreaseLiquidityData, collectFeesData, burnData], { gasLimit: GAS_LIMIT }); } - async adjustLiquidity (wallet, action, tokenId, amount0, amount1) { - const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet); + async adjustLiquidity (wallet, action, tokenId, token0, token1, amount0, amount1) { + const contract = this.get_contract("nft", wallet); + const parsedAmount0 = ethers.utils.parseUnits(amount0, token0.decimals) + const parsedAmount1 = ethers.utils.parseUnits(amount1, token1.decimals) if (action === "INCREASE") { - return await contract.increaseLiquidity(tokenId, amount0, amount1, amount0Min, amount1Min, TTL); + return await contract.increaseLiquidity({ + tokenId: tokenId, + amount0Desired: parsedAmount0, + amount1Desired: parsedAmount1, + amount0Min: 0, + amount1Min: 0, + deadline: Date.now() + TTL}, + { gasLimit: GAS_LIMIT }); } else { - return await contract.decreaseLiquidity(tokenId, amount0, amount1, amount0Min, amount1Min, TTL); + const liquidity = getLiquidity(ethers.utils.parseUnits(amount0, 6), ethers.utils.parseUnits(amount1, 6)) // use method from sdk to calculate liquidity from amount correctly + const decreaseLiquidityData = contract.interface.encodeFunctionData('decreaseLiquidity', [{ + tokenId: tokenId, + liquidity: liquidity, + amount0Min: 0, + amount1Min: 0, + deadline: Date.now() + TTL}]); + const collectFeesData = contract.interface.encodeFunctionData('collect', [{ + tokenId: tokenId, + recipient: wallet.address, + amount0Max: MaxUint128, + amount1Max: MaxUint128}]); + + return await contract.multicall([decreaseLiquidityData, collectFeesData], { gasLimit: GAS_LIMIT }); } } - async collectFees (wallet, tokenId, amount0, amount1) { - const contract = new ethers.Contract(this.router, routerArtifact.abi, wallet); - return await contract.collect(tokenId, wallet.address, amount0, amount1); + async collectFees (wallet, tokenId) { + const contract = this.get_contract("nft", wallet); + return await contract.collect({ + tokenId: tokenId, + recipient: wallet.address, + amount0Max: MaxUint128, + amount1Max: MaxUint128}, + { gasLimit: GAS_LIMIT }); +} } diff --git a/src/static/uniswap-v3/encodePriceSqrt.js b/src/static/uniswap-v3/encodePriceSqrt.js deleted file mode 100644 index f95cd23..0000000 --- a/src/static/uniswap-v3/encodePriceSqrt.js +++ /dev/null @@ -1,16 +0,0 @@ -import bn from 'bignumber.js' -import { BigNumber, BigNumberish } from 'ethers' - -bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }) - -// returns the sqrt price as a 64x96 -export function encodePriceSqrt(reserve1: BigNumberish, reserve0: BigNumberish): BigNumber { - return BigNumber.from( - new bn(reserve1.toString()) - .div(reserve0.toString()) - .sqrt() - .multipliedBy(new bn(2).pow(96)) - .integerValue(3) - .toString() - ) -} diff --git a/src/static/uniswap-v3/helper_functions.js b/src/static/uniswap-v3/helper_functions.js new file mode 100644 index 0000000..6313995 --- /dev/null +++ b/src/static/uniswap-v3/helper_functions.js @@ -0,0 +1,132 @@ +import bn from 'bignumber.js' +import JSBI from 'jsbi' +import { BigNumber, BigNumberish } from 'ethers' + +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }) + +// returns the sqrt price as a 64x96 +export function encodePriceSqrt(reserve1, reserve0) { + return BigNumber.from( + new bn(reserve1.toString()) + .div(reserve0.toString()) + .sqrt() + .multipliedBy(new bn(2).pow(96)) + .integerValue(3) + .toString() + ) +} + +export function getLiquidity(amount0, amount1) { + return BigNumber.from( + new bn(amount0.toString()) + .multipliedBy(amount1.toString()) + .sqrt() + .toString() + ) +} + + +const TWO = JSBI.BigInt(2) +const POWERS_OF_2 = [128, 64, 32, 16, 8, 4, 2, 1].map((pow) => [ + pow, + JSBI.exponentiate(TWO, JSBI.BigInt(pow)) +]) + +export function mostSignificantBit(x) { + + let msb = 0 + for (const [power, min] of POWERS_OF_2) { + if (JSBI.greaterThanOrEqual(x, min)) { + x = JSBI.signedRightShift(x, JSBI.BigInt(power)) + msb += power + } + } + return msb +} + +const MIN_TICK = -887272 + +const MAX_TICK = -MIN_TICK + +const MIN_SQRT_RATIO = JSBI.BigInt('4295128739') + +const MAX_SQRT_RATIO = JSBI.BigInt('1461446703485210103287273052203988822378723970342') + +export function getSqrtRatioAtTick(tick) { + const absTick = tick < 0 ? tick * -1 : tick + + let ratio = + (absTick & 0x1) != 0 + ? JSBI.BigInt('0xfffcb933bd6fad37aa2d162d1a594001') + : JSBI.BigInt('0x100000000000000000000000000000000') + if ((absTick & 0x2) != 0) ratio = mulShift(ratio, '0xfff97272373d413259a46990580e213a') + if ((absTick & 0x4) != 0) ratio = mulShift(ratio, '0xfff2e50f5f656932ef12357cf3c7fdcc') + if ((absTick & 0x8) != 0) ratio = mulShift(ratio, '0xffe5caca7e10e4e61c3624eaa0941cd0') + if ((absTick & 0x10) != 0) ratio = mulShift(ratio, '0xffcb9843d60f6159c9db58835c926644') + if ((absTick & 0x20) != 0) ratio = mulShift(ratio, '0xff973b41fa98c081472e6896dfb254c0') + if ((absTick & 0x40) != 0) ratio = mulShift(ratio, '0xff2ea16466c96a3843ec78b326b52861') + if ((absTick & 0x80) != 0) ratio = mulShift(ratio, '0xfe5dee046a99a2a811c461f1969c3053') + if ((absTick & 0x100) != 0) ratio = mulShift(ratio, '0xfcbe86c7900a88aedcffc83b479aa3a4') + if ((absTick & 0x200) != 0) ratio = mulShift(ratio, '0xf987a7253ac413176f2b074cf7815e54') + if ((absTick & 0x400) != 0) ratio = mulShift(ratio, '0xf3392b0822b70005940c7a398e4b70f3') + if ((absTick & 0x800) != 0) ratio = mulShift(ratio, '0xe7159475a2c29b7443b29c7fa6e889d9') + if ((absTick & 0x1000) != 0) ratio = mulShift(ratio, '0xd097f3bdfd2022b8845ad8f792aa5825') + if ((absTick & 0x2000) != 0) ratio = mulShift(ratio, '0xa9f746462d870fdf8a65dc1f90e061e5') + if ((absTick & 0x4000) != 0) ratio = mulShift(ratio, '0x70d869a156d2a1b890bb3df62baf32f7') + if ((absTick & 0x8000) != 0) ratio = mulShift(ratio, '0x31be135f97d08fd981231505542fcfa6') + if ((absTick & 0x10000) != 0) ratio = mulShift(ratio, '0x9aa508b5b7a84e1c677de54f3e99bc9') + if ((absTick & 0x20000) != 0) ratio = mulShift(ratio, '0x5d6af8dedb81196699c329225ee604') + if ((absTick & 0x40000) != 0) ratio = mulShift(ratio, '0x2216e584f5fa1ea926041bedfe98') + if ((absTick & 0x80000) != 0) ratio = mulShift(ratio, '0x48a170391f7dc42444e8fa2') + + if (tick > 0) ratio = JSBI.divide(MaxUint256, ratio) + + // back to Q96 + return JSBI.greaterThan(JSBI.remainder(ratio, Q32), ZERO) + ? JSBI.add(JSBI.divide(ratio, Q32), ONE) + : JSBI.divide(ratio, Q32) +} + +export function getTickAtSqrtRatio(sqrtRatioX96) { + + const sqrtRatioX128 = JSBI.leftShift(sqrtRatioX96, JSBI.BigInt(32)) + + const msb = mostSignificantBit(sqrtRatioX128) + + let r + if (JSBI.greaterThanOrEqual(JSBI.BigInt(msb), JSBI.BigInt(128))) { + r = JSBI.signedRightShift(sqrtRatioX128, JSBI.BigInt(msb - 127)) + } else { + r = JSBI.leftShift(sqrtRatioX128, JSBI.BigInt(127 - msb)) + } + + let log_2 = JSBI.leftShift(JSBI.subtract(JSBI.BigInt(msb), JSBI.BigInt(128)), JSBI.BigInt(64)) + + for (let i = 0; i < 14; i++) { + r = JSBI.signedRightShift(JSBI.multiply(r, r), JSBI.BigInt(127)) + const f = JSBI.signedRightShift(r, JSBI.BigInt(128)) + log_2 = JSBI.bitwiseOr(log_2, JSBI.leftShift(f, JSBI.BigInt(63 - i))) + r = JSBI.signedRightShift(r, f) + } + + const log_sqrt10001 = JSBI.multiply(log_2, JSBI.BigInt('255738958999603826347141')) + + const tickLow = JSBI.toNumber( + JSBI.signedRightShift( + JSBI.subtract(log_sqrt10001, JSBI.BigInt('3402992956809132418596140100660247210')), + JSBI.BigInt(128) + ) + ) + const tickHigh = JSBI.toNumber( + JSBI.signedRightShift( + JSBI.add(log_sqrt10001, JSBI.BigInt('291339464771989622907027621153398088495')), + JSBI.BigInt(128) + ) + ) + + return tickLow === tickHigh + ? tickLow + : JSBI.lessThanOrEqual(getSqrtRatioAtTick(tickHigh), sqrtRatioX96) + ? tickHigh + : tickLow + } diff --git a/yarn.lock b/yarn.lock index a3a5e0c..a54fd7b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1219,6 +1219,11 @@ "@ethersproject/properties" "^5.0.3" "@ethersproject/strings" "^5.0.4" +"@openzeppelin/contracts@3.4.1-solc-0.7-2": + version "3.4.1-solc-0.7-2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92" + integrity sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q== + "@perp/contract@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@perp/contract/-/contract-1.0.6.tgz#b423738d095a15fccd17de7bc46a531482a45d18" @@ -1270,6 +1275,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== +"@uniswap/lib@^4.0.1-alpha": + version "4.0.1-alpha" + resolved "https://registry.yarnpkg.com/@uniswap/lib/-/lib-4.0.1-alpha.tgz#2881008e55f075344675b3bca93f020b028fbd02" + integrity sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA== + "@uniswap/sdk@^3.0.3": version "3.0.3" resolved "https://registry.yarnpkg.com/@uniswap/sdk/-/sdk-3.0.3.tgz#8201c7c72215d0030cb99acc7e661eff895c18a9" @@ -1283,11 +1293,26 @@ tiny-warning "^1.0.3" toformat "^2.0.0" -"@uniswap/v2-core@^1.0.0": +"@uniswap/v2-core@1.0.1", "@uniswap/v2-core@^1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/@uniswap/v2-core/-/v2-core-1.0.1.tgz#af8f508bf183204779938969e2e54043e147d425" integrity sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q== +"@uniswap/v3-core@1.0.0-rc.2": + version "1.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.0-rc.2.tgz#a1afb3253a7295bec6165ad1d960121e6851a576" + integrity sha512-vsqkqAHPCKsVi0nWwWeX+mHnSTJ8ZUdu1zAVXB9Mj9A+aeBQGV9foRKs9ufDGJq7S1nqmz+7FdjSOcVoeiUqgQ== + +"@uniswap/v3-periphery@^1.0.0-beta.21": + version "1.0.0-beta.21" + resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.0.0-beta.21.tgz#0b8510bebca4b74aabdca72c5545bd5bec5128cd" + integrity sha512-o4U+lyH6qtlG2RTy3H/mtUGJuflkmVJ0pnXyrThZKC1KV/avlVgf4hmlG2PvOCV0yfwGMjQARKQ4jv6OpLFVqA== + dependencies: + "@openzeppelin/contracts" "3.4.1-solc-0.7-2" + "@uniswap/lib" "^4.0.1-alpha" + "@uniswap/v2-core" "1.0.1" + "@uniswap/v3-core" "1.0.0-rc.2" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" From 31e4015694724e44e9c549d34979f5bc461df4e6 Mon Sep 17 00:00:00 2001 From: vic-en Date: Thu, 29 Apr 2021 22:24:35 +0100 Subject: [PATCH 05/31] (feat) add postman collection --- .../Uniswap V3.postman_collection.json | 493 ++++++++++++++++++ 1 file changed, 493 insertions(+) create mode 100644 test/postman/Uniswap V3.postman_collection.json diff --git a/test/postman/Uniswap V3.postman_collection.json b/test/postman/Uniswap V3.postman_collection.json new file mode 100644 index 0000000..24dfcc5 --- /dev/null +++ b/test/postman/Uniswap V3.postman_collection.json @@ -0,0 +1,493 @@ +{ + "info": { + "_postman_id": "5de36bfa-027e-46e3-810d-219e42c75314", + "name": "Uniswap V3", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "uniswap v3 endpoints", + "item": [ + { + "name": "eth/uniswap/v3", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/gas-limit", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3", + "gas-limit" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/result", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/result?logs=§ion=lp", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3", + "result" + ], + "query": [ + { + "key": "logs", + "value": "" + }, + { + "key": "section", + "value": "lp" + } + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "DAI", + "type": "text" + }, + { + "key": "quote", + "value": "USDC", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3", + "price" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "WETH", + "type": "text" + }, + { + "key": "quote", + "value": "DAI", + "type": "text" + }, + { + "key": "amount", + "value": "0.25", + "type": "text" + }, + { + "key": "limitPrice", + "value": "1.2115524", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/trade", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3", + "trade" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/position", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenId", + "value": "43", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/position", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3", + "position" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/add-position", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "token0", + "value": "DAI", + "type": "text" + }, + { + "key": "token1", + "value": "USDC", + "type": "text" + }, + { + "key": "fee", + "value": "MEDIUM", + "type": "text" + }, + { + "key": "tickLower", + "value": "5", + "type": "text" + }, + { + "key": "tickUpper", + "value": "10", + "type": "text" + }, + { + "key": "amount0", + "value": "2", + "type": "text" + }, + { + "key": "amount1", + "value": "2", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/add-position", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3", + "add-position" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/adjust-liquidity", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "action", + "value": "DECREASE", + "type": "text" + }, + { + "key": "amount0", + "value": "1", + "type": "text" + }, + { + "key": "amount1", + "value": "1", + "type": "text" + }, + { + "key": "tokenId", + "value": "43", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/adjust-liquidity", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3", + "adjust-liquidity" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/collect-fees", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "tokenId", + "value": "44", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/collect-fees", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3", + "", + "collect-fees" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/remove-position", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "tokenId", + "value": "", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/remove-position", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "v3", + "remove-position" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + } + ] +} From bd1c6baf9cf8251864c8eec6c04feddeaa99859e Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 3 May 2021 13:24:19 +0100 Subject: [PATCH 06/31] (cleanup) remove spenders from eth.js file --- src/services/eth.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/eth.js b/src/services/eth.js index bc85016..36d4303 100644 --- a/src/services/eth.js +++ b/src/services/eth.js @@ -17,11 +17,13 @@ export default class Ethereum { this.provider = new ethers.providers.JsonRpcProvider(providerUrl) this.erc20TokenListURL = process.env.ETHEREUM_TOKEN_LIST_URL this.network = network + /* this.spenders = { balancer: process.env.EXCHANGE_PROXY, uniswap: process.env.UNISWAP_ROUTER, uniswapV3: process.UNISWAP_V3_ROUTER } + */ // update token list this.getERC20TokenList() // erc20TokenList } From 446812ebf1cd3cddbdb6bd53e00db7a6e56d4115 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 3 May 2021 13:25:01 +0100 Subject: [PATCH 07/31] (feat) update custom HB tokens --- src/static/erc20_tokens_kovan.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/erc20_tokens_kovan.json b/src/static/erc20_tokens_kovan.json index f12f7a3..78d2621 100644 --- a/src/static/erc20_tokens_kovan.json +++ b/src/static/erc20_tokens_kovan.json @@ -58,7 +58,7 @@ }, { "symbol": "COIN2", - "address": "0xbab297ff0d366d9c2639cf291e5be4b2c7ca5ce2", + "address": "0x03E406ce22AFdc7d4E24Bf55eCe2A910DE7b0D73", "decimals": 8 } ] From 47e6355059f3347a4c490bd73e146655f0ba0ebb Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 3 May 2021 13:25:30 +0100 Subject: [PATCH 08/31] (refactor) correctly parse prices for add-position endpoint rather than ticks --- src/routes/uniswap_v3.route.js | 14 +++++----- src/services/uniswap_v3.js | 31 ++++++++--------------- src/static/uniswap-v3/helper_functions.js | 27 ++++++++++++++++++++ 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js index 6c86cc3..a62eb50 100644 --- a/src/routes/uniswap_v3.route.js +++ b/src/routes/uniswap_v3.route.js @@ -321,8 +321,8 @@ router.post('/add-position', async (req, res) => { "token0":"BAT" "token1":"DAI" "fee":1 - "tickLower": 1 - "tickUpper": 2 + "lowerPrice": 1 + "upperPrice": 2 "amount0": amount0 "amount1": amount1 } @@ -335,8 +335,8 @@ router.post('/add-position', async (req, res) => { const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0) const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1) const fee = paramData.fee - const tickLower = paramData.tickLower - const tickUpper = paramData.tickUpper + const lowerPrice = paramData.lowerPrice + const upperPrice = paramData.upperPrice const amount0 = paramData.amount0 const amount1 = paramData.amount1 @@ -352,7 +352,7 @@ router.post('/add-position', async (req, res) => { try { // add position to pool - const newPosition = await uniswap.addPosition(wallet, baseTokenContractInfo, quoteTokenContractInfo, amount0, amount1, fee, tickLower, tickUpper); + const newPosition = await uniswap.addPosition(wallet, baseTokenContractInfo, quoteTokenContractInfo, amount0, amount1, fee, lowerPrice, upperPrice); const result = { network: uniswap.network, @@ -363,8 +363,8 @@ router.post('/add-position', async (req, res) => { fee: fee, amount0: amount0, amount1: amount1, - tickLower: tickLower, - tickUpper: tickUpper, + lowerPrice: lowerPrice, + upperPrice: upperPrice, hash: newPosition.hash, gasPrice: gasPrice, gasLimit: gasLimit, diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js index abe905c..a6b8114 100644 --- a/src/services/uniswap_v3.js +++ b/src/services/uniswap_v3.js @@ -1,5 +1,5 @@ import { logger } from './logger'; -import { encodePriceSqrt, getLiquidity, getTickAtSqrtRatio } from '../static/uniswap-v3/helper_functions'; +import { encodePriceSqrt, getLiquidity, getTickFromPrice } from '../static/uniswap-v3/helper_functions'; const debug = require('debug')('router') const math = require('mathjs') @@ -177,27 +177,13 @@ export default class UniswapV3 { return position } - //getMinTick (tickSpacing){ return Math.ceil(-887272 / tickSpacing) * tickSpacing} - - //getMaxTick (tickSpacing){ return Math.floor(887272 / tickSpacing) * tickSpacing} - async addPosition (wallet, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice) { + try{ const nftContract = this.get_contract("nft", wallet); const coreContract = this.get_contract("core", wallet); - //const pool = await coreContract.getPool(token0.address, token1.address, FeeAmount[fee]); + const pool = await coreContract.getPool(token0.address, token1.address, FeeAmount[fee]); const midPrice = math.fraction((lowerPrice + upperPrice) / 2) // Use mid price to initialize uninitialized pool - /* TO-DO: Accept price for upper and lower tick from client then convert to ticks - try{ - const lowerPriceFraction = math.fraction(lowerPrice) - const upperPriceFraction = math.fraction(upperPrice) - console.log(lowerPriceFraction) - console.log(upperPriceFraction) - console.log(getTickAtSqrtRatio(encodePriceSqrt(lowerPriceFraction.n, lowerPriceFraction.d))) - console.log(getTickAtSqrtRatio(encodePriceSqrt(upperPriceFraction.n, upperPriceFraction.d))) - }catch(err){console.log(err)} - */ - const initPoolData = nftContract.interface.encodeFunctionData('createAndInitializePoolIfNecessary', [ token0.address, token1.address, @@ -206,8 +192,8 @@ export default class UniswapV3 { const mintData = nftContract.interface.encodeFunctionData('mint', [{ token0: token0.address, token1: token1.address, - tickLower: lowerPrice, - tickUpper: upperPrice, + tickLower: getTickFromPrice(lowerPrice, fee, "UPPER"), + tickUpper: getTickFromPrice(upperPrice, fee, "LOWER"), amount0Desired: ethers.utils.parseUnits(amount0, token0.decimals), amount1Desired: ethers.utils.parseUnits(amount1, token1.decimals), // slippage isn't applied for now @@ -225,6 +211,7 @@ export default class UniswapV3 { const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }); return tx; + } catch(err) { console.log(err)} } async removePosition (wallet, tokenId) { @@ -261,7 +248,9 @@ export default class UniswapV3 { deadline: Date.now() + TTL}, { gasLimit: GAS_LIMIT }); } else { - const liquidity = getLiquidity(ethers.utils.parseUnits(amount0, 6), ethers.utils.parseUnits(amount1, 6)) // use method from sdk to calculate liquidity from amount correctly + //const liquidity = getLiquidity(ethers.utils.parseUnits(amount0, 6), ethers.utils.parseUnits(amount1, 6)) // use method from sdk to calculate liquidity from amount correctly + const liquidity = getLiquidity(amount0, amount1) + console.log(liquidity.toString()) const decreaseLiquidityData = contract.interface.encodeFunctionData('decreaseLiquidity', [{ tokenId: tokenId, liquidity: liquidity, @@ -274,7 +263,7 @@ export default class UniswapV3 { amount0Max: MaxUint128, amount1Max: MaxUint128}]); - return await contract.multicall([decreaseLiquidityData, collectFeesData], { gasLimit: GAS_LIMIT }); + //return await contract.multicall([decreaseLiquidityData, collectFeesData], { gasLimit: GAS_LIMIT }); } } diff --git a/src/static/uniswap-v3/helper_functions.js b/src/static/uniswap-v3/helper_functions.js index 6313995..f028eca 100644 --- a/src/static/uniswap-v3/helper_functions.js +++ b/src/static/uniswap-v3/helper_functions.js @@ -2,6 +2,9 @@ import bn from 'bignumber.js' import JSBI from 'jsbi' import { BigNumber, BigNumberish } from 'ethers' +const math = require('mathjs') +const TICK_SPACINGS = { LOW: 10, MEDIUM: 60, HIGH: 2000 }; + bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }) // returns the sqrt price as a 64x96 @@ -23,6 +26,11 @@ export function getLiquidity(amount0, amount1) { .sqrt() .toString() ) + /*let tokenPrice0, tokenPrice1, tokenFraction; + tokenFraction = math.fraction(amount1/amount0) + tokenPrice0 = encodePriceSqrt(tokenFraction.n, tokenFraction.d) + tokenPrice1 = encodePriceSqrt(tokenFraction.d, tokenFraction.n) + return tokenPrice0.mul(tokenPrice1)*/ } @@ -130,3 +138,22 @@ export function getTickAtSqrtRatio(sqrtRatioX96) { ? tickHigh : tickLow } + +export function getTickFromPrice(price, tier, side) { + var tick = 0; + if (side === "UPPER") { + tick = math.ceil(math.log(price, 1.0001) / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier] + } + else { + tick = math.floor(math.log(price, 1.0001) / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier] + } + + if (tick >= getMaxTick(tier)) { return getMaxTick(tier) } + else if (tick <= getMinTick(tier)) { return getMinTick(tier) } + else { return tick } + +} + +export function getMinTick (tier){ return Math.ceil(-887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]} + +export function getMaxTick (tier){ return Math.floor(887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]} From c433b58dbf78909e76b5fda77fa574289453c8e6 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 3 May 2021 13:35:57 +0100 Subject: [PATCH 09/31] (fix) update custom token addresses --- src/static/erc20_tokens_kovan.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/static/erc20_tokens_kovan.json b/src/static/erc20_tokens_kovan.json index 78d2621..ea84a4b 100644 --- a/src/static/erc20_tokens_kovan.json +++ b/src/static/erc20_tokens_kovan.json @@ -53,13 +53,18 @@ }, { "symbol": "COIN1", - "address": "0xf7699696b7d92d9b4735bf1ddfdd92577b5869b0", + "address": "0x809F5A762e7b0CC75C42cd76098b85CB7BD2BA64", "decimals": 18 }, { "symbol": "COIN2", - "address": "0x03E406ce22AFdc7d4E24Bf55eCe2A910DE7b0D73", + "address": "0x9866c4043bc6cf47eaf845c56f6ab221c204e0df", "decimals": 8 + }, + { + "symbol": "COIN3", + "address": "0x3D2097889B97A9eF23B3eA8FC10c626fbda29099", + "decimals": 18 } ] } From d3e4727b01a69c0b4c8042586144ba068e940fa0 Mon Sep 17 00:00:00 2001 From: vic-en Date: Thu, 6 May 2021 18:08:16 +0100 Subject: [PATCH 10/31] (feat) update v3 connector --- package-lock.json | 434 +++++++++++----------- package.json | 16 +- src/routes/eth.route.js | 2 +- src/routes/uniswap_v3.route.js | 304 +++++++-------- src/services/uniswap_v3.js | 119 +++--- src/static/uniswap-v3/helper_functions.js | 13 + 6 files changed, 469 insertions(+), 419 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a29fac..2621a34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,82 +14,41 @@ } }, "@babel/compat-data": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", - "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", + "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", "dev": true }, "@babel/core": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", - "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.0.tgz", + "integrity": "sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", + "@babel/generator": "^7.14.0", "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.16", - "@babel/parser": "^7.13.16", + "@babel/helper-module-transforms": "^7.14.0", + "@babel/helpers": "^7.14.0", + "@babel/parser": "^7.14.0", "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", "semver": "^6.3.0", "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", - "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", - "dev": true, - "requires": { - "@babel/types": "^7.13.16", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - } - }, - "@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==", - "dev": true - }, - "@babel/types": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", - "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/generator": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", - "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", + "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", "dev": true, "requires": { - "@babel/types": "^7.13.0", + "@babel/types": "^7.14.1", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -114,27 +73,28 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", - "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", + "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", "dev": true, "requires": { - "@babel/compat-data": "^7.13.12", + "@babel/compat-data": "^7.13.15", "@babel/helper-validator-option": "^7.12.17", "browserslist": "^4.14.5", "semver": "^6.3.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.13.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", - "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz", + "integrity": "sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg==", "dev": true, "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", "@babel/helper-function-name": "^7.12.13", - "@babel/helper-member-expression-to-functions": "^7.13.0", + "@babel/helper-member-expression-to-functions": "^7.13.12", "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-replace-supers": "^7.13.12", "@babel/helper-split-export-declaration": "^7.12.13" } }, @@ -194,13 +154,13 @@ } }, "@babel/helper-hoist-variables": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz", - "integrity": "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==", + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz", + "integrity": "sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg==", "dev": true, "requires": { - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/traverse": "^7.13.15", + "@babel/types": "^7.13.16" } }, "@babel/helper-member-expression-to-functions": { @@ -222,19 +182,27 @@ } }, "@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz", + "integrity": "sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.13.12", "@babel/helper-replace-supers": "^7.13.12", "@babel/helper-simple-access": "^7.13.12", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.14.0", "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "dev": true + } } }, "@babel/helper-optimise-call-expression": { @@ -327,59 +295,14 @@ } }, "@babel/helpers": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", - "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", + "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", "dev": true, "requires": { "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.17", - "@babel/types": "^7.13.17" - }, - "dependencies": { - "@babel/generator": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", - "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", - "dev": true, - "requires": { - "@babel/types": "^7.13.16", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==", - "dev": true - }, - "@babel/traverse": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", - "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.16", - "@babel/types": "^7.13.17", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", - "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - } + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" } }, "@babel/highlight": { @@ -408,9 +331,9 @@ } }, "@babel/parser": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz", - "integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", "dev": true }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { @@ -445,6 +368,16 @@ "@babel/helper-plugin-utils": "^7.13.0" } }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.13.11.tgz", + "integrity": "sha512-fJTdFI4bfnMjvxJyNuaf8i9mVcZ0UhetaGEUHaHV9KEnibLugJkZAtXikR8KcYj+NYmI4DZMS8yQAyg+hvfSqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-class-static-block": "^7.12.13" + } + }, "@babel/plugin-proposal-dynamic-import": { "version": "7.13.8", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", @@ -549,6 +482,18 @@ "@babel/helper-plugin-utils": "^7.13.0" } }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz", + "integrity": "sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-create-class-features-plugin": "^7.14.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.0" + } + }, "@babel/plugin-proposal-unicode-property-regex": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", @@ -577,6 +522,15 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz", + "integrity": "sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, "@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", @@ -658,6 +612,15 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz", + "integrity": "sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, "@babel/plugin-syntax-top-level-await": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", @@ -697,12 +660,12 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz", - "integrity": "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.1.tgz", + "integrity": "sha512-2mQXd0zBrwfp0O1moWIhPpEeTKDvxyHcnma3JATVP1l+CctWBuot6OJG8LQ4DnBj4ZZPSmlb/fm4mu47EOAnVA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-classes": { @@ -730,9 +693,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz", - "integrity": "sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==", + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz", + "integrity": "sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0" @@ -805,25 +768,25 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", - "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.0.tgz", + "integrity": "sha512-CF4c5LX4LQ03LebQxJ5JZes2OYjzBuk1TdiF7cG7d5dK4lAdw9NZmaxq5K/mouUdNeqwz3TNjnW6v01UqUNgpQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-module-transforms": "^7.14.0", "@babel/helper-plugin-utils": "^7.13.0", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", - "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz", + "integrity": "sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-module-transforms": "^7.14.0", "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-simple-access": "^7.12.13", + "@babel/helper-simple-access": "^7.13.12", "babel-plugin-dynamic-import-node": "^2.3.3" } }, @@ -841,12 +804,12 @@ } }, "@babel/plugin-transform-modules-umd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", - "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz", + "integrity": "sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-module-transforms": "^7.14.0", "@babel/helper-plugin-utils": "^7.13.0" } }, @@ -980,18 +943,19 @@ } }, "@babel/preset-env": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.15.tgz", - "integrity": "sha512-D4JAPMXcxk69PKe81jRJ21/fP/uYdcTZ3hJDF5QX2HSI9bBxxYw/dumdR6dGumhjxlprHPE4XWoPaqzZUVy2MA==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.1.tgz", + "integrity": "sha512-0M4yL1l7V4l+j/UHvxcdvNfLB9pPtIooHTbEhgD/6UGyh8Hy3Bm1Mj0buzjDXATCSz3JFibVdnoJZCrlUCanrQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-compilation-targets": "^7.13.13", + "@babel/compat-data": "^7.14.0", + "@babel/helper-compilation-targets": "^7.13.16", "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-validator-option": "^7.12.17", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", "@babel/plugin-proposal-async-generator-functions": "^7.13.15", "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-class-static-block": "^7.13.11", "@babel/plugin-proposal-dynamic-import": "^7.13.8", "@babel/plugin-proposal-export-namespace-from": "^7.12.13", "@babel/plugin-proposal-json-strings": "^7.13.8", @@ -1002,9 +966,11 @@ "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", "@babel/plugin-proposal-optional-chaining": "^7.13.12", "@babel/plugin-proposal-private-methods": "^7.13.0", + "@babel/plugin-proposal-private-property-in-object": "^7.14.0", "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.12.13", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.3", @@ -1014,14 +980,15 @@ "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.0", "@babel/plugin-syntax-top-level-await": "^7.12.13", "@babel/plugin-transform-arrow-functions": "^7.13.0", "@babel/plugin-transform-async-to-generator": "^7.13.0", "@babel/plugin-transform-block-scoped-functions": "^7.12.13", - "@babel/plugin-transform-block-scoping": "^7.12.13", + "@babel/plugin-transform-block-scoping": "^7.14.1", "@babel/plugin-transform-classes": "^7.13.0", "@babel/plugin-transform-computed-properties": "^7.13.0", - "@babel/plugin-transform-destructuring": "^7.13.0", + "@babel/plugin-transform-destructuring": "^7.13.17", "@babel/plugin-transform-dotall-regex": "^7.12.13", "@babel/plugin-transform-duplicate-keys": "^7.12.13", "@babel/plugin-transform-exponentiation-operator": "^7.12.13", @@ -1029,10 +996,10 @@ "@babel/plugin-transform-function-name": "^7.12.13", "@babel/plugin-transform-literals": "^7.12.13", "@babel/plugin-transform-member-expression-literals": "^7.12.13", - "@babel/plugin-transform-modules-amd": "^7.13.0", - "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/plugin-transform-modules-amd": "^7.14.0", + "@babel/plugin-transform-modules-commonjs": "^7.14.0", "@babel/plugin-transform-modules-systemjs": "^7.13.8", - "@babel/plugin-transform-modules-umd": "^7.13.0", + "@babel/plugin-transform-modules-umd": "^7.14.0", "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", "@babel/plugin-transform-new-target": "^7.12.13", "@babel/plugin-transform-object-super": "^7.12.13", @@ -1048,7 +1015,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.12.13", "@babel/plugin-transform-unicode-regex": "^7.12.13", "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.13.14", + "@babel/types": "^7.14.1", "babel-plugin-polyfill-corejs2": "^0.2.0", "babel-plugin-polyfill-corejs3": "^0.2.0", "babel-plugin-polyfill-regenerator": "^0.2.0", @@ -1083,9 +1050,9 @@ } }, "@babel/runtime": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", - "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", + "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -1103,30 +1070,37 @@ } }, "@babel/traverse": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz", - "integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", + "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", + "@babel/generator": "^7.14.0", "@babel/helper-function-name": "^7.12.13", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.15", - "@babel/types": "^7.13.14", + "@babel/parser": "^7.14.0", + "@babel/types": "^7.14.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", - "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", + "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.0", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "dev": true + } } }, "@balancer-labs/sor": { @@ -1661,31 +1635,31 @@ "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==" }, "@uniswap/v3-core": { - "version": "1.0.0-rc.2", - "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0-rc.2.tgz", - "integrity": "sha512-vsqkqAHPCKsVi0nWwWeX+mHnSTJ8ZUdu1zAVXB9Mj9A+aeBQGV9foRKs9ufDGJq7S1nqmz+7FdjSOcVoeiUqgQ==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0.tgz", + "integrity": "sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==" }, "@uniswap/v3-periphery": { - "version": "1.0.0-beta.23", - "resolved": "https://registry.npmjs.org/@uniswap/v3-periphery/-/v3-periphery-1.0.0-beta.23.tgz", - "integrity": "sha512-5cvK8/ITIVql+iZdPd0TR5EiNNm55ejAspjIxcsnGKyflaeQb+ePw6X4HTruTPGvPoaFvk+UirYeezUspXhlcg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@uniswap/v3-periphery/-/v3-periphery-1.0.0.tgz", + "integrity": "sha512-kRqUrjnyh+X1wJdSENPDFr9sjRVebv2KyLtfqDOPij0dXJ69GspFU2qrZXjouc6LYdkWG7x3fagiTlw0eGniYQ==", "requires": { "@openzeppelin/contracts": "3.4.1-solc-0.7-2", "@uniswap/lib": "^4.0.1-alpha", "@uniswap/v2-core": "1.0.1", - "@uniswap/v3-core": "1.0.0-rc.2", + "@uniswap/v3-core": "1.0.0", "base64-sol": "1.0.1" } }, "@uniswap/v3-sdk": { - "version": "1.0.0-alpha.29", - "resolved": "https://registry.npmjs.org/@uniswap/v3-sdk/-/v3-sdk-1.0.0-alpha.29.tgz", - "integrity": "sha512-fGwCin5VRzvv605I4vjt1erT9BmJJk/T7UD9GxjCs9NZTVzoJ0mqvTacGvg3EXbzmXD1PtlNmUgfYUvN4uq4bg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@uniswap/v3-sdk/-/v3-sdk-1.0.3.tgz", + "integrity": "sha512-izIrHTAXCeMhfye0nHntoAS0UTbpa8HyGSD++Zmy+kROeb2gSAcpXvnLHzRDIPxq0G4rOH0h05Y5fhHAxaXj5w==", "requires": { "@ethersproject/abi": "^5.0.12", "@ethersproject/solidity": "^5.0.9", "@uniswap/sdk-core": "^1.0.10", - "@uniswap/v3-periphery": "^1.0.0-beta.23", + "@uniswap/v3-periphery": "1.0.0", "tiny-invariant": "^1.1.0", "tiny-warning": "^1.0.3" } @@ -2161,14 +2135,14 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, "browserslist": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", - "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001208", + "caniuse-lite": "^1.0.30001219", "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.712", + "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", "node-releases": "^1.1.71" } @@ -2269,9 +2243,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001214", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz", - "integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==", + "version": "1.0.30001223", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", + "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", "dev": true }, "capture-console": { @@ -2499,12 +2473,12 @@ "dev": true }, "core-js-compat": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.10.1.tgz", - "integrity": "sha512-ZHQTdTPkqvw2CeHiZC970NNJcnwzT6YIueDMASKt+p3WbZsLXOcoD392SkcWhkC0wBBHhlfhqGKKsNCQUozYtg==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.12.0.tgz", + "integrity": "sha512-vvaN8EOvYBEjrr+MN3vCKrMNc/xdYZI+Rt/uPMROi4T5Hj8Fz6TiPQm2mrB9aZoQVW1lCFHYmMrv99aUct9mkg==", "dev": true, "requires": { - "browserslist": "^4.16.3", + "browserslist": "^4.16.6", "semver": "7.0.0" }, "dependencies": { @@ -2681,9 +2655,9 @@ } }, "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" }, "duplexer3": { "version": "0.1.4", @@ -2697,9 +2671,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.717", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz", - "integrity": "sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ==", + "version": "1.3.727", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", + "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", "dev": true }, "elliptic": { @@ -3731,9 +3705,9 @@ } }, "helmet": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.5.0.tgz", - "integrity": "sha512-GfxdTaKarneWOpxmiVb/1YsY+fIwDOxVUGrvNEM1MC8W6Z2PREfkXiWF4XHQdvkyXwUTHuY4DRwB0uH/Q6BVyQ==" + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.6.0.tgz", + "integrity": "sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg==" }, "hmac-drbg": { "version": "1.0.1", @@ -6118,14 +6092,52 @@ } }, "winston-daily-rotate-file": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.2.tgz", - "integrity": "sha512-DpAz9djExzFGVGRIKCKzsjOQaIINbjOUJ8CRsZGz0SQOMMcO1kM7jqTdzQAM9CRTEksZV9bBw9TT0ddQBGxs9g==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.4.tgz", + "integrity": "sha512-jq7Y2kjonNipXBtsuJOhu4UadKELwfogzHcV6WtrPf6io2YJN/mH7NC0ZWMuIQ4ZEeUm3L2QlV0Fk+o4YwS5Sw==", "requires": { "file-stream-rotator": "^0.5.7", "object-hash": "^2.0.1", "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" + "winston-transport": "https://github.com/winstonjs/winston-transport/archive/868d6577956f82ee0b021b119a4de938c61645f7.tar.gz" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "winston-transport": { + "version": "https://github.com/winstonjs/winston-transport/archive/868d6577956f82ee0b021b119a4de938c61645f7.tar.gz", + "integrity": "sha512-VvPC8ef3s6OX+dJJROxGwwZ66qjlfv75n0+alCXYoVPxMMSJAHlH0GpOcHj+jcWF65Es3SLgBf/7p5XsrIfVeg==", + "requires": { + "logform": "^2.2.0", + "readable-stream": "^2.3.7", + "triple-beam": "^1.2.0" + } + } } }, "winston-transport": { diff --git a/package.json b/package.json index 64cd551..39d1a3a 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,9 @@ "@perp/contract": "^1.0.6", "@terra-money/terra.js": "^1.7.0", "@uniswap/sdk": "^3.0.3", - "@uniswap/v3-core": "^1.0.0-rc.2", - "@uniswap/v3-periphery": "^1.0.0-beta.23", - "@uniswap/v3-sdk": "^1.0.0-alpha.29", + "@uniswap/v3-core": "^1.0.0", + "@uniswap/v3-periphery": "^1.0.0", + "@uniswap/v3-sdk": "^1.0.3", "abi-decoder": "^2.4.0", "app-root-path": "^3.0.0", "axios": "^0.21.1", @@ -27,23 +27,23 @@ "capture-console": "^1.0.1", "cross-fetch": "^3.0.6", "debug": "^4.2.0", - "dotenv": "^8.2.0", + "dotenv": "^8.6.0", "ethers": "^5.1.4", "express": "^4.17.1", "express-ipfilter": "^1.1.2", - "helmet": "^4.1.1", + "helmet": "^4.6.0", "http-status-codes": "^2.1.3", "lodash": "^4.17.20", "mathjs": "^9.3.0", "moment": "^2.29.1", "util": "^0.12.3", "winston": "^3.3.3", - "winston-daily-rotate-file": "^4.5.0" + "winston-daily-rotate-file": "^4.5.4" }, "devDependencies": { - "@babel/core": "^7.13.16", + "@babel/core": "^7.14.0", "@babel/node": "^7.10.5", - "@babel/preset-env": "^7.11.5", + "@babel/preset-env": "^7.14.1", "eslint": "^7.25.0", "eslint-config-standard": "^14.1.1", "eslint-plugin-import": "^2.22.1", diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index dbc1a23..3e42aab 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -314,7 +314,7 @@ router.post('/approve', async (req, res) => { let amount paramData.amount ? amount = ethers.utils.parseUnits(paramData.amount, decimals) - : amount = ethers.utils.parseUnits('1000000000', decimals) // approve for 1 billion units if no amount specified + : amount = ethers.constants.MaxUint256 // approve max possible units if no amount specified let gasPrice if (paramData.gasPrice) { gasPrice = parseFloat(paramData.gasPrice) diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js index a62eb50..64f01a5 100644 --- a/src/routes/uniswap_v3.route.js +++ b/src/routes/uniswap_v3.route.js @@ -7,37 +7,37 @@ import Ethereum from '../services/eth'; import UniswapV3 from '../services/uniswap_v3'; import Fees from '../services/fees'; -require('dotenv').config() +require('dotenv').config(); -const debug = require('debug')('router') -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) -const uniswap = new UniswapV3(process.env.ETHEREUM_CHAIN) +const debug = require('debug')('router'); +const router = express.Router(); +const eth = new Ethereum(process.env.ETHEREUM_CHAIN); +const uniswap = new UniswapV3(process.env.ETHEREUM_CHAIN); -const fees = new Fees() +const fees = new Fees(); //const swapMoreThanMaxPriceError = 'Price too high' //const swapLessThanMaxPriceError = 'Price too low' const estimateGasLimit = () => { - return uniswap.gasLimit + return uniswap.gasLimit; } const getErrorMessage = (err) => { /* [WIP] Custom error message based-on string match */ - let message = err + let message = err; if (err.includes('failed to meet quorum')) { - message = 'Failed to meet quorum in Uniswap' + message = 'Failed to meet quorum in Uniswap'; } else if (err.includes('Invariant failed: ADDRESSES')) { - message = 'Invariant failed: ADDRESSES' + message = 'Invariant failed: ADDRESSES'; } else if (err.includes('"call revert exception')) { - message = statusMessages.no_pool_available + message = statusMessages.no_pool_available; } else if (err.includes('"trade" is read-only')) { - message = statusMessages.no_pool_available + message = statusMessages.no_pool_available; } - return message + return message; } router.post('/', async (req, res) => { @@ -66,8 +66,8 @@ router.post('/gas-limit', async (req, res) => { timestamp: Date.now(), }) } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? reason = err.reason : reason = statusMessages.operation_error res.status(500).json({ error: reason, @@ -83,9 +83,9 @@ router.get('/result', async (req, res) => { "logs":"[...]" } */ - const initTime = Date.now() - const paramData = getParamData(req.query) - const logs = JSON.parse(paramData.logs) + const initTime = Date.now(); + const paramData = getParamData(req.query); + const logs = JSON.parse(paramData.logs); const result = { network: eth.network, @@ -93,7 +93,7 @@ router.get('/result', async (req, res) => { latency: latency(initTime, Date.now()), info: uniswap.abiDecoder.decodeLogs(logs) } - res.status(200).json(result) + res.status(200).json(result); }) router.post('/trade', async (req, res) => { @@ -110,32 +110,32 @@ router.post('/trade', async (req, res) => { "side":{buy|sell} } */ - const initTime = Date.now() + const initTime = Date.now(); // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) - const amount = paramData.amount - - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() - const tier = paramData.tier.toUpperCase() - - let limitPrice + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const amount = paramData.amount; + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const side = paramData.side.toUpperCase(); + const tier = paramData.tier.toUpperCase(); + + let limitPrice; if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice) + limitPrice = parseFloat(paramData.limitPrice); } else { limitPrice = 0} - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { if (side === 'BUY') { @@ -148,8 +148,6 @@ router.post('/trade', async (req, res) => { tier, gasPrice ) - console.log(tx) - console.log(tx.expectedAmount) // submit response res.status(200).json({ network: uniswap.network, @@ -213,31 +211,31 @@ router.post('/price', async (req, res) => { "base":"DAI" } */ - const initTime = Date.now() + const initTime = Date.now(); // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, uniswap.provider); - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; //const side = paramData.side.toUpperCase() // not used for now - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { // fetch pools for all tiers - const prices = await uniswap.currentPrice(wallet, baseTokenAddress, quoteTokenAddress) + const prices = await uniswap.currentPrice(wallet, baseTokenAddress, quoteTokenAddress); const result = { network: uniswap.network, @@ -251,18 +249,18 @@ router.post('/price', async (req, res) => { gasCost: gasCost, } debug(`Mid Price ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | (rate:${JSON.stringify(prices)}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) - res.status(200).json(result) + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - let errCode = 500 + logger.error(req.originalUrl, { message: err }); + let reason; + let errCode = 500; if (Object.keys(err).includes('isInsufficientReservesError')) { - errCode = 200 - reason = statusMessages.insufficient_reserves + ' in ' + side + ' at Uniswap' + errCode = 200; + reason = statusMessages.insufficient_reserves + ' in ' + side + ' at Uniswap'; } else if (Object.getOwnPropertyNames(err).includes('message')) { - reason = getErrorMessage(err.message) + reason = getErrorMessage(err.message); if (reason === statusMessages.no_pool_available) { - errCode = 200 + errCode = 200; res.status(errCode).json({ info: reason, message: err @@ -287,11 +285,11 @@ router.post('/position', async (req, res) => { "tokenId":"tokenId" } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) - const tokenId = paramData.tokenId + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const tokenId = paramData.tokenId; try { // fetch position data @@ -303,13 +301,13 @@ router.post('/position', async (req, res) => { latency: latency(initTime, Date.now()), position: positionData } - debug(`Position data: ${positionData} `) - res.status(200).json(result) + debug(`Position data: ${positionData} `); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) - res.status(200).json({ + logger.error(req.originalUrl, { message: err }); + res.status(500).json({ info: statusMessages.operation_error, - message: err + position: {} }) } }) @@ -327,27 +325,27 @@ router.post('/add-position', async (req, res) => { "amount1": amount1 } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) - - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1) - const fee = paramData.fee - const lowerPrice = paramData.lowerPrice - const upperPrice = paramData.upperPrice - const amount0 = paramData.amount0 - const amount1 = paramData.amount1 - - let gasPrice + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, uniswap.provider); + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1); + const fee = paramData.fee; + const lowerPrice = parseFloat(paramData.lowerPrice); + const upperPrice = parseFloat(paramData.upperPrice); + const amount0 = paramData.amount0; + const amount1 = paramData.amount1; + + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { @@ -370,10 +368,10 @@ router.post('/add-position', async (req, res) => { gasLimit: gasLimit, gasCost: gasCost } - debug(`New Position: ${newPosition.hash}`) - res.status(200).json(result) + debug(`New Position: ${newPosition.hash}`); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) + logger.error(req.originalUrl, { message: err }); res.status(200).json({ info: statusMessages.operation_error, message: err @@ -383,30 +381,30 @@ router.post('/add-position', async (req, res) => { router.post('/remove-position', async (req, res) => { /* - POST: /position + POST: /remove-position x-www-form-urlencoded: { "tokenId":"12" } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) - const tokenId = paramData.tokenId + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const tokenId = paramData.tokenId; - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { - const removelp = await uniswap.removePosition(wallet, tokenId) + const removelp = await uniswap.removePosition(wallet, tokenId); const result = { network: uniswap.network, @@ -417,13 +415,13 @@ router.post('/remove-position', async (req, res) => { gasLimit: gasLimit, gasCost: gasCost, } - debug(`Remove lp: ${removelp.hash}`) - res.status(200).json(result) + debug(`Remove lp: ${removelp.hash}`); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - let errCode = 500 - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + let errCode = 500; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(errCode).json({ error: reason, message: err @@ -431,40 +429,48 @@ router.post('/remove-position', async (req, res) => { } }) -router.post('/adjust-liquidity', async (req, res) => { +router.post('/replace-position', async (req, res) => { /* - POST: /position + POST: /replace-position x-www-form-urlencoded: { - "action":"INCREASE"/"DECREASE" "tokenId":"tokenId" + "token0":"BAT" + "token1":"DAI" + "fee":1 + "lowerPrice": 1 + "upperPrice": 2 "amount0": amount0 "amount1": amount1 } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) - const action = paramData.action.toUpperCase() - const tokenId = paramData.tokenId - const amount0 = paramData.amount0 - const amount1 = paramData.amount1 - - let gasPrice + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const tokenId = paramData.tokenId; + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1); + const fee = paramData.fee; + const lowerPrice = parseFloat(paramData.lowerPrice); + const upperPrice = parseFloat(paramData.upperPrice); + const amount0 = paramData.amount0; + const amount1 = paramData.amount1; + + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { - const position = await uniswap.getPosition(wallet, tokenId) - const token0 = eth.getERC20TokenByAddress(position.token0) - const token1 = eth.getERC20TokenByAddress(position.token1) - const positionChange = await uniswap.adjustLiquidity(wallet, action, tokenId, token0, token1, amount0, amount1); + // const position = await uniswap.getPosition(wallet, tokenId) + // const token0 = eth.getERC20TokenByAddress(position.token0) + // const token1 = eth.getERC20TokenByAddress(position.token1) + const positionChange = await uniswap.replacePosition(wallet, tokenId, baseTokenContractInfo, quoteTokenContractInfo, amount0, amount1, fee, lowerPrice, upperPrice); const result = { network: uniswap.network, @@ -478,10 +484,10 @@ router.post('/adjust-liquidity', async (req, res) => { gasLimit: gasLimit, gasCost: gasCost, } - debug(`Position change ${positionChange.hash}`) - res.status(200).json(result) + debug(`Position change ${positionChange.hash}`); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) + logger.error(req.originalUrl, { message: err }); res.status(200).json({ info: statusMessages.operation_error, message: err @@ -498,20 +504,20 @@ router.post('/collect-fees', async (req, res) => { "amount1": amount1 } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) - const tokenId = paramData.tokenId + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const tokenId = paramData.tokenId; - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { @@ -528,10 +534,10 @@ router.post('/collect-fees', async (req, res) => { gasLimit: gasLimit, gasCost: gasCost, } - debug(`Fees: ${collect.hash}`) - res.status(200).json(result) + debug(`Fees: ${collect.hash}`); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) + logger.error(req.originalUrl, { message: err }); res.status(200).json({ info: statusMessages.operation_error, message: err diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js index a6b8114..5af19a1 100644 --- a/src/services/uniswap_v3.js +++ b/src/services/uniswap_v3.js @@ -1,5 +1,5 @@ import { logger } from './logger'; -import { encodePriceSqrt, getLiquidity, getTickFromPrice } from '../static/uniswap-v3/helper_functions'; +import { encodePriceSqrt, getLiquidity, getTickFromPrice, toHex, expandTo18Decimals } from '../static/uniswap-v3/helper_functions'; const debug = require('debug')('router') const math = require('mathjs') @@ -53,7 +53,6 @@ export default class UniswapV3 { default: const err = `Invalid network ${network}` logger.error(err) - throw Error(err) } } @@ -78,7 +77,7 @@ export default class UniswapV3 { if (values[pool].value === ethers.constants.AddressZero) { poolPrices[pool] = 0 } else { poolContract = new ethers.Contract(values[pool].value, poolArtifact.abi, wallet) - poolPrices[pool] = poolContract.observe([13]); + poolPrices[pool] = poolContract.observe([1, 0]); } } }) @@ -89,19 +88,18 @@ export default class UniswapV3 { for (let tick of values[pool].value.tickCumulatives) { poolPrices[pool] = tick.toNumber() - poolPrices[pool]; } - poolPrices[pool] /= 13; poolPrices[pool] = math.pow(1.0001, poolPrices[pool]) } } }) - return Object.assign(...keys.map((k, i) => ({[k]: poolPrices[i]}))) + return Object.assign(...keys.map((k, i) => ({[k]: poolPrices[i]}))); } async swapExactIn (wallet, baseTokenContractInfo, quoteTokenContractInfo, baseAmount, limitPrice, tier, gasPrice) { //sell, In => base, Out => quote - const minPercentOut = (1 - (this.slippage / 100)) - const amountOutMinimum = math.floor(baseAmount * limitPrice * minPercentOut, quoteTokenContractInfo.decimals) + const minPercentOut = (1 - (this.slippage / 100)); + const amountOutMinimum = math.floor(baseAmount * limitPrice * minPercentOut, quoteTokenContractInfo.decimals); //const priceFraction = math.fraction(limitPrice) const contract = this.get_contract("router", wallet); const tx = await contract.exactInputSingle({ @@ -122,14 +120,14 @@ export default class UniswapV3 { ) debug(`Tx Hash: ${tx.hash}`); - tx.expectedAmount = amountOutMinimum - return tx + tx.expectedAmount = amountOutMinimum; + return tx; } async swapExactOut (wallet, baseTokenContractInfo, quoteTokenContractInfo, baseAmount, limitPrice, tier, gasPrice) { //buy, In => quote, Out => base - const maxPercentIn = (1 + (this.slippage / 100)) - const amountInMaximum = math.ceil(baseAmount * limitPrice * maxPercentIn, quoteTokenContractInfo.decimals) + const maxPercentIn = (1 + (this.slippage / 100)); + const amountInMaximum = math.ceil(baseAmount * limitPrice * maxPercentIn, quoteTokenContractInfo.decimals); //const priceFraction = math.fraction(limitPrice) const contract = this.get_contract("router", wallet); const tx = await contract.exactOutputSingle({ @@ -150,8 +148,8 @@ export default class UniswapV3 { ) debug(`Tx Hash: ${tx.hash}`); - tx.expectedAmount = amountInMaximum - return tx + tx.expectedAmount = amountInMaximum; + return tx; } // LP section @@ -164,9 +162,9 @@ export default class UniswapV3 { operator: position[1], token0: position[2], token1: position[3], - fee: position[4], - tickLower: position[5], - tickUpper: position[6], + fee: Object.keys(FeeAmount).find(key => FeeAmount[key] === position[4]), + lowerPrice: math.pow(1.0001, position[5]), + upperPrice: math.pow(1.0001, position[6]), liquidity: position[7].toString(), feeGrowthInside0LastX128: position[8].toString(), feeGrowthInside1LastX128: position[9].toString(), @@ -174,22 +172,28 @@ export default class UniswapV3 { tokensOwed1: position[11].toString() } - return position + return position; } - async addPosition (wallet, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice) { - try{ - const nftContract = this.get_contract("nft", wallet); - const coreContract = this.get_contract("core", wallet); - const pool = await coreContract.getPool(token0.address, token1.address, FeeAmount[fee]); - const midPrice = math.fraction((lowerPrice + upperPrice) / 2) // Use mid price to initialize uninitialized pool + getRemoveLiquidityData(wallet, contract, tokenId, liquidity) { + const decreaseLiquidityData = contract.interface.encodeFunctionData('decreaseLiquidity', [{ + tokenId: tokenId, + liquidity: liquidity, + amount0Min: 0, + amount1Min: 0, + deadline: Date.now() + TTL}]); + const collectFeesData = contract.interface.encodeFunctionData('collect', [{ + tokenId: tokenId, + recipient: wallet.address, + amount0Max: MaxUint128, + amount1Max: MaxUint128}]); + const burnData = contract.interface.encodeFunctionData('burn', [tokenId]); - const initPoolData = nftContract.interface.encodeFunctionData('createAndInitializePoolIfNecessary', [ - token0.address, - token1.address, - FeeAmount[fee], - encodePriceSqrt(midPrice.n, midPrice.d)]); - const mintData = nftContract.interface.encodeFunctionData('mint', [{ + return [decreaseLiquidityData, collectFeesData, burnData]; + } + + getAddLiquidityData(wallet, contract, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice) { + const mintData = contract.interface.encodeFunctionData('mint', [{ token0: token0.address, token1: token1.address, tickLower: getTickFromPrice(lowerPrice, fee, "UPPER"), @@ -204,36 +208,51 @@ export default class UniswapV3 { fee: FeeAmount[fee] }]); - let calls = [mintData] + return mintData; + } - if (pool === ethers.constants.AddressZero) { const calls = [initPoolData, mintData] } + async addPosition (wallet, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice) { + const nftContract = this.get_contract("nft", wallet); + const coreContract = this.get_contract("core", wallet); + const pool = await coreContract.getPool(token0.address, token1.address, FeeAmount[fee]); + const midPrice = math.fraction((lowerPrice + upperPrice) / 2); // Use mid price to initialize uninitialized pool + + const initPoolData = nftContract.interface.encodeFunctionData('createAndInitializePoolIfNecessary', [ + token0.address, + token1.address, + FeeAmount[fee], + encodePriceSqrt(midPrice.n, midPrice.d)]); - const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }); + const mintData = this.getAddLiquidityData(wallet, nftContract, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice); - return tx; - } catch(err) { console.log(err)} + let calls = [mintData] + if (pool === ethers.constants.AddressZero) { + const tx = await nftContract.multicall([initPoolData, mintData], { gasLimit: GAS_LIMIT }); + return tx; + } + else { + const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }); + return tx; } +} async removePosition (wallet, tokenId) { // Reduce position and burn - let positionData = await this.getPosition(wallet, tokenId); + const positionData = await this.getPosition(wallet, tokenId); const contract = this.get_contract("nft", wallet); - const decreaseLiquidityData = contract.interface.encodeFunctionData('decreaseLiquidity', [{ - tokenId: tokenId, - liquidity: positionData.liquidity, - amount0Min: 0, - amount1Min: 0, - deadline: Date.now() + TTL}]); - const collectFeesData = contract.interface.encodeFunctionData('collect', [{ - tokenId: tokenId, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128}]); - const burnData = contract.interface.encodeFunctionData('burn', [tokenId]); - - return await contract.multicall([decreaseLiquidityData, collectFeesData, burnData], { gasLimit: GAS_LIMIT }); + const data = this.getRemoveLiquidityData(wallet, contract, tokenId, positionData.liquidity); + return await contract.multicall(data, { gasLimit: GAS_LIMIT }); } + async replacePosition ( wallet, tokenId, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice) { + const contract = this.get_contract("nft", wallet); + let positionData = await this.getPosition(wallet, tokenId); + const removeData = this.getRemoveLiquidityData(wallet, contract, tokenId, positionData.liquidity); + const mintData = this.getAddLiquidityData(wallet, contract, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice); + + return await contract.multicall(removeData.concat(mintData), { gasLimit: GAS_LIMIT }); + } + /* async adjustLiquidity (wallet, action, tokenId, token0, token1, amount0, amount1) { const contract = this.get_contract("nft", wallet); const parsedAmount0 = ethers.utils.parseUnits(amount0, token0.decimals) @@ -250,7 +269,6 @@ export default class UniswapV3 { } else { //const liquidity = getLiquidity(ethers.utils.parseUnits(amount0, 6), ethers.utils.parseUnits(amount1, 6)) // use method from sdk to calculate liquidity from amount correctly const liquidity = getLiquidity(amount0, amount1) - console.log(liquidity.toString()) const decreaseLiquidityData = contract.interface.encodeFunctionData('decreaseLiquidity', [{ tokenId: tokenId, liquidity: liquidity, @@ -266,6 +284,7 @@ export default class UniswapV3 { //return await contract.multicall([decreaseLiquidityData, collectFeesData], { gasLimit: GAS_LIMIT }); } } + */ async collectFees (wallet, tokenId) { const contract = this.get_contract("nft", wallet); diff --git a/src/static/uniswap-v3/helper_functions.js b/src/static/uniswap-v3/helper_functions.js index f028eca..2549d75 100644 --- a/src/static/uniswap-v3/helper_functions.js +++ b/src/static/uniswap-v3/helper_functions.js @@ -7,6 +7,19 @@ const TICK_SPACINGS = { LOW: 10, MEDIUM: 60, HIGH: 2000 }; bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }) +export function expandTo18Decimals(n) { + return BigNumber.from(n).mul(BigNumber.from(10).pow(18)) +} + +export function toHex(bigintIsh) { + const bigInt = JSBI.BigInt(bigintIsh) + let hex = bigInt.toString(16) + if (hex.length % 2 !== 0) { + hex = `0${hex}` + } + return `0x${hex}` +} + // returns the sqrt price as a 64x96 export function encodePriceSqrt(reserve1, reserve0) { return BigNumber.from( From 88e95eea7aef955e06626d447b608c09147fdcff Mon Sep 17 00:00:00 2001 From: vic-en Date: Fri, 7 May 2021 09:24:13 +0100 Subject: [PATCH 11/31] (feat) update postman collection --- ...son => Uniswap_V3_postman_collection.json} | 71 +++++++++++++------ 1 file changed, 48 insertions(+), 23 deletions(-) rename test/postman/{Uniswap V3.postman_collection.json => Uniswap_V3_postman_collection.json} (88%) diff --git a/test/postman/Uniswap V3.postman_collection.json b/test/postman/Uniswap_V3_postman_collection.json similarity index 88% rename from test/postman/Uniswap V3.postman_collection.json rename to test/postman/Uniswap_V3_postman_collection.json index 24dfcc5..877abbd 100644 --- a/test/postman/Uniswap V3.postman_collection.json +++ b/test/postman/Uniswap_V3_postman_collection.json @@ -111,12 +111,12 @@ "urlencoded": [ { "key": "base", - "value": "DAI", + "value": "COIN1", "type": "text" }, { "key": "quote", - "value": "USDC", + "value": "COIN2", "type": "text" }, { @@ -153,22 +153,22 @@ "urlencoded": [ { "key": "base", - "value": "WETH", + "value": "COIN1", "type": "text" }, { "key": "quote", - "value": "DAI", + "value": "COIN2", "type": "text" }, { "key": "amount", - "value": "0.25", + "value": "0.000009", "type": "text" }, { "key": "limitPrice", - "value": "1.2115524", + "value": "0.000000000025", "type": "text" }, { @@ -186,6 +186,11 @@ "key": "side", "value": "buy", "type": "text" + }, + { + "key": "tier", + "value": "HIGH", + "type": "text" } ] }, @@ -216,7 +221,7 @@ "urlencoded": [ { "key": "tokenId", - "value": "43", + "value": "66", "type": "text" }, { @@ -280,17 +285,17 @@ }, { "key": "fee", - "value": "MEDIUM", + "value": "LOW", "type": "text" }, { - "key": "tickLower", - "value": "5", + "key": "lowerPrice", + "value": "1561", "type": "text" }, { - "key": "tickUpper", - "value": "10", + "key": "upperPrice", + "value": "1570", "type": "text" }, { @@ -323,7 +328,7 @@ "response": [] }, { - "name": "eth/uniswap/v3/adjust-liquidity", + "name": "eth/uniswap/v3/replace-position", "request": { "method": "POST", "header": [], @@ -342,29 +347,49 @@ "type": "text" }, { - "key": "action", - "value": "DECREASE", + "key": "token0", + "value": "COIN1", + "type": "text" + }, + { + "key": "token1", + "value": "COIN2", + "type": "text" + }, + { + "key": "fee", + "value": "MEDIUM", + "type": "text" + }, + { + "key": "lowerPrice", + "value": "6", + "type": "text" + }, + { + "key": "upperPrice", + "value": "20", "type": "text" }, { "key": "amount0", - "value": "1", + "value": "2", "type": "text" }, { "key": "amount1", - "value": "1", + "value": "2", "type": "text" }, { "key": "tokenId", - "value": "43", + "value": "69", "type": "text" } ] }, "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/adjust-liquidity", + "raw": "https://localhost:{{port}}/eth/uniswap/v3/replace-position", "protocol": "https", "host": [ "localhost" @@ -374,7 +399,7 @@ "eth", "uniswap", "v3", - "adjust-liquidity" + "replace-position" ] } }, @@ -407,7 +432,7 @@ ] }, "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/collect-fees", + "raw": "https://localhost:{{port}}/eth/uniswap/v3//collect-fees", "protocol": "https", "host": [ "localhost" @@ -445,7 +470,7 @@ }, { "key": "tokenId", - "value": "", + "value": "66", "type": "text" } ] @@ -490,4 +515,4 @@ ] } ] -} +} \ No newline at end of file From 3a963613b16cd65105ba14b6f1e3d62192c46ae5 Mon Sep 17 00:00:00 2001 From: vic-en Date: Sun, 9 May 2021 22:08:55 +0100 Subject: [PATCH 12/31] (feat) add nonce manager to uniswap v3 --- .env.example | 5 ++++- package-lock.json | 10 ++++++++++ package.json | 3 ++- src/routes/eth.route.js | 3 +-- src/routes/uniswap_v3.route.js | 15 ++++++++------- src/services/uniswap_v3.js | 14 ++++++++------ src/services/utils.js | 17 +++++++++++++++++ 7 files changed, 50 insertions(+), 17 deletions(-) diff --git a/.env.example b/.env.example index 8b3e860..91aa8c2 100644 --- a/.env.example +++ b/.env.example @@ -43,9 +43,12 @@ EXCHANGE_PROXY={exchange_proxy} # Uniswap # Reference: https://uniswap.org/docs/v2/smart-contracts/router02/ -# UniswapV2Router02 is deployed at 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets. +# UniswapV2Router02 is deployed at 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets. # It was built from commit 6961711. UNISWAP_ROUTER=0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D +UNISWAP_V3_CORE=0x1F98431c8aD98523631AE4a59f267346ea31F984 +UNISWAP_V3_ROUTER=0xE592427A0AEce92De3Edee1F18E0157C05861564 +UNISWAP_V3_NFT_MANAGER=0xC36442b4a4522E871399CD717aBDD847Ab11FE88 # allowed slippage for swap transactions UNISWAP_ALLOWED_SLIPPAGE=1.5 # restrict updating pairs that have no reserves or failed for 5 minutes diff --git a/package-lock.json b/package-lock.json index 2621a34..31ec545 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1264,6 +1264,16 @@ "@ethersproject/transactions": "^5.1.0" } }, + "@ethersproject/experimental": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@ethersproject/experimental/-/experimental-5.1.2.tgz", + "integrity": "sha512-Agz2/Of+qaNddu/8XJcH2eSewwDZpEId4R1/hj3pgQagYR0hGcCjICDqYizFM4b8MoZs/nA/DuhgWnT6YmjhyQ==", + "requires": { + "@ethersproject/web": "^5.1.0", + "ethers": "^5.1.0", + "scrypt-js": "3.0.1" + } + }, "@ethersproject/hash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz", diff --git a/package.json b/package.json index 39d1a3a..34348f0 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "scripts": { "start": "babel-node src/index.js", "dev": "nodemon --exec babel-node src/index.js", - "debug": "DEBUG=*router nodemon --exec babel-node src/index.js", + "debug": "DEBUG=*router nodemon --watch src/* --exec babel-node src/index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { @@ -19,6 +19,7 @@ "@uniswap/v3-core": "^1.0.0", "@uniswap/v3-periphery": "^1.0.0", "@uniswap/v3-sdk": "^1.0.3", + "@ethersproject/experimental": "^5.1.2", "abi-decoder": "^2.4.0", "app-root-path": "^3.0.0", "axios": "^0.21.1", diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index 3e42aab..8008ab7 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -78,7 +78,7 @@ router.post('/balances', async (req, res) => { } } )).then(() => { - console.log('eth.route - Get Account Balance', { message: JSON.stringify(tokenList) }) + debug('eth.route - Get Account Balance', { message: JSON.stringify(tokenList) }) res.status(200).json({ network: eth.network, timestamp: initTime, @@ -352,7 +352,6 @@ router.post('/poll', async (req, res) => { const paramData = getParamData(req.body) const txHash = paramData.txHash const txReceipt = await eth.provider.getTransactionReceipt(txHash) - console.log(txReceipt) const receipt = {} const confirmed = txReceipt && txReceipt.blockNumber ? true : false if (confirmed) { diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js index 64f01a5..c448466 100644 --- a/src/routes/uniswap_v3.route.js +++ b/src/routes/uniswap_v3.route.js @@ -1,5 +1,6 @@ import { ethers } from 'ethers'; import express from 'express'; +import { getNonceManager } from '../services/utils'; import { getParamData, latency, statusMessages } from '../services/utils'; import { logger } from '../services/logger'; @@ -114,7 +115,7 @@ router.post('/trade', async (req, res) => { // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) const paramData = getParamData(req.body); const privateKey = paramData.privateKey; - const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); const amount = paramData.amount; const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); @@ -215,7 +216,7 @@ router.post('/price', async (req, res) => { // params: base (required), quote (required), amount (required) const paramData = getParamData(req.body); const privateKey = paramData.privateKey; - const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); @@ -288,7 +289,7 @@ router.post('/position', async (req, res) => { const initTime = Date.now(); const paramData = getParamData(req.body); const privateKey = paramData.privateKey; - const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); const tokenId = paramData.tokenId; try { @@ -328,7 +329,7 @@ router.post('/add-position', async (req, res) => { const initTime = Date.now(); const paramData = getParamData(req.body); const privateKey = paramData.privateKey; - const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0); const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1); @@ -389,7 +390,7 @@ router.post('/remove-position', async (req, res) => { const initTime = Date.now(); const paramData = getParamData(req.body); const privateKey = paramData.privateKey; - const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); const tokenId = paramData.tokenId; @@ -446,7 +447,7 @@ router.post('/replace-position', async (req, res) => { const initTime = Date.now(); const paramData = getParamData(req.body); const privateKey = paramData.privateKey; - const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); const tokenId = paramData.tokenId; const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0); const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1); @@ -507,7 +508,7 @@ router.post('/collect-fees', async (req, res) => { const initTime = Date.now(); const paramData = getParamData(req.body); const privateKey = paramData.privateKey; - const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); const tokenId = paramData.tokenId; let gasPrice; diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js index 5af19a1..c3d9e2b 100644 --- a/src/services/uniswap_v3.js +++ b/src/services/uniswap_v3.js @@ -42,6 +42,7 @@ export default class UniswapV3 { this.pairs = [] this.tokenSwapList = {} this.cachedRoutes = {} + this.abiDecoder = abiDecoder switch (network) { case 'mainnet': @@ -106,7 +107,7 @@ export default class UniswapV3 { tokenIn: baseTokenContractInfo.address, tokenOut: quoteTokenContractInfo.address, fee: FeeAmount[tier], - recipient: wallet.address, + recipient: wallet.signer.address, deadline: Date.now() + TTL, amountIn: ethers.utils.parseUnits(baseAmount, baseTokenContractInfo.decimals), amountOutMinimum: ethers.utils.parseUnits(amountOutMinimum.toString(), quoteTokenContractInfo.decimals), @@ -134,7 +135,7 @@ export default class UniswapV3 { tokenIn: quoteTokenContractInfo.address, tokenOut: baseTokenContractInfo.address, fee: FeeAmount[tier], - recipient: wallet.address, + recipient: wallet.signer.address, deadline: Date.now() + TTL, amountOut: ethers.utils.parseUnits(baseAmount, baseTokenContractInfo.decimals), amountInMaximum: ethers.utils.parseUnits(amountInMaximum.toString(), quoteTokenContractInfo.decimals), @@ -184,7 +185,7 @@ export default class UniswapV3 { deadline: Date.now() + TTL}]); const collectFeesData = contract.interface.encodeFunctionData('collect', [{ tokenId: tokenId, - recipient: wallet.address, + recipient: wallet.signer.address, amount0Max: MaxUint128, amount1Max: MaxUint128}]); const burnData = contract.interface.encodeFunctionData('burn', [tokenId]); @@ -203,7 +204,7 @@ export default class UniswapV3 { // slippage isn't applied for now amount0Min: 0, amount1Min: 0, - recipient: wallet.address, + recipient: wallet.signer.address, deadline: Date.now() + TTL, fee: FeeAmount[fee] }]); @@ -225,6 +226,7 @@ export default class UniswapV3 { const mintData = this.getAddLiquidityData(wallet, nftContract, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice); + let calls = [mintData] if (pool === ethers.constants.AddressZero) { const tx = await nftContract.multicall([initPoolData, mintData], { gasLimit: GAS_LIMIT }); @@ -277,7 +279,7 @@ export default class UniswapV3 { deadline: Date.now() + TTL}]); const collectFeesData = contract.interface.encodeFunctionData('collect', [{ tokenId: tokenId, - recipient: wallet.address, + recipient: wallet.signer.address, amount0Max: MaxUint128, amount1Max: MaxUint128}]); @@ -290,7 +292,7 @@ export default class UniswapV3 { const contract = this.get_contract("nft", wallet); return await contract.collect({ tokenId: tokenId, - recipient: wallet.address, + recipient: wallet.signer.address, amount0Max: MaxUint128, amount1Max: MaxUint128}, { gasLimit: GAS_LIMIT }); diff --git a/src/services/utils.js b/src/services/utils.js index 23182cc..19192c1 100644 --- a/src/services/utils.js +++ b/src/services/utils.js @@ -3,6 +3,7 @@ */ const lodash = require('lodash') const moment = require('moment') +const { NonceManager } = require('@ethersproject/experimental') export const statusMessages = { ssl_cert_required: 'SSL Certificate required', @@ -108,3 +109,19 @@ export const getLocalDate = () => { } return newDate } + + +export const nonceManagerCache = {} + +export const getNonceManager = async (signer) => { + let key = await signer.getAddress() + if (signer.provider) { + key += (await signer.provider.getNetwork()).chainId + } + let nonceManager = nonceManagerCache[key] + if (typeof nonceManager === 'undefined') { + nonceManager = new NonceManager(signer) + nonceManagerCache[key] = nonceManager + } + return nonceManager +} From 65ebe4a835deb67ef36c2408aac1d14f37baac59 Mon Sep 17 00:00:00 2001 From: vic-en Date: Fri, 21 May 2021 10:13:45 +0100 Subject: [PATCH 13/31] minor refactor to uni v3 --- package.json | 2 +- src/routes/uniswap_v3.route.js | 4 ++-- src/services/uniswap_v3.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 34348f0..f9ff014 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "scripts": { "start": "babel-node src/index.js", "dev": "nodemon --exec babel-node src/index.js", - "debug": "DEBUG=*router nodemon --watch src/* --exec babel-node src/index.js", + "debug": "DEBUG=*router nodemon --exec babel-node src/index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js index c448466..f252b33 100644 --- a/src/routes/uniswap_v3.route.js +++ b/src/routes/uniswap_v3.route.js @@ -77,7 +77,7 @@ router.post('/gas-limit', async (req, res) => { } }) -router.get('/result', async (req, res) => { +router.post('/result', async (req, res) => { /* POST: /eth/uniswap/v3/result x-www-form-urlencoded: { @@ -85,7 +85,7 @@ router.get('/result', async (req, res) => { } */ const initTime = Date.now(); - const paramData = getParamData(req.query); + const paramData = getParamData(req.body); const logs = JSON.parse(paramData.logs); const result = { diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js index c3d9e2b..b7fe98d 100644 --- a/src/services/uniswap_v3.js +++ b/src/services/uniswap_v3.js @@ -100,7 +100,7 @@ export default class UniswapV3 { async swapExactIn (wallet, baseTokenContractInfo, quoteTokenContractInfo, baseAmount, limitPrice, tier, gasPrice) { //sell, In => base, Out => quote const minPercentOut = (1 - (this.slippage / 100)); - const amountOutMinimum = math.floor(baseAmount * limitPrice * minPercentOut, quoteTokenContractInfo.decimals); + const amountOutMinimum = Math.floor(baseAmount * limitPrice * minPercentOut * quoteTokenContractInfo.decimals) / quoteTokenContractInfo.decimals; //const priceFraction = math.fraction(limitPrice) const contract = this.get_contract("router", wallet); const tx = await contract.exactInputSingle({ @@ -128,7 +128,7 @@ export default class UniswapV3 { async swapExactOut (wallet, baseTokenContractInfo, quoteTokenContractInfo, baseAmount, limitPrice, tier, gasPrice) { //buy, In => quote, Out => base const maxPercentIn = (1 + (this.slippage / 100)); - const amountInMaximum = math.ceil(baseAmount * limitPrice * maxPercentIn, quoteTokenContractInfo.decimals); + const amountInMaximum = Math.ceil(baseAmount * limitPrice * maxPercentIn * quoteTokenContractInfo.decimals) / quoteTokenContractInfo.decimals; //const priceFraction = math.fraction(limitPrice) const contract = this.get_contract("router", wallet); const tx = await contract.exactOutputSingle({ From 70262ee7535bba5e5d181b0bed5ef62c7d02e8b0 Mon Sep 17 00:00:00 2001 From: vic-en Date: Fri, 28 May 2021 12:35:09 +0100 Subject: [PATCH 14/31] update gateway env updates --- env.yaml | 87 +++++++++++++++++ package.json | 5 +- src/app.js | 7 -- src/index.js | 4 +- src/routes/perpetual_finance.route.js | 2 +- src/routes/uniswap.route.js | 2 +- src/services/balancer.js | 2 +- src/services/eth.js | 1 + src/services/fees.js | 8 +- src/services/logger.js | 2 +- src/services/terra.js | 2 +- yarn.lock | 132 ++++++++++++++++++++++++++ 12 files changed, 235 insertions(+), 19 deletions(-) create mode 100644 env.yaml diff --git a/env.yaml b/env.yaml new file mode 100644 index 0000000..fbb28a9 --- /dev/null +++ b/env.yaml @@ -0,0 +1,87 @@ +APPNAME: Hummingbot Gateway API +NODE_ENV: dev +PORT: 5000 + +# use only if ip whitelist is required for local or docker instance +# note that docker instance does not use 127.0.0.1 address +# ipv6 format for locahost ["::ffff:127.0.0.1", "::ffff:1", "fe80::1", "::1"] +IP_WHITELIST: + +HUMMINGBOT_INSTANCE_ID: {client_id} + +# Celo + +# Terra +# - mainnet: https://lcd.terra.dev +# - mainnet chain: columbus-4 +# - testnet: https://tequila-lcd.terra.dev +# - testnet chain: tequila-0004 +TERRA_LCD_URL: {testnet_lcd_url} +TERRA_CHAIN: {testnet_chain_id} + +# Ethereum +# - chain: mainnet, kovan, etc +# - rpc url: infura or other rpc url +# - token list: erc20 token list source (ref: https://tokenlists.org/) +ETHEREUM_CHAIN: kovan +# ETHEREUM_RPC_URL: https://mainnet.infura.io/v3/117bfd0769f54bd2b91f50d2b1c19f9a +ETHEREUM_RPC_URL: https://kovan.infura.io/v3/117bfd0769f54bd2b91f50d2b1c19f9a +ETHEREUM_TOKEN_LIST_URL: https://wispy-bird-88a7.uniswap.workers.dev/?url=http://tokens.1inch.eth.link + +# Balancer +# subgraph_chain +# Reference: https://docs.balancer.finance/sor/development#subgraph +# - mainnet: balancer +# - kovan: balancer-kovan +# Note: REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor +REACT_APP_SUBGRAPH_URL: https://api.thegraph.com/subgraphs/name/balancer-labs/{subgraph_chain} + +# exchange_proxy: +# Reference: https://docs.balancer.finance/smart-contracts/addresses +# - mainnet: 0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21 +# - kovan: 0x4e67bf5bD28Dd4b570FBAFe11D0633eCbA2754Ec +EXCHANGE_PROXY: "0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21" + +# Uniswap +# Reference: https://uniswap.org/docs/v2/smart-contracts/router02/ +# UniswapV2Router02 is deployed at 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets. +# It was built from commit 6961711. +UNISWAP_ROUTER: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D" +UNISWAP_V3_CORE: "0x1F98431c8aD98523631AE4a59f267346ea31F984" +UNISWAP_V3_ROUTER: "0xE592427A0AEce92De3Edee1F18E0157C05861564" +UNISWAP_V3_NFT_MANAGER: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88" +# allowed slippage for swap transactions +UNISWAP_ALLOWED_SLIPPAGE: 1.5 +# restrict updating pairs that have no reserves or failed for 5 minutes +uNISWAP_NO_RESERVE_CHECK_INTERVALL: 300011 +# cache info about pair for 1 second +UNISWAP_PAIRS_CACHE_TIME: 1000 + +# cert +CERT_PATH: /home/vic/hummingbot/certs/ +CERT_PASSPHRASE: a + +# logs +# default to ./logs if path is not set +# LOG_PATH: /Users/hbot/hummingbot_files/hummingbot_logs + +# GMT offset for logging (alpine docker image default to UTC timezone) +# -0800, -0500, +0200, +0800 +GMT_OFFSET: "+0800" + +# EthGasStation +# API key for defipulse.com gas station API +# Gas level you want to use for Ethereum transactions (fast, fastest, safeLow, average) +ENABLE_ETH_GAS_STATION: true +ETH_GAS_STATION_API_KEY: {apikey} +ETH_GAS_STATION_GAS_LEVEL: fast +ETH_GAS_STATION_REFRESH_TIME: 60 +MANUAL_GAS_PRICE: 100 + +# Balancer Config +BALANCER_MAX_SWAPS: 4 + + +# Perpetual Finance Provider URL +# default: https://dai.poa.network , https://rpc.xdaichain.com, etc +XDAI_PROVIDER: https://xdai.poanetwork.dev diff --git a/package.json b/package.json index 817ee0d..bec10eb 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,9 @@ "cross-fetch": "^3.0.6", "debug": "^4.2.0", "dotenv": "^8.2.0", + "yenv": "^3.0.0", + "yaml": "^1.10.2", + "yawn-yaml": "^1.5.0", "ethers": "^5.0.14", "express": "^4.17.1", "express-ipfilter": "^1.1.2", @@ -49,7 +52,7 @@ "nodemon": "^2.0.4" }, "engines": { - "node": "10.x" + "node": "12.x" }, "type": "module" } diff --git a/src/app.js b/src/app.js index 647b14f..d6574d6 100644 --- a/src/app.js +++ b/src/app.js @@ -16,13 +16,6 @@ import terraRoutes from './routes/terra.route' import uniswapRoutes from './routes/uniswap.route' import perpFiRoutes from './routes/perpetual_finance.route' -// terminate if environment not found -const result = dotenv.config(); -if (result.error) { - logger.error(result.error); - process.exit(1); -} - // create app const app = express(); diff --git a/src/index.js b/src/index.js index 957acc3..90bf3f6 100644 --- a/src/index.js +++ b/src/index.js @@ -2,15 +2,15 @@ // absolute imports import https from 'https' -import dotenv from 'dotenv' import fs from 'fs' +import yenv from 'yenv' // relative imports import app from './app' import { logger } from './services/logger' // terminate if environment not found -const result = dotenv.config(); +const result2 = yenv() if (result.error) { logger.info(result.error); process.exit(1); diff --git a/src/routes/perpetual_finance.route.js b/src/routes/perpetual_finance.route.js index f16b30e..ae96622 100644 --- a/src/routes/perpetual_finance.route.js +++ b/src/routes/perpetual_finance.route.js @@ -5,7 +5,7 @@ import { getParamData, latency, statusMessages } from '../services/utils'; import { logger } from '../services/logger'; import PerpetualFinance from '../services/perpetual_finance'; -require('dotenv').config() +// require('dotenv').config() const router = express.Router() const perpFi = new PerpetualFinance(process.env.ETHEREUM_CHAIN) diff --git a/src/routes/uniswap.route.js b/src/routes/uniswap.route.js index 812e0ef..2ef7b64 100644 --- a/src/routes/uniswap.route.js +++ b/src/routes/uniswap.route.js @@ -7,7 +7,7 @@ import Ethereum from '../services/eth'; import Uniswap from '../services/uniswap'; import Fees from '../services/fees'; -require('dotenv').config() +// require('dotenv').config() const debug = require('debug')('router') const router = express.Router() diff --git a/src/services/balancer.js b/src/services/balancer.js index dc4bb43..375fc7b 100644 --- a/src/services/balancer.js +++ b/src/services/balancer.js @@ -1,6 +1,6 @@ import { logger } from '../services/logger'; const debug = require('debug')('router') -require('dotenv').config() // DO NOT REMOVE. needed to configure REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor +// require('dotenv').config() // DO NOT REMOVE. needed to configure REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor const sor = require('@balancer-labs/sor') const BigNumber = require('bignumber.js') const ethers = require('ethers') diff --git a/src/services/eth.js b/src/services/eth.js index 61a51cd..3a9d20e 100644 --- a/src/services/eth.js +++ b/src/services/eth.js @@ -7,6 +7,7 @@ const fs = require('fs'); const ethers = require('ethers') const abi = require('../static/abi') + // constants const APPROVAL_GAS_LIMIT = process.env.ETH_APPROVAL_GAS_LIMIT || 50000; diff --git a/src/services/fees.js b/src/services/fees.js index 0535897..f987346 100644 --- a/src/services/fees.js +++ b/src/services/fees.js @@ -2,7 +2,7 @@ import { logger } from './logger'; import axios from 'axios' import BigNumber from 'bignumber.js' -require('dotenv').config() +//require('dotenv').config() const debug = require('debug')('router') // constants @@ -28,10 +28,10 @@ export default class Fees { const response = await axios.get(ethGasStationURL) // divite by 10 to convert it to Gwei) this.ethGasPrice = response.data[gasLevel] / 10 - console.log(`get ETHGasStation gas price (${gasLevel}): ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) + console.log(`get ETHGasStation gas price (${gasLevel}): ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) } else { this.ethGasPrice = ethManualGasPrice - console.log(`get manual fixed gas price: ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) + console.log(`get manual fixed gas price: ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) } } catch (err) { console.log(err); @@ -49,5 +49,5 @@ export default class Fees { async getGasCost (gasPrice, gasLimit, inGwei = false) { const cost = gasPrice * gasLimit return inGwei ? cost : cost / denom - } + } } diff --git a/src/services/logger.js b/src/services/logger.js index 90bf160..eca9d94 100644 --- a/src/services/logger.js +++ b/src/services/logger.js @@ -1,5 +1,5 @@ import { getLocalDate } from './utils' -require('dotenv').config() +// require('dotenv').config() const appRoot = require('app-root-path') const winston = require('winston') require('winston-daily-rotate-file'); diff --git a/src/services/terra.js b/src/services/terra.js index 38dac2e..ef17ba9 100644 --- a/src/services/terra.js +++ b/src/services/terra.js @@ -4,7 +4,7 @@ import BigNumber from 'bignumber.js' import { getHummingbotMemo } from './utils'; const debug = require('debug')('router') -require('dotenv').config() +// require('dotenv').config() // constants const TERRA_TOKENS = { diff --git a/yarn.lock b/yarn.lock index a3a5e0c..3f41ed6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1355,6 +1355,13 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + ansi-styles@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" @@ -1391,6 +1398,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + array-filter@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" @@ -1709,6 +1721,15 @@ cli-boxes@^2.2.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" @@ -1716,6 +1737,11 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" +coercer@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/coercer/-/coercer-1.1.2.tgz#eaea4459511f73f9f36ade04a98107ce75824b70" + integrity sha1-6upEWVEfc/nzat4EqYEHznWCS3A= + color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -2129,6 +2155,11 @@ escalade@^3.1.0: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e" integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig== +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + escape-goat@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" @@ -2568,6 +2599,11 @@ gensync@^1.0.0-beta.1: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -3038,6 +3074,21 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.4.2: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsbi@^3.1.1: version "3.1.4" resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-3.1.4.tgz#9654dd02207a66a4911b4e4bb74265bc2cbc9dd0" @@ -3082,6 +3133,11 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +keyblade@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/keyblade/-/keyblade-0.3.2.tgz#1e657f47746596807d6b591c53476bea9a1ac2d4" + integrity sha1-HmV/R3RlloB9a1kcU0dr6poawtQ= + keyv@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" @@ -3870,6 +3926,11 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -4117,6 +4178,15 @@ string-width@^4.0.0, string-width@^4.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + string.prototype.trimend@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" @@ -4525,6 +4595,15 @@ word-wrap@^1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -4556,3 +4635,56 @@ xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yaml-js@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/yaml-js/-/yaml-js-0.1.5.tgz#a01369010b3558d8aaed2394615dfd0780fd8fac" + integrity sha1-oBNpAQs1WNiq7SOUYV39B4D9j6w= + +yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^20.2.2: + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yawn-yaml@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/yawn-yaml/-/yawn-yaml-1.5.0.tgz#95fba7544d5375fce3dc84514f12218ed0d2ebcb" + integrity sha512-sH2zX9K1QiWhWh9U19pye660qlzrEAd5c4ebw/6lqz17LZw7xYi7nqXlBoVLVtc2FZFXDKiJIsvVcKGYbLVyFQ== + dependencies: + js-yaml "^3.4.2" + lodash "^4.17.11" + yaml-js "^0.1.3" + +yenv@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/yenv/-/yenv-3.0.0.tgz#8fe7eadbccda6f4e4271bf12ba3169bbe207f16d" + integrity sha512-ghUzu49pchzamfLuJrplGlZc+N3dyPmFyv2B2W+ZzTvTuuwU3WJaR5P0zPNbixIuTr4Mo4iSPQ4R8P2eAhcSww== + dependencies: + coercer "^1.1.2" + deep-extend "^0.6.0" + js-yaml "^4.0.0" + keyblade "^0.3.2" + yargs "^16.2.0" From 24bd9a19250c0e2fb429ce8964c08a2919c8f292 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 31 May 2021 21:01:10 +0100 Subject: [PATCH 15/31] update packages --- package.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index bec10eb..29d94b7 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,10 @@ "license": "Apache 2", "repository": "https://github.com/coinalpha/gateway-api", "scripts": { - "start": "babel-node src/index.js", - "dev": "nodemon --exec babel-node src/index.js", + "start": "pm2 start babel-node -- src/index.js", + "status": "pm2 monit", + "stop": "pm2 stop all", + "logs": "pm2 logs", "debug": "DEBUG=*router nodemon --exec babel-node src/index.js", "test": "echo \"Error: no test specified\" && exit 1" }, @@ -49,7 +51,8 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", - "nodemon": "^2.0.4" + "nodemon": "^2.0.4", + "pm2": "^4.5.6" }, "engines": { "node": "12.x" From b620077ea5cc24ff3968431765c9252696d9b4c7 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 31 May 2021 21:09:11 +0100 Subject: [PATCH 16/31] add config manager class --- .babelrc | 5 - .dockerignore | 12 - .env.example | 83 - .eslintrc.js | 14 - .gitignore | 30 - CODE_OF_CONDUCT.md | 76 - CONTRIBUTING.md | 138 - Dockerfile | 34 - LICENSE | 201 - README.md | 48 - certs/readme.md | 1 - docker-compose.yml | 11 - env.yaml | 87 - package-lock.json | 5874 ----------------- package.json | 61 - setup.md | 133 - src/app.js | 61 - src/index.js | 91 - src/routes/balancer.route.js | 360 - src/routes/celo.route.js | 252 - src/routes/eth.route.js | 428 -- src/routes/index.route.js | 16 - src/routes/perpetual_finance.route.js | 519 -- src/routes/terra.route.js | 228 - src/routes/uniswap.route.js | 367 - src/services/access.js | 25 - src/services/balancer.js | 206 - src/services/eth.js | 167 - src/services/fees.js | 53 - src/services/logger.js | 44 - src/services/perpetual_finance.js | 298 - src/services/terra.js | 316 - src/services/uniswap.js | 217 - src/services/utils.js | 110 - src/static/ExchangeProxy.json | 624 -- src/static/abi.js | 234 - src/static/erc20_tokens_kovan.json | 55 - src/static/uniswap_route_tokens.json | 15 - src/static/uniswap_v2_router_abi.json | 1924 ------ test/command.md | 3 - test/conf/ca.cnf | 25 - test/conf/client.cnf | 13 - test/conf/server.cnf | 13 - test/index.js | 1 - ...eway-Ethereum-Base.postman_collection.json | 1264 ---- .../Gateway-Terra.postman_collection.json | 328 - test/postman/PERPFI.postman_collection.json | 454 -- test/postman/terra.postman_environment.json | 29 - .../v2/Gateway.postman_collection.json | 1001 --- .../v2/Gateway.postman_environment.json | 34 - test/ssl-scripts.sh | 54 - yarn-error.log | 4329 ------------ yarn.lock | 4690 ------------- 53 files changed, 25656 deletions(-) delete mode 100644 .babelrc delete mode 100644 .dockerignore delete mode 100644 .env.example delete mode 100644 .eslintrc.js delete mode 100644 .gitignore delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.md delete mode 100644 Dockerfile delete mode 100644 LICENSE delete mode 100644 README.md delete mode 100644 certs/readme.md delete mode 100644 docker-compose.yml delete mode 100644 env.yaml delete mode 100644 package-lock.json delete mode 100644 package.json delete mode 100644 setup.md delete mode 100644 src/app.js delete mode 100644 src/index.js delete mode 100644 src/routes/balancer.route.js delete mode 100644 src/routes/celo.route.js delete mode 100644 src/routes/eth.route.js delete mode 100644 src/routes/index.route.js delete mode 100644 src/routes/perpetual_finance.route.js delete mode 100644 src/routes/terra.route.js delete mode 100644 src/routes/uniswap.route.js delete mode 100644 src/services/access.js delete mode 100644 src/services/balancer.js delete mode 100644 src/services/eth.js delete mode 100644 src/services/fees.js delete mode 100644 src/services/logger.js delete mode 100644 src/services/perpetual_finance.js delete mode 100644 src/services/terra.js delete mode 100644 src/services/uniswap.js delete mode 100644 src/services/utils.js delete mode 100644 src/static/ExchangeProxy.json delete mode 100644 src/static/abi.js delete mode 100644 src/static/erc20_tokens_kovan.json delete mode 100644 src/static/uniswap_route_tokens.json delete mode 100644 src/static/uniswap_v2_router_abi.json delete mode 100644 test/command.md delete mode 100644 test/conf/ca.cnf delete mode 100644 test/conf/client.cnf delete mode 100644 test/conf/server.cnf delete mode 100644 test/index.js delete mode 100644 test/postman/Gateway-Ethereum-Base.postman_collection.json delete mode 100644 test/postman/Gateway-Terra.postman_collection.json delete mode 100644 test/postman/PERPFI.postman_collection.json delete mode 100644 test/postman/terra.postman_environment.json delete mode 100644 test/postman/v2/Gateway.postman_collection.json delete mode 100644 test/postman/v2/Gateway.postman_environment.json delete mode 100755 test/ssl-scripts.sh delete mode 100644 yarn-error.log delete mode 100644 yarn.lock diff --git a/.babelrc b/.babelrc deleted file mode 100644 index cedf24f..0000000 --- a/.babelrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "presets": [ - "@babel/preset-env" - ] -} \ No newline at end of file diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index cd75aae..0000000 --- a/.dockerignore +++ /dev/null @@ -1,12 +0,0 @@ -.DS_Store -node_modules -npm-debug.log -.git -# Environment files -*.env -*.env.* -# except the example .env.example -!.env.example - -# Gateway API files -*.pem diff --git a/.env.example b/.env.example deleted file mode 100644 index 8b3e860..0000000 --- a/.env.example +++ /dev/null @@ -1,83 +0,0 @@ -APPNAME=Hummingbot Gateway API -NODE_ENV=dev -PORT=5000 - -# use only if ip whitelist is required for local or docker instance -# note that docker instance does not use 127.0.0.1 address -# ipv6 format for locahost ["::ffff:127.0.0.1", "::ffff:1", "fe80::1", "::1"] -IP_WHITELIST= - -HUMMINGBOT_INSTANCE_ID={client_id} - -# Celo - -# Terra -# - mainnet: https://lcd.terra.dev -# - mainnet chain: columbus-4 -# - testnet: https://tequila-lcd.terra.dev -# - testnet chain: tequila-0004 -TERRA_LCD_URL={testnet_lcd_url} -TERRA_CHAIN={testnet_chain_id} - -# Ethereum -# - chain: mainnet, kovan, etc -# - rpc url: infura or other rpc url -# - token list: erc20 token list source (ref: https://tokenlists.org/) -ETHEREUM_CHAIN={chain} -ETHEREUM_RPC_URL=https://{chain}.infura.io/v3/{api_key} -ETHEREUM_TOKEN_LIST_URL=https://wispy-bird-88a7.uniswap.workers.dev/?url=http://tokens.1inch.eth.link - -# Balancer -# subgraph_chain -# Reference: https://docs.balancer.finance/sor/development#subgraph -# - mainnet: balancer -# - kovan: balancer-kovan -# Note: REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor -REACT_APP_SUBGRAPH_URL=https://api.thegraph.com/subgraphs/name/balancer-labs/{subgraph_chain} - -# exchange_proxy: -# Reference: https://docs.balancer.finance/smart-contracts/addresses -# - mainnet: 0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21 -# - kovan: 0x4e67bf5bD28Dd4b570FBAFe11D0633eCbA2754Ec -EXCHANGE_PROXY={exchange_proxy} - -# Uniswap -# Reference: https://uniswap.org/docs/v2/smart-contracts/router02/ -# UniswapV2Router02 is deployed at 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets. -# It was built from commit 6961711. -UNISWAP_ROUTER=0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D -# allowed slippage for swap transactions -UNISWAP_ALLOWED_SLIPPAGE=1.5 -# restrict updating pairs that have no reserves or failed for 5 minutes -UNISWAP_NO_RESERVE_CHECK_INTERVAL=300000 -# cache info about pair for 1 second -UNISWAP_PAIRS_CACHE_TIME=1000 - -# cert -CERT_PATH={full_path_to_certs_folder} -CERT_PASSPHRASE={passphrase} - -# logs -# default to ./logs if path is not set -LOG_PATH=/Users/hbot/hummingbot_files/hummingbot_logs - -# GMT offset for logging (alpine docker image default to UTC timezone) -# -0800, -0500, +0200, +0800 -GMT_OFFSET=+0800 - -# EthGasStation -# API key for defipulse.com gas station API -# Gas level you want to use for Ethereum transactions (fast, fastest, safeLow, average) -ENABLE_ETH_GAS_STATION=true -ETH_GAS_STATION_API_KEY={apikey} -ETH_GAS_STATION_GAS_LEVEL=fast -ETH_GAS_STATION_REFRESH_TIME=60 -MANUAL_GAS_PRICE=100 - -# Balancer Config -BALANCER_MAX_SWAPS=4 - - -# Perpetual Finance Provider URL -# default: https://dai.poa.network , https://rpc.xdaichain.com, etc -XDAI_PROVIDER={providerUrl} diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 8156b59..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - extends: 'standard', - rules: { - // disable semicolon check - semi: 'off', - - // override default options for rules from base configurations - 'comma-dangle': 'off', - - // disable rules from base configurations - 'no-console': 'off', - 'no-multi-spaces': 'off', - } -}; diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 2f9e925..0000000 --- a/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -# OS files -**/.DS_Store -Desktop.ini - -# IDEA files -.idea - -# Environment files -*.env -*.env.* -# except the example .env.example -!.env.example - -# node installs -node_modules/ - -# debug logs -npm-debug.log - -# distribution files -dist/ - -# misc -logs/ - -# cert -*.pem -*.srl -*.key -*.crt \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 1d15957..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,76 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at dev@coinalpha.com. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 5dd883c..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,138 +0,0 @@ -# Contributing - -## General workflow - -1. Fork the repo -1. Create a new branch from the [`development`](https://github.com/CoinAlpha/gateway-api/tree/development) branch (see: [branch naming guidelines](#branch-naming-guidelines)) -1. Make commits to your branch -1. When you've finished with your fix or feature: - - Rebase upstream changes into your branch - - Submit a pull request to the [`development`](https://github.com/CoinAlpha/gateway-api/tree/development) branch - - Include a description of your changes -1. Your pull request will be reviewed by [CoinAlpha's development team](mailto:dev@coinalpha.com). -1. Fix any issues raised by your code reviewer, and push your fixes as a single new commit. -1. Once the pull request has been reviewed and accepted, it will be merged by a member of the CoinAlpha development team. - -## Detailed workflow - -### Fork the repo - -Use github’s interface to make a fork of the repo, then add that repo as an upstream remote: - -``` -git remote add upstream https://github.com/CoinAlpha/gateway-api.git -``` - -### Branch naming guidelines - -Your branch should follow this naming convention: - - feat/... - - bug/... - - refactor/... - - test/... - - doc/... - -These commands will help you do this: - -``` bash -# Creates your branch and brings you there -git checkout -b `your-branch-name` -``` - -### Make commits to your feature branch - -Prefix each commit like so - - (feat) Add a new feature - - (fix) Fix inconsistent tests [Fixes #0] - - (refactor) ... - - (cleanup) ... - - (test) ... - - (doc) ... - -Make changes and commits on your branch, and make sure that you -only make changes that are relevant to this branch. If you find -yourself making unrelated changes, make a new branch for those -changes. - -#### Commit message guidelines - -- Commit messages should be written in the present tense; e.g. "Fix continuous integration script". -- The first line of your commit message should be a brief summary of what the commit changes. Aim for about 70 characters max. Remember: This is a summary, not a detailed description of everything that changed. -- If you want to explain the commit in more depth, following the first line should be a blank line and then a more detailed description of the commit. This can be as detailed as you want, so dig into details here and keep the first line short. - -### Rebase upstream changes into your branch - -Once you are done making changes, you can begin the process of getting -your code merged into the main repo. Step 1 is to rebase upstream -changes to the `development` branch into yours by running this command -from your branch: - -```bash -git pull --rebase upstream development -``` - -This will start the rebase process. You must commit all of your changes -before doing this. If there are no conflicts, this should just roll all -of your changes back on top of the changes from upstream, leading to a -nice, clean, linear commit history. - -If there are conflicting changes, git will start yelling at you part way -through the rebasing process. Git will pause rebasing to allow you to sort -out the conflicts. You do this the same way you solve merge conflicts, -by checking all of the files git says have been changed in both histories -and picking the versions you want. Be aware that these changes will show -up in your pull request, so try and incorporate upstream changes as much -as possible. - -You pick a file by `git add`ing it - you do not make commits during a -rebase. - -Once you are done fixing conflicts for a specific commit, run: - -```bash -git rebase --continue -``` - -This will continue the rebasing process. Once you are done fixing all -conflicts you should run the existing tests to make sure you didn’t break -anything, then run your new tests (there are new tests, right?) and -make sure they work also. - -If rebasing broke anything, fix it, then repeat the above process until -you get here again and nothing is broken and all the tests pass. - -### Make a pull request - -Make a clear pull request from your fork and branch to the upstream `development` -branch, detailing exactly what changes you made and what feature this -should add. The clearer your pull request is the faster you can get -your changes incorporated into this repo. - -If the development team requests changes, you should make more commits to your -branch to address these, then follow this process again from rebasing onwards. - -Once you get back here, make a comment requesting further review and -someone will look at your code again. If it addresses the requests, it will -get merged, else, just repeat again. - -Thanks for contributing! - -### Testing - -Tests are very, very important. Submit tests if your pull request contains new, testable behavior. - -## Checklist: - -This is just to help you organize your process - -- [ ] Did I create my branch from `development` (don't create new branches from existing feature branches)? -- [ ] Did I follow the correct naming convention for my branch? -- [ ] Is my branch focused on a single main change? - - [ ] Do all of my changes directly relate to this change? -- [ ] Did I rebase the upstream `development` branch after I finished all my - work? -- [ ] Did I write a clear pull request message detailing what changes I made? -- [ ] Did I get a code review? - - [ ] Did I make any requested changes from that code review? - -If you follow all of these guidelines and make good changes, you should have no problem getting your changes merged in. diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 47d8c7c..0000000 --- a/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -FROM node:10.22.0-alpine - -# Add timezone database -RUN apk add --no-cache tzdata - -# Set labels -LABEL application="gateway-api" -LABEL branch=${BRANCH} -LABEL commit=${COMMIT} -LABEL date=${BUILD_DATE} - -# Set ENV variables -ENV COMMIT_BRANCH=${BRANCH} -ENV COMMIT_SHA=${COMMIT} -ENV BUILD_DATE=${DATE} - -# app directory -WORKDIR /usr/src/app - -# install dependancies -COPY package*.json ./ -COPY yarn.lock ./ - -RUN yarn install - -# copy pwd file to container -COPY . . - -# create empty env file -RUN touch .env - -EXPOSE 5000 - -CMD ["yarn", "run", "start"] \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index ceee1ca..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2020 CoinAlpha, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md deleted file mode 100644 index 01aa595..0000000 --- a/README.md +++ /dev/null @@ -1,48 +0,0 @@ -![Hummingbot](https://i.ibb.co/X5zNkKw/blacklogo-with-text.png) - ----- - -Hummingbot Gateway is an open-source project that integrates cryptocurrency trading on both **centralized exchanges** and **decentralized protocols**. It allows users to run a client that executes customized, automated trading strategies for cryptocurrencies. - -We created hummingbot to promote **decentralized market-making**: enabling members of the community to contribute to the liquidity and trading efficiency in cryptocurrency markets. - - - -## Getting Started - -### Learn more about Hummingbot - -- [Website](https://hummingbot.io) -- [Documentation](https://docs.hummingbot.io) -- [FAQs](https://docs.hummingbot.io/faq/) - -### Install Hummingbot - -- [Quickstart guide](https://docs.hummingbot.io/quickstart/) -- [All installation options](https://docs.hummingbot.io/installation/overview/) - -### Get support -- Chat with our support team on [Discord](https://discord.hummingbot.io) -- Email us at support@hummingbot.io - -### Chat with other traders -- Join our community on [Discord](https://discord.coinalpha.com) or [Reddit](https://www.reddit.com/r/Hummingbot/) -- Follow Hummingbot on [Twitter](https://twitter.com/hummingbot_io) - -## Contributions - -We welcome contributions from the community: -- **Code and documentation contributions** via [pull requests](https://github.com/CoinAlpha/gateway-api/pulls) -- **Bug reports and feature requests** through [Github issues](https://github.com/CoinAlpha/gateway-api/issues) -- When contributing, please review the [contributing guidelines](CONTRIBUTING.md) - -## About us - -Hummingbot Gateway was created and is maintained by CoinAlpha, Inc. We are [a global team of engineers and traders](https://hummingbot.io/about/). - -- **General**: contact us at [dev@hummingbot.io](mailto:dev@hummingbot.io) or join our [Discord server](https://discord.hummingbot.io). -- **Business inquiries**: contact us at [partnerships@hummingbot.io](mailto:partnerships@hummingbot.io). - -## Legal - -- **License**: Hummingbot is licensed under [Apache 2.0](./LICENSE). diff --git a/certs/readme.md b/certs/readme.md deleted file mode 100644 index 8d9f12b..0000000 --- a/certs/readme.md +++ /dev/null @@ -1 +0,0 @@ -certs dir for local testing only \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 4f8c4ae..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,11 +0,0 @@ -version: '3' - -services: - gateway: - build: . - volumes: - - .:/usr/src/app - ports: - - 5001:5000 - - \ No newline at end of file diff --git a/env.yaml b/env.yaml deleted file mode 100644 index fbb28a9..0000000 --- a/env.yaml +++ /dev/null @@ -1,87 +0,0 @@ -APPNAME: Hummingbot Gateway API -NODE_ENV: dev -PORT: 5000 - -# use only if ip whitelist is required for local or docker instance -# note that docker instance does not use 127.0.0.1 address -# ipv6 format for locahost ["::ffff:127.0.0.1", "::ffff:1", "fe80::1", "::1"] -IP_WHITELIST: - -HUMMINGBOT_INSTANCE_ID: {client_id} - -# Celo - -# Terra -# - mainnet: https://lcd.terra.dev -# - mainnet chain: columbus-4 -# - testnet: https://tequila-lcd.terra.dev -# - testnet chain: tequila-0004 -TERRA_LCD_URL: {testnet_lcd_url} -TERRA_CHAIN: {testnet_chain_id} - -# Ethereum -# - chain: mainnet, kovan, etc -# - rpc url: infura or other rpc url -# - token list: erc20 token list source (ref: https://tokenlists.org/) -ETHEREUM_CHAIN: kovan -# ETHEREUM_RPC_URL: https://mainnet.infura.io/v3/117bfd0769f54bd2b91f50d2b1c19f9a -ETHEREUM_RPC_URL: https://kovan.infura.io/v3/117bfd0769f54bd2b91f50d2b1c19f9a -ETHEREUM_TOKEN_LIST_URL: https://wispy-bird-88a7.uniswap.workers.dev/?url=http://tokens.1inch.eth.link - -# Balancer -# subgraph_chain -# Reference: https://docs.balancer.finance/sor/development#subgraph -# - mainnet: balancer -# - kovan: balancer-kovan -# Note: REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor -REACT_APP_SUBGRAPH_URL: https://api.thegraph.com/subgraphs/name/balancer-labs/{subgraph_chain} - -# exchange_proxy: -# Reference: https://docs.balancer.finance/smart-contracts/addresses -# - mainnet: 0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21 -# - kovan: 0x4e67bf5bD28Dd4b570FBAFe11D0633eCbA2754Ec -EXCHANGE_PROXY: "0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21" - -# Uniswap -# Reference: https://uniswap.org/docs/v2/smart-contracts/router02/ -# UniswapV2Router02 is deployed at 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets. -# It was built from commit 6961711. -UNISWAP_ROUTER: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D" -UNISWAP_V3_CORE: "0x1F98431c8aD98523631AE4a59f267346ea31F984" -UNISWAP_V3_ROUTER: "0xE592427A0AEce92De3Edee1F18E0157C05861564" -UNISWAP_V3_NFT_MANAGER: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88" -# allowed slippage for swap transactions -UNISWAP_ALLOWED_SLIPPAGE: 1.5 -# restrict updating pairs that have no reserves or failed for 5 minutes -uNISWAP_NO_RESERVE_CHECK_INTERVALL: 300011 -# cache info about pair for 1 second -UNISWAP_PAIRS_CACHE_TIME: 1000 - -# cert -CERT_PATH: /home/vic/hummingbot/certs/ -CERT_PASSPHRASE: a - -# logs -# default to ./logs if path is not set -# LOG_PATH: /Users/hbot/hummingbot_files/hummingbot_logs - -# GMT offset for logging (alpine docker image default to UTC timezone) -# -0800, -0500, +0200, +0800 -GMT_OFFSET: "+0800" - -# EthGasStation -# API key for defipulse.com gas station API -# Gas level you want to use for Ethereum transactions (fast, fastest, safeLow, average) -ENABLE_ETH_GAS_STATION: true -ETH_GAS_STATION_API_KEY: {apikey} -ETH_GAS_STATION_GAS_LEVEL: fast -ETH_GAS_STATION_REFRESH_TIME: 60 -MANUAL_GAS_PRICE: 100 - -# Balancer Config -BALANCER_MAX_SWAPS: 4 - - -# Perpetual Finance Provider URL -# default: https://dai.poa.network , https://rpc.xdaichain.com, etc -XDAI_PROVIDER: https://xdai.poanetwork.dev diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 199add5..0000000 --- a/package-lock.json +++ /dev/null @@ -1,5874 +0,0 @@ -{ - "name": "gateway-api", - "version": "0.3.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "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.12.13" - } - }, - "@babel/compat-data": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", - "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==", - "dev": true - }, - "@babel/core": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.15.tgz", - "integrity": "sha512-6GXmNYeNjS2Uz+uls5jalOemgIhnTMeaXo+yBUA72kC2uX/8VW6XyhVIo2L8/q0goKQA3EVKx0KOQpVKSeWadQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.10", - "@babel/parser": "^7.13.15", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.14", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", - "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", - "dev": true, - "requires": { - "@babel/types": "^7.13.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", - "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", - "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", - "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.12", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.13.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", - "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-member-expression-to-functions": "^7.13.0", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", - "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "regexpu-core": "^4.7.1" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz", - "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", - "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", - "dev": true, - "requires": { - "@babel/types": "^7.13.0" - } - }, - "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz", - "integrity": "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==", - "dev": true, - "requires": { - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", - "dev": true, - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "dev": true, - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", - "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-wrap-function": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", - "dev": true, - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", - "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", - "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "@babel/helpers": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", - "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", - "dev": true, - "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/node": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.13.13.tgz", - "integrity": "sha512-gElSPunpriXoBGQxDkd5h9L13SVTyzFLTPv9jN1aXJNLR10iNs+MsfhYL/WGJGCJQFddHAdThY7CkmGVz2KPag==", - "dev": true, - "requires": { - "@babel/register": "^7.13.8", - "commander": "^4.0.1", - "core-js": "^3.2.1", - "node-environment-flags": "^1.0.5", - "regenerator-runtime": "^0.13.4", - "v8flags": "^3.1.1" - } - }, - "@babel/parser": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz", - "integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==", - "dev": true - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", - "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.13.12" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz", - "integrity": "sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-remap-async-to-generator": "^7.13.0", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", - "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", - "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", - "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", - "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", - "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", - "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", - "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", - "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-compilation-targets": "^7.13.8", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.13.0" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", - "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", - "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", - "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", - "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", - "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", - "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", - "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-remap-async-to-generator": "^7.13.0" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", - "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz", - "integrity": "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", - "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", - "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz", - "integrity": "sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", - "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", - "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", - "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", - "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", - "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", - "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", - "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", - "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", - "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-simple-access": "^7.12.13", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", - "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.13.0", - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-identifier": "^7.12.11", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", - "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", - "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", - "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", - "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13", - "@babel/helper-replace-supers": "^7.12.13" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", - "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", - "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz", - "integrity": "sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", - "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", - "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", - "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", - "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", - "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", - "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", - "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", - "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/preset-env": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.15.tgz", - "integrity": "sha512-D4JAPMXcxk69PKe81jRJ21/fP/uYdcTZ3hJDF5QX2HSI9bBxxYw/dumdR6dGumhjxlprHPE4XWoPaqzZUVy2MA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-option": "^7.12.17", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-async-generator-functions": "^7.13.15", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-dynamic-import": "^7.13.8", - "@babel/plugin-proposal-export-namespace-from": "^7.12.13", - "@babel/plugin-proposal-json-strings": "^7.13.8", - "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-numeric-separator": "^7.12.13", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-private-methods": "^7.13.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.12.13", - "@babel/plugin-transform-arrow-functions": "^7.13.0", - "@babel/plugin-transform-async-to-generator": "^7.13.0", - "@babel/plugin-transform-block-scoped-functions": "^7.12.13", - "@babel/plugin-transform-block-scoping": "^7.12.13", - "@babel/plugin-transform-classes": "^7.13.0", - "@babel/plugin-transform-computed-properties": "^7.13.0", - "@babel/plugin-transform-destructuring": "^7.13.0", - "@babel/plugin-transform-dotall-regex": "^7.12.13", - "@babel/plugin-transform-duplicate-keys": "^7.12.13", - "@babel/plugin-transform-exponentiation-operator": "^7.12.13", - "@babel/plugin-transform-for-of": "^7.13.0", - "@babel/plugin-transform-function-name": "^7.12.13", - "@babel/plugin-transform-literals": "^7.12.13", - "@babel/plugin-transform-member-expression-literals": "^7.12.13", - "@babel/plugin-transform-modules-amd": "^7.13.0", - "@babel/plugin-transform-modules-commonjs": "^7.13.8", - "@babel/plugin-transform-modules-systemjs": "^7.13.8", - "@babel/plugin-transform-modules-umd": "^7.13.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", - "@babel/plugin-transform-new-target": "^7.12.13", - "@babel/plugin-transform-object-super": "^7.12.13", - "@babel/plugin-transform-parameters": "^7.13.0", - "@babel/plugin-transform-property-literals": "^7.12.13", - "@babel/plugin-transform-regenerator": "^7.13.15", - "@babel/plugin-transform-reserved-words": "^7.12.13", - "@babel/plugin-transform-shorthand-properties": "^7.12.13", - "@babel/plugin-transform-spread": "^7.13.0", - "@babel/plugin-transform-sticky-regex": "^7.12.13", - "@babel/plugin-transform-template-literals": "^7.13.0", - "@babel/plugin-transform-typeof-symbol": "^7.12.13", - "@babel/plugin-transform-unicode-escapes": "^7.12.13", - "@babel/plugin-transform-unicode-regex": "^7.12.13", - "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.13.14", - "babel-plugin-polyfill-corejs2": "^0.2.0", - "babel-plugin-polyfill-corejs3": "^0.2.0", - "babel-plugin-polyfill-regenerator": "^0.2.0", - "core-js-compat": "^3.9.0", - "semver": "^6.3.0" - } - }, - "@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/register": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.13.14.tgz", - "integrity": "sha512-iyw0hUwjh/fzN8qklVqZodbyWjEBOG0KdDnBOpv3zzIgK3NmuRXBmIXH39ZBdspkn8LTHvSboN+oYb4MT43+9Q==", - "dev": true, - "requires": { - "find-cache-dir": "^2.0.0", - "lodash": "^4.17.19", - "make-dir": "^2.1.0", - "pirates": "^4.0.0", - "source-map-support": "^0.5.16" - } - }, - "@babel/runtime": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", - "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz", - "integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.15", - "@babel/types": "^7.13.14", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", - "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "@balancer-labs/sor": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@balancer-labs/sor/-/sor-0.3.3.tgz", - "integrity": "sha512-hdPp55A2Hw+Koq81nhqTy15jNRCDW1k5ZT47nk2uEx7N5D9GiAx4BCNDzTiuJLErj6QHJTbEKK7Y5jei702c4g==", - "requires": { - "bignumber.js": "^9.0.0", - "isomorphic-fetch": "^2.2.1" - } - }, - "@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", - "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "@eslint/eslintrc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", - "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - } - } - }, - "@ethersproject/abi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.0.tgz", - "integrity": "sha512-N/W9Sbn1/C6Kh2kuHRjf/hX6euMK4+9zdJRBB8sDWmihVntjUAfxbusGZKzDQD8i3szAHhTz8K7XADV5iFNfJw==", - "requires": { - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/hash": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/strings": "^5.1.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz", - "integrity": "sha512-8dJUnT8VNvPwWhYIau4dwp7qe1g+KgdRm4XTWvjkI9gAT2zZa90WF5ApdZ3vl1r6NDmnn6vUVvyphClRZRteTQ==", - "requires": { - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/networks": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", - "@ethersproject/web": "^5.1.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.1.0.tgz", - "integrity": "sha512-qQDMkjGZSSJSKl6AnfTgmz9FSnzq3iEoEbHTYwjDlEAv+LNP7zd4ixCcVWlWyk+2siud856M5CRhAmPdupeN9w==", - "requires": { - "@ethersproject/abstract-provider": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0" - } - }, - "@ethersproject/address": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.1.0.tgz", - "integrity": "sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg==", - "requires": { - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/rlp": "^5.1.0" - } - }, - "@ethersproject/base64": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.1.0.tgz", - "integrity": "sha512-npD1bLvK4Bcxz+m4EMkx+F8Rd7CnqS9DYnhNu0/GlQBXhWjvfoAZzk5HJ0f1qeyp8d+A86PTuzLOGOXf4/CN8g==", - "requires": { - "@ethersproject/bytes": "^5.1.0" - } - }, - "@ethersproject/basex": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.1.0.tgz", - "integrity": "sha512-vBKr39bum7DDbOvkr1Sj19bRMEPA4FnST6Utt6xhDzI7o7L6QNkDn2yrCfP+hnvJGhZFKtLygWwqlTBZoBXYLg==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/properties": "^5.1.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.0.tgz", - "integrity": "sha512-wUvQlhTjPjFXIdLPOuTrFeQmSa6Wvls1bGXQNQWvB/SEn1NsTCE8PmumIEZxmOPjSHl1eV2uyHP5jBm5Cgj92Q==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "bn.js": "^4.4.0" - } - }, - "@ethersproject/bytes": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", - "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", - "requires": { - "@ethersproject/logger": "^5.1.0" - } - }, - "@ethersproject/constants": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", - "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", - "requires": { - "@ethersproject/bignumber": "^5.1.0" - } - }, - "@ethersproject/contracts": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.1.1.tgz", - "integrity": "sha512-6WwktLJ0DFWU8pDkgH4IGttQHhQN4SnwKFu9h+QYVe48VGWtbDu4W8/q/7QA1u/HWlWMrKxqawPiZUJj0UMvOw==", - "requires": { - "@ethersproject/abi": "^5.1.0", - "@ethersproject/abstract-provider": "^5.1.0", - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/transactions": "^5.1.0" - } - }, - "@ethersproject/hash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz", - "integrity": "sha512-fNwry20yLLPpnRRwm3fBL+2ksgO+KMadxM44WJmRIoTKzy4269+rbq9KFoe2LTqq2CXJM2CE70beGaNrpuqflQ==", - "requires": { - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/strings": "^5.1.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.1.0.tgz", - "integrity": "sha512-obIWdlujloExPHWJGmhJO/sETOOo7SEb6qemV4f8kyFoXg+cJK+Ta9SvBrj7hsUK85n3LZeZJZRjjM7oez3Clg==", - "requires": { - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/basex": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/pbkdf2": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/sha2": "^5.1.0", - "@ethersproject/signing-key": "^5.1.0", - "@ethersproject/strings": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", - "@ethersproject/wordlists": "^5.1.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.1.0.tgz", - "integrity": "sha512-00n2iBy27w8zrGZSiU762UOVuzCQZxUZxopsZC47++js6xUFuI74DHcJ5K/2pddlF1YBskvmMuboEu1geK8mnA==", - "requires": { - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/hdnode": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/pbkdf2": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/random": "^5.1.0", - "@ethersproject/strings": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "@ethersproject/keccak256": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.1.0.tgz", - "integrity": "sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "js-sha3": "0.5.7" - } - }, - "@ethersproject/logger": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", - "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" - }, - "@ethersproject/networks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.1.0.tgz", - "integrity": "sha512-A/NIrIED/G/IgU1XUukOA3WcFRxn2I4O5GxsYGA5nFlIi+UZWdGojs85I1VXkR1gX9eFnDXzjE6OtbgZHjFhIA==", - "requires": { - "@ethersproject/logger": "^5.1.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.1.0.tgz", - "integrity": "sha512-B8cUbHHTgs8OtgJIafrRcz/YPDobVd5Ru8gTnShOiM9EBuFpYHQpq3+8iQJ6pyczDu6HP/oc/njAsIBhwFZYew==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/sha2": "^5.1.0" - } - }, - "@ethersproject/properties": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.1.0.tgz", - "integrity": "sha512-519KKTwgmH42AQL3+GFV3SX6khYEfHsvI6v8HYejlkigSDuqttdgVygFTDsGlofNFchhDwuclrxQnD5B0YLNMg==", - "requires": { - "@ethersproject/logger": "^5.1.0" - } - }, - "@ethersproject/providers": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.1.tgz", - "integrity": "sha512-+xWqQh4eLnAePRR5CHSySCVke//NxGSuQEUzGTdDtt0yCbizwlKGm7CrsU0zF8JUcKDrDh36ezzTicOMd5sl9w==", - "requires": { - "@ethersproject/abstract-provider": "^5.1.0", - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/basex": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/hash": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/networks": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/random": "^5.1.0", - "@ethersproject/rlp": "^5.1.0", - "@ethersproject/sha2": "^5.1.0", - "@ethersproject/strings": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", - "@ethersproject/web": "^5.1.0", - "bech32": "1.1.4", - "ws": "7.2.3" - }, - "dependencies": { - "ws": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", - "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" - } - } - }, - "@ethersproject/random": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.1.0.tgz", - "integrity": "sha512-+uuczLQZ4+no9cP6TCoCktXx0u2YbNaRT7lRkSt12d8263e702f0u+4JnnRO8Qmv5nylWJebnqCHzyxP+6mLqw==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0" - } - }, - "@ethersproject/rlp": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.1.0.tgz", - "integrity": "sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0" - } - }, - "@ethersproject/sha2": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.1.0.tgz", - "integrity": "sha512-+fNSeZRstOpdRJpdGUkRONFCaiAqWkc91zXgg76Nlp5ndBQE25Kk5yK8gCPG1aGnCrbariiPr5j9DmrYH78JCA==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "hash.js": "1.1.3" - }, - "dependencies": { - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - } - } - }, - "@ethersproject/signing-key": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.1.0.tgz", - "integrity": "sha512-tE5LFlbmdObG8bY04NpuwPWSRPgEswfxweAI1sH7TbP0ml1elNfqcq7ii/3AvIN05i5U0Pkm3Tf8bramt8MmLw==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "bn.js": "^4.4.0", - "elliptic": "6.5.4" - } - }, - "@ethersproject/solidity": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.1.0.tgz", - "integrity": "sha512-kPodsGyo9zg1g9XSXp1lGhFaezBAUUsAUB1Vf6OkppE5Wksg4Et+x3kG4m7J/uShDMP2upkJtHNsIBK2XkVpKQ==", - "requires": { - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/sha2": "^5.1.0", - "@ethersproject/strings": "^5.1.0" - } - }, - "@ethersproject/strings": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.1.0.tgz", - "integrity": "sha512-perBZy0RrmmL0ejiFGUOlBVjMsUceqLut3OBP3zP96LhiJWWbS8u1NqQVgN4/Gyrbziuda66DxiQocXhsvx+Sw==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/logger": "^5.1.0" - } - }, - "@ethersproject/transactions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.1.1.tgz", - "integrity": "sha512-Nwgbp09ttIVN0OoUBatCXaHxR7grWPHbozJN8v7AXDLrl6nnOIBEMDh+yJTnosSQlFhcyjfTGGN+Mx6R8HdvMw==", - "requires": { - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/rlp": "^5.1.0", - "@ethersproject/signing-key": "^5.1.0" - } - }, - "@ethersproject/units": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.1.0.tgz", - "integrity": "sha512-isvJrx6qG0nKWfxsGORNjmOq/nh175fStfvRTA2xEKrGqx8JNJY83fswu4GkILowfriEM/eYpretfJnfzi7YhA==", - "requires": { - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/logger": "^5.1.0" - } - }, - "@ethersproject/wallet": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.1.0.tgz", - "integrity": "sha512-ULmUtiYQLTUS+y3DgkLzRhFEK10zMwmjOthnjiZxee3Q/MVwr3rnmuAnXIUZrPjna6hvUPnyRIdW5XuF0Ld0YQ==", - "requires": { - "@ethersproject/abstract-provider": "^5.1.0", - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/hash": "^5.1.0", - "@ethersproject/hdnode": "^5.1.0", - "@ethersproject/json-wallets": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/random": "^5.1.0", - "@ethersproject/signing-key": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", - "@ethersproject/wordlists": "^5.1.0" - } - }, - "@ethersproject/web": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.1.0.tgz", - "integrity": "sha512-LTeluWgTq04+RNqAkVhpydPcRZK/kKxD2Vy7PYGrAD27ABO9kTqTBKwiOuzTyAHKUQHfnvZbXmxBXJAGViSDcA==", - "requires": { - "@ethersproject/base64": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/strings": "^5.1.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.1.0.tgz", - "integrity": "sha512-NsUCi/TpBb+oTFvMSccUkJGtp5o/84eOyqp5q5aBeiNBSLkYyw21znRn9mAmxZgySpxgruVgKbaapnYPgvctPQ==", - "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/hash": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/strings": "^5.1.0" - } - }, - "@perp/contract": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@perp/contract/-/contract-1.1.0.tgz", - "integrity": "sha512-79O3DoGYtC6Nu9TnzC6aUTwCuEfe3+CIZr9a27Uh26MQ0jHkCq2Rc4sz35k3ChuN9zL2ZmrsAR+mO785QGZFpw==" - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@terra-money/terra.js": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-0.5.13.tgz", - "integrity": "sha512-v2B+VqVar6gryTfpHsusmDn2WIRT23xnTKsxFn6G20WIN5XCeRQa84cnAlZHuNP9w5ejuvRmoHX0Wg6g1DJo3g==", - "requires": { - "axios": "^0.20.0", - "bech32": "^1.1.4", - "bip32": "^2.0.6", - "bip39": "^3.0.2", - "bufferutil": "^4.0.1", - "crypto-js": "3.3.0", - "decimal.js": "^10.2.1", - "post-message-stream": "^3.0.0", - "secp256k1": "^4.0.2", - "tmp": "^0.2.1", - "utf-8-validate": "^5.0.2", - "ws": "^7.3.1" - }, - "dependencies": { - "axios": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", - "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", - "requires": { - "follow-redirects": "^1.10.0" - } - } - } - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" - }, - "@uniswap/sdk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@uniswap/sdk/-/sdk-3.0.3.tgz", - "integrity": "sha512-t4s8bvzaCFSiqD2qfXIm3rWhbdnXp+QjD3/mRaeVDHK7zWevs6RGEb1ohMiNgOCTZANvBayb4j8p+XFdnMBadQ==", - "requires": { - "@uniswap/v2-core": "^1.0.0", - "big.js": "^5.2.2", - "decimal.js-light": "^2.5.0", - "jsbi": "^3.1.1", - "tiny-invariant": "^1.1.0", - "tiny-warning": "^1.0.3", - "toformat": "^2.0.0" - } - }, - "@uniswap/v2-core": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@uniswap/v2-core/-/v2-core-1.0.1.tgz", - "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true - }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "dev": true, - "requires": { - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "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", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "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.0" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "app-root-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", - "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==" - }, - "argle": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/argle/-/argle-1.1.1.tgz", - "integrity": "sha1-DP47wDLDay9IukK5wX+J9wYH6ZQ=", - "requires": { - "lodash.isfunction": "^3.0.8", - "lodash.isnumber": "^3.0.3" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - } - }, - "array-uniq": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz", - "integrity": "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0=" - }, - "array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, - "available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "requires": { - "array-filter": "^1.0.0" - } - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz", - "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.0", - "semver": "^6.1.1" - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz", - "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.0", - "core-js-compat": "^3.9.1" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz", - "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip32": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", - "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", - "requires": { - "@types/node": "10.12.18", - "bs58check": "^2.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "tiny-secp256k1": "^1.1.3", - "typeforce": "^1.11.5", - "wif": "^2.0.6" - } - }, - "bip39": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.3.tgz", - "integrity": "sha512-P0dKrz4g0V0BjXfx7d9QNkJ/Txcz/k+hM9TnjqjUaXtuOfAvxXSw2rJw8DX0e3ZPwnK/IgDxoRqf0bvoVCqbMg==", - "requires": { - "@types/node": "11.11.6", - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1" - }, - "dependencies": { - "@types/node": { - "version": "11.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", - "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" - } - } - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "dev": true, - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserslist": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", - "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001208", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.712", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "bufferutil": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", - "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", - "requires": { - "node-gyp-build": "^4.2.0" - } - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001211", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001211.tgz", - "integrity": "sha512-v3GXWKofIkN3PkSidLI5d1oqeKNsam9nQkqieoMhP87nxOY0RPDC8X2+jcv8pjV4dRozPLSoMqNii9sDViOlIg==", - "dev": true - }, - "capture-console": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-console/-/capture-console-1.0.1.tgz", - "integrity": "sha1-22PDmscyOQGbrdf7sQFD7aOA/3E=", - "requires": { - "argle": "~1.1.1", - "lodash.isfunction": "~3.0.8", - "randomstring": "~1.1.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "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.1", - "color-string": "^1.5.2" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "color-string": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", - "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" - }, - "colorspace": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", - "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", - "requires": { - "color": "3.0.x", - "text-hex": "1.0.x" - } - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "complex.js": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.12.tgz", - "integrity": "sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - } - } - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "core-js": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.10.1.tgz", - "integrity": "sha512-pwCxEXnj27XG47mu7SXAwhLP3L5CrlvCB91ANUkIz40P27kUcvNfSdvyZJ9CLHiVoKSp+TTChMQMSKQEH/IQxA==", - "dev": true - }, - "core-js-compat": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.10.1.tgz", - "integrity": "sha512-ZHQTdTPkqvw2CeHiZC970NNJcnwzT6YIueDMASKt+p3WbZsLXOcoD392SkcWhkC0wBBHhlfhqGKKsNCQUozYtg==", - "dev": true, - "requires": { - "browserslist": "^4.16.3", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", - "requires": { - "node-fetch": "2.6.1" - }, - "dependencies": { - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - } - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-js": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", - "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" - }, - "decimal.js-light": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", - "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "electron-to-chromium": { - "version": "1.3.717", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz", - "integrity": "sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ==", - "dev": true - }, - "elliptic": { - "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.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - } - } - }, - "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-latex": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", - "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" - }, - "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 - }, - "eslint": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", - "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.21", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "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==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "globals": { - "version": "13.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", - "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } - } - }, - "eslint-config-standard": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", - "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "eslint-module-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", - "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } - } - }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", - "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", - "dev": true, - "requires": { - "array-includes": "^3.1.1", - "array.prototype.flat": "^1.2.3", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.0", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.1", - "read-pkg-up": "^2.0.0", - "resolve": "^1.17.0", - "tsconfig-paths": "^3.9.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - } - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", - "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", - "dev": true - }, - "eslint-plugin-standard": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", - "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", - "dev": true - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "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" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "ethers": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.2.tgz", - "integrity": "sha512-yM+2bINj7Li9jeKX+hGZ/rFTo6kXcCwZTcCBmAwS+J3bLfyGX/o21fcssuPb9kfR26suCV+98XTWIuTuGiDO5A==", - "requires": { - "@ethersproject/abi": "5.1.0", - "@ethersproject/abstract-provider": "5.1.0", - "@ethersproject/abstract-signer": "5.1.0", - "@ethersproject/address": "5.1.0", - "@ethersproject/base64": "5.1.0", - "@ethersproject/basex": "5.1.0", - "@ethersproject/bignumber": "5.1.0", - "@ethersproject/bytes": "5.1.0", - "@ethersproject/constants": "5.1.0", - "@ethersproject/contracts": "5.1.1", - "@ethersproject/hash": "5.1.0", - "@ethersproject/hdnode": "5.1.0", - "@ethersproject/json-wallets": "5.1.0", - "@ethersproject/keccak256": "5.1.0", - "@ethersproject/logger": "5.1.0", - "@ethersproject/networks": "5.1.0", - "@ethersproject/pbkdf2": "5.1.0", - "@ethersproject/properties": "5.1.0", - "@ethersproject/providers": "5.1.1", - "@ethersproject/random": "5.1.0", - "@ethersproject/rlp": "5.1.0", - "@ethersproject/sha2": "5.1.0", - "@ethersproject/signing-key": "5.1.0", - "@ethersproject/solidity": "5.1.0", - "@ethersproject/strings": "5.1.0", - "@ethersproject/transactions": "5.1.1", - "@ethersproject/units": "5.1.0", - "@ethersproject/wallet": "5.1.0", - "@ethersproject/web": "5.1.0", - "@ethersproject/wordlists": "5.1.0" - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "express-ipfilter": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/express-ipfilter/-/express-ipfilter-1.2.0.tgz", - "integrity": "sha512-nPXKMuhqVjX7+Vny4XsrpdqlX4YAGcanE0gh5xzpfmNTsINGAgPnpk67kb0No3p1m4vGQQLU6hdaXRxsuGNlTA==", - "requires": { - "ip": "~1.1.0", - "lodash": "^4.17.11", - "proxy-addr": "^2.0.4", - "range_check": "^1.2.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" - }, - "fecha": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", - "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-stream-rotator": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.5.7.tgz", - "integrity": "sha512-VYb3HZ/GiAGUCrfeakO8Mp54YGswNUHvL7P09WQcXAJNSj3iQ5QraYSp3cIn1MUyw6uzfgN/EFOarCNa4JvUHQ==", - "requires": { - "moment": "^2.11.2" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - } - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", - "dev": true - }, - "fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fraction.js": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz", - "integrity": "sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "global-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", - "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", - "dev": true, - "requires": { - "ini": "1.3.7" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "helmet": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.5.0.tgz", - "integrity": "sha512-GfxdTaKarneWOpxmiVb/1YsY+fIwDOxVUGrvNEM1MC8W6Z2PREfkXiWF4XHQdvkyXwUTHuY4DRwB0uH/Q6BVyQ==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } - }, - "http-status-codes": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.1.4.tgz", - "integrity": "sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg==" - }, - "iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "ip6": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/ip6/-/ip6-0.0.4.tgz", - "integrity": "sha1-RMWp23njnUBSAbTXjROzhw5I2zE=" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "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==" - }, - "is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-function": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", - "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "dev": true, - "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, - "is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, - "javascript-natural-sort": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", - "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbi": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", - "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "requires": { - "package-json": "^6.3.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "logform": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", - "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", - "requires": { - "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "triple-beam": "^1.3.0" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "mathjs": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-9.3.2.tgz", - "integrity": "sha512-0YKSKAeN9OkbIQrxfxnBT4kk/KlH71piWOsvVvAasyRIj/Xd/zlpc5VP/aFxwr+llOq2F3f6booPEu2fWv3yjQ==", - "requires": { - "complex.js": "^2.0.11", - "decimal.js": "^10.2.1", - "escape-latex": "^1.2.0", - "fraction.js": "^4.0.13", - "javascript-natural-sort": "^0.7.1", - "seedrandom": "^3.0.5", - "tiny-emitter": "^2.1.0", - "typed-function": "^2.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "requires": { - "mime-db": "1.47.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", - "dev": true - }, - "nodemon": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", - "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", - "dev": true, - "requires": { - "chokidar": "^3.2.2", - "debug": "^3.2.6", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.7", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.3", - "update-notifier": "^4.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true - }, - "object-hash": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz", - "integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==" - }, - "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" - } - }, - "object.values": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", - "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "requires": { - "fn.name": "1.x.x" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "post-message-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/post-message-stream/-/post-message-stream-3.0.0.tgz", - "integrity": "sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg=", - "requires": { - "readable-stream": "^2.1.4" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, - "requires": { - "escape-goat": "^2.0.0" - } - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomstring": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.1.5.tgz", - "integrity": "sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM=", - "requires": { - "array-uniq": "1.0.2" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "range_check": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/range_check/-/range_check-1.4.0.tgz", - "integrity": "sha1-zYfHrGLEC6nfabhwPGBPYMN0hjU=", - "requires": { - "ip6": "0.0.4", - "ipaddr.js": "1.2" - }, - "dependencies": { - "ipaddr.js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.2.0.tgz", - "integrity": "sha1-irpJyRknmVhb3WQ+DMtQ6K53e6Q=" - } - } - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - } - } - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - } - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true - }, - "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - }, - "regexpu-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" - } - }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "regjsparser": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", - "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "seedrandom": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", - "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "requires": { - "semver": "^6.3.0" - } - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "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==" - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "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.1" - } - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "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=" - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "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" - } - }, - "table": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.2.0.tgz", - "integrity": "sha512-WMBBLuauiLXJjth35K4vOnd/xkaZ/dxEcyoZ+YhxSwfxFqvh+av06+oRqIwbR14m1lENB1egSWOFv/bNEt2D8A==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "ajv": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", - "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true - }, - "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", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" - }, - "tiny-invariant": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", - "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" - }, - "tiny-secp256k1": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", - "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==", - "requires": { - "bindings": "^1.3.0", - "bn.js": "^4.11.8", - "create-hmac": "^1.1.7", - "elliptic": "^6.4.0", - "nan": "^2.13.2" - } - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "requires": { - "rimraf": "^3.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toformat": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", - "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "requires": { - "nopt": "~1.0.10" - } - }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typed-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-2.0.0.tgz", - "integrity": "sha512-Hhy1Iwo/e4AtLZNK10ewVVcP2UEs408DS35ubP825w/YgSBK1KVLwALvvIG4yX75QJrxjCpcWkzkVRB0BwwYlA==" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typeforce": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", - "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "undefsafe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", - "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "dev": true, - "requires": { - "debug": "^2.2.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", - "dev": true - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "update-notifier": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", - "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", - "dev": true, - "requires": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "utf-8-validate": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", - "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", - "requires": { - "node-gyp-build": "^4.2.0" - } - }, - "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - } - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - } - }, - "wif": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", - "requires": { - "bs58check": "<3.0.0" - } - }, - "winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "requires": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "dependencies": { - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - } - } - }, - "winston-daily-rotate-file": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.2.tgz", - "integrity": "sha512-DpAz9djExzFGVGRIKCKzsjOQaIINbjOUJ8CRsZGz0SQOMMcO1kM7jqTdzQAM9CRTEksZV9bBw9TT0ddQBGxs9g==", - "requires": { - "file-stream-rotator": "^0.5.7", - "object-hash": "^2.0.1", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - } - }, - "winston-transport": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", - "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", - "requires": { - "readable-stream": "^2.3.7", - "triple-beam": "^1.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 29d94b7..0000000 --- a/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "gateway-api", - "version": "0.3.1", - "description": "Hummingbot Gateway", - "main": "index.js", - "license": "Apache 2", - "repository": "https://github.com/coinalpha/gateway-api", - "scripts": { - "start": "pm2 start babel-node -- src/index.js", - "status": "pm2 monit", - "stop": "pm2 stop all", - "logs": "pm2 logs", - "debug": "DEBUG=*router nodemon --exec babel-node src/index.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "@balancer-labs/sor": "^0.3.3", - "@perp/contract": "^1.0.6", - "@terra-money/terra.js": "^0.5.8", - "@uniswap/sdk": "^3.0.3", - "app-root-path": "^3.0.0", - "axios": "^0.21.1", - "bignumber.js": "^9.0.0", - "body-parser": "^1.19.0", - "capture-console": "^1.0.1", - "cross-fetch": "^3.0.6", - "debug": "^4.2.0", - "dotenv": "^8.2.0", - "yenv": "^3.0.0", - "yaml": "^1.10.2", - "yawn-yaml": "^1.5.0", - "ethers": "^5.0.14", - "express": "^4.17.1", - "express-ipfilter": "^1.1.2", - "helmet": "^4.1.1", - "http-status-codes": "^2.1.3", - "lodash": "^4.17.20", - "mathjs": "^9.3.0", - "moment": "^2.29.1", - "util": "^0.12.3", - "winston": "^3.3.3", - "winston-daily-rotate-file": "^4.5.0" - }, - "devDependencies": { - "@babel/core": "^7.11.6", - "@babel/node": "^7.10.5", - "@babel/preset-env": "^7.11.5", - "eslint": "^7.10.0", - "eslint-config-standard": "^14.1.1", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^4.0.1", - "nodemon": "^2.0.4", - "pm2": "^4.5.6" - }, - "engines": { - "node": "12.x" - }, - "type": "module" -} diff --git a/setup.md b/setup.md deleted file mode 100644 index 3340dce..0000000 --- a/setup.md +++ /dev/null @@ -1,133 +0,0 @@ -# Hummingbot Gateway - -## Express Middleware - -NodeJS, Express middleware/REST API server that connects to protocol library. - -This can be used as a common API server to handle transactions that requires custom or third party libraries. - -## Development Requirements - -- NodeJS - - Tested on Node v10.22.1 - - https://docs.npmjs.com/downloading-and-installing-node-js-and-npm - - ```bash - # Using Homebrew MacOS: - brew install node - - ``` - -- Yarn (for node package installations) - - Tested on v1.22.5 - - To install yarn: - ```bash - npm install yarn - - ``` - -- ExpressJS - Install through package.json - -[optional] -To switch to specific Node version, you can use `n` to handle the version installation and switch easily. - -```bash -# install n -npm -g install n -# list remote available node version -n ls-remote -# list locally installed node version -n ls -# install specific version (e.g. 10, 12.18.3, 14.11.0) -n 10 -# use specific version, then select installed version -n - - -## Setup - -```bash - -git clone -cd - -# install npm packages -yarn install - -# setup config -cp .env.example .env - -# run dev mode with hot reload on code changes -yarn run dev - -# run debug mode with additional route debug logging -yarn run debug - -# Run prod mode -yarn run start - -# API -https://localhost:5000/api - -# Protocol Endpoints -All endpoint require POST request with data - -# ETHEREUM - -# get ETH and ERC-20 tokens balances in the user's wallet -https://localhost:5000/eth/balances - -# get ERC-20 allowances for a contract address -https://localhost:5000/eth/allowances - -# approve a contract to allow transferring tokens to it -https://localhost:5000/eth/approve - -# send testnet ETH to WETH contract to get testnet WETH -https://localhost:5000/eth/deposit - - -# BALANCER - -# get price and pools for a trade -https://localhost:5000/balancer/buy-price -https://localhost:5000/balancer/sell-price - -# execute trade -https://localhost:5000/balancer/buy -https://localhost:5000/balancer/sell - - -``` - -### SSL Test - -SSL is setup for HTTPS traffic to Gateway running at localhost. To run Gateway as standalone API server, use the following test script to generate the SSL certs. - -```bash -$ ssl-scripts.sh - -# Test endpoint -curl --insecure --key ./certs/client_key.pem --cert ./certs/client_cert.pem https://localhost:5000/api - -``` - -Test endpoint on Python -```python - -# update the locaiton path of the pem files - -def test_get_api_status(self): - url = 'https://localhost:5000/api' - - ca_certs = realpath(join(__file__, join("../../certs/ca_cert.pem"))) - client_certs = (realpath(join(__file__, join("../../certs/client_cert.pem"))), - realpath(join(__file__, join("../../certs/client_key.pem")))) - response = requests.get(url, verify=ca_certs, cert=client_certs) - - result = response.json() - print('result', result) - - self.assertTrue('status' in result.keys() and result['status'] == 'ok', f"Gateway API {url} not ready") - -``` diff --git a/src/app.js b/src/app.js deleted file mode 100644 index d6574d6..0000000 --- a/src/app.js +++ /dev/null @@ -1,61 +0,0 @@ -import dotenv from 'dotenv'; -import bodyParser from 'body-parser' -import express from 'express' -import helmet from 'helmet' -import { statusMessages } from './services/utils'; -import { validateAccess } from './services/access'; -import { IpFilter } from 'express-ipfilter' -import { logger } from './services/logger'; - -// Routes -import apiRoutes from './routes/index.route' -import balancerRoutes from './routes/balancer.route' -// import celoRoutes from './routes/celo.route' -import ethRoutes from './routes/eth.route' -import terraRoutes from './routes/terra.route' -import uniswapRoutes from './routes/uniswap.route' -import perpFiRoutes from './routes/perpetual_finance.route' - -// create app -const app = express(); - -// middleware -// #security: remove response headers from middleware -// https://www.npmjs.com/package/helmet -app.use(helmet()); - -const ipWhitelist = process.env.IP_WHITELIST; -if (ipWhitelist) { - app.use(IpFilter(JSON.parse(ipWhitelist), { mode: 'allow' })) -} -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: true })); - -app.use(validateAccess) - -// mount routes to specific path -app.use('/api', apiRoutes); -app.use('/eth', ethRoutes); -app.use('/eth/uniswap', uniswapRoutes); -app.use('/eth/balancer', balancerRoutes); -app.use('/terra', terraRoutes); -app.use('/perpfi', perpFiRoutes); -// app.use('/celo', celoRoutes); - -app.get('/', (req, res, next) => { - res.send('ok') -}) - -/** - * Catch all 404 response when routes are not found - */ -app.use((req, res, next) => { - const message = `${statusMessages.page_not_found} at ${req.originalUrl}` - logger.error(message) - res.status(404).send({ - error: 'Page not found', - message: message - }); -}); - -export default app; diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 90bf3f6..0000000 --- a/src/index.js +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env node - -// absolute imports -import https from 'https' -import fs from 'fs' -import yenv from 'yenv' - -// relative imports -import app from './app' -import { logger } from './services/logger' - -// terminate if environment not found -const result2 = yenv() -if (result.error) { - logger.info(result.error); - process.exit(1); -} - -const env = process.env.NODE_ENV -const port = process.env.PORT -const certPassphrase = process.env.CERT_PASSPHRASE -const ethereumChain = process.env.ETHEREUM_CHAIN -const terraChain = process.env.TERRA_CHAIN -let certPath = process.env.CERT_PATH - -if ((typeof certPath === 'undefined' && certPath == null) || certPath === '') { - // assuming it is local development using test script to generate certs - certPath = './certs' -} else { - certPath = certPath.replace(/\/$/, ''); -} - -// set app environment -app.set('env', env) -const options = { - key: fs.readFileSync(certPath.concat('/server_key.pem'), { encoding: 'utf-8' }), - cert: fs.readFileSync(certPath.concat('/server_cert.pem'), { encoding: 'utf-8' }), - // request client certificate from user - requestCert: true, - // reject requests with no valid certificate - rejectUnauthorized: true, - // use ca cert created with own key for self-signed - ca: [fs.readFileSync(certPath.concat('/ca_cert.pem'), { encoding: 'utf-8' })], - passphrase: certPassphrase -}; - -const server = https.createServer(options, app) - -// event listener for "error" event -const onError = error => { - if (error.syscall !== 'listen') { - throw error - } - - const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port - - // handle specific listen errors with friendly messages - switch (error.code) { - case 'EACCES': - console.error(bind + ' requires elevated privileges') - process.exit(1) - case 'EADDRINUSE': - console.error(bind + ' is already in use') - process.exit(1) - default: - throw error - } -} - -// event listener for "listening" event. -const onListening = () => { - const addr = server.address() - const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port - console.log('listening on ' + bind) - logger.debug('listening on ' + bind) -} - -// listen on provided port, on all network interfaces. -server.listen(port) -server.on('error', onError) -server.on('listening', onListening) - -const serverConfig = { - app: 'gateway-api', - port: port, - ethereumChain: ethereumChain, - terraChain: terraChain -} - -logger.info(JSON.stringify(serverConfig)) -console.log(serverConfig) diff --git a/src/routes/balancer.route.js b/src/routes/balancer.route.js deleted file mode 100644 index a27fe5d..0000000 --- a/src/routes/balancer.route.js +++ /dev/null @@ -1,360 +0,0 @@ -import BigNumber from 'bignumber.js'; -import { ethers } from 'ethers'; -import express from 'express'; - -import { getParamData, latency, reportConnectionError, statusMessages } from '../services/utils'; - -import Ethereum from '../services/eth'; -import Balancer from '../services/balancer'; -import Fees from '../services/fees'; -import { logger } from '../services/logger'; - -const debug = require('debug')('router') -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) -const balancer = new Balancer(process.env.ETHEREUM_CHAIN) -const fees = new Fees() - -const swapMoreThanMaxPriceError = 'Price too high' -const swapLessThanMaxPriceError = 'Price too low' - -const estimateGasLimit = (maxswaps) => { - const gasLimit = balancer.gasBase + maxswaps * balancer.gasPerSwap - return gasLimit -} - -router.post('/', async (req, res) => { - /* - POST / - */ - res.status(200).json({ - network: balancer.network, - provider: balancer.provider.connection.url, - exchangeProxy: balancer.exchangeProxy, - subgraphUrl: balancer.subgraphUrl, - connection: true, - timestamp: Date.now(), - }) -}) - -router.post('/gas-limit', async (req, res) => { - /* - POST: /buy-price - x-www-form-urlencoded: { - "maxSwaps":4 - } - */ - const paramData = getParamData(req.body) - - try { - const swaps = paramData.maxSwaps - const maxSwaps = typeof swaps === 'undefined' || parseInt(swaps) === 0 ? balancer.maxSwaps : parseInt(swaps) - const gasLimit = estimateGasLimit(maxSwaps) - - res.status(200).json({ - network: balancer.network, - gasLimit: gasLimit, - timestamp: Date.now(), - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.get('/start', async (req, res) => { - /* - POST: /eth/balancer/start - x-www-form-urlencoded: { - "pairs":'["ETH-USDT", ...]' - "gasPrice":30 - } - */ - const initTime = Date.now() - const paramData = getParamData(req.query) - const pairs = JSON.parse(paramData.pairs) - let gasPrice - if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) - } else { - gasPrice = fees.ethGasPrice - } - - // get token contract address and cache pools - for (let pair of pairs){ - pair = pair.split("-") - const baseTokenSymbol = pair[0] - const quoteTokenSymbol = pair[1] - const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) - - // check for valid token symbols - if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { - const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol - res.status(500).json({ - error: `Token ${undefinedToken} contract address not found`, - message: `Token contract address not found for ${undefinedToken}. Check token list source`, - }) - return - } - await Promise.allSettled([balancer.fetchPool(baseTokenContractInfo.address, quoteTokenContractInfo.address), - balancer.fetchPool(quoteTokenContractInfo.address, baseTokenContractInfo.address)]) - } - - - const gasLimit = estimateGasLimit(balancer.maxSwaps) - const gasCost = await fees.getGasCost(gasPrice, gasLimit) - - const result = { - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - success: true, - pairs: pairs, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - } - console.log('Initializing balancer') - res.status(200).json(result) -}) - -router.post('/price', async (req, res) => { - /* - POST: /eth/balancer/price - x-www-form-urlencoded: { - "quote":"BAT" - "base":"USDC" - "amount":0.1 - "side":buy - } - */ - const initTime = Date.now() - // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body) - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals - const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals - const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) - const maxSwaps = balancer.maxSwaps - const side = paramData.side.toUpperCase() - let gasPrice - if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) - } else { - gasPrice = fees.ethGasPrice - } - - try { - // fetch the optimal pool mix from balancer-sor - const { swaps, expectedAmount } = side === 'BUY' - ? await balancer.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount, - maxSwaps, - ) - : await balancer.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount, - maxSwaps, - ) - - if (swaps != null && expectedAmount != null) { - const gasLimit = estimateGasLimit(swaps.length) - const gasCost = await fees.getGasCost(gasPrice, gasLimit) - - const tradeAmount = parseFloat(amount) - const expectedTradeAmount = parseInt(expectedAmount) / quoteDenomMultiplier - const tradePrice = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier - - const result = { - network: balancer.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseTokenContractInfo, - quote: quoteTokenContractInfo, - amount: tradeAmount, - side: side, - expectedAmount: expectedTradeAmount, - price: tradePrice, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - swaps: swaps, - } - debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) - res.status(200).json(result) - } else { // no pool available - res.status(200).json({ - info: statusMessages.no_pool_available, - message: statusMessages.no_pool_available - }) - } - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/trade', async (req, res) => { - /* - POST: /trade - x-www-form-urlencoded: { - "quote":"BAT" - "base":"USDC" - "amount":0.1 - "limitPrice":1 - "gasPrice":10 - "side":{buy|sell} - "privateKey":{{privateKey}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, balancer.provider) - - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals - const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals - const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) - - const maxSwaps = balancer.maxSwaps - const side = paramData.side.toUpperCase() - - let limitPrice - if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice) - } - let gasPrice - if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) - } else { - gasPrice = fees.ethGasPrice - } - - try { - // fetch the optimal pool mix from balancer-sor - const { swaps, expectedAmount } = side === 'BUY' - ? await balancer.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount, - maxSwaps, - ) - : await balancer.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount, - maxSwaps, - ) - - const gasLimit = estimateGasLimit(swaps.length) - const gasCost = await fees.getGasCost(gasPrice, gasLimit) - - if (side === 'BUY') { - const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier - logger.info(`Price: ${price.toString()}`) - if (!limitPrice || price <= limitPrice) { - // pass swaps to exchange-proxy to complete trade - const tx = await balancer.swapExactOut( - wallet, - swaps, - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - expectedAmount.toString(), - gasPrice, - ) - - // submit response - res.status(200).json({ - network: balancer.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseTokenContractInfo, - quote: quoteTokenContractInfo, - amount: parseFloat(paramData.amount), - expectedIn: expectedAmount / quoteDenomMultiplier, - price: price, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - txHash: tx.hash, - }) - } else { - res.status(200).json({ - error: swapMoreThanMaxPriceError, - message: `Swap price ${price} exceeds limitPrice ${limitPrice}` - }) - debug(`Swap price ${price} exceeds limitPrice ${limitPrice}`) - } - } else { - // sell - const minAmountOut = limitPrice / amount * baseDenomMultiplier - debug('minAmountOut', minAmountOut) - const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier - logger.info(`Price: ${price.toString()}`) - if (!limitPrice || price >= limitPrice) { - // pass swaps to exchange-proxy to complete trade - const tx = await balancer.swapExactIn( - wallet, - swaps, - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount.toString(), - parseInt(expectedAmount) / quoteDenomMultiplier, - gasPrice, - ) - // submit response - res.status(200).json({ - network: balancer.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseTokenContractInfo, - quote: quoteTokenContractInfo, - amount: parseFloat(paramData.amount), - expectedOut: expectedAmount / quoteDenomMultiplier, - price: price, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - txHash: tx.hash, - }) - } else { - res.status(200).json({ - error: swapLessThanMaxPriceError, - message: `Swap price ${price} lower than limitPrice ${limitPrice}` - }) - debug(`Swap price ${price} lower than limitPrice ${limitPrice}`) - } - } - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -export default router; diff --git a/src/routes/celo.route.js b/src/routes/celo.route.js deleted file mode 100644 index a5ad910..0000000 --- a/src/routes/celo.route.js +++ /dev/null @@ -1,252 +0,0 @@ -'use strict' - -const express = require('express') -const router = express.Router() -const BigNumber = require('bignumber.js'); -const debug = require('debug')('router') -const spawn = require('child_process').spawn - -const network = 'celo' -const celocli = 'celocli' -const DENOM_UNIT_MULTIPLIER = BigNumber('1e+18') - -const hbUtils = require('../services/utils') -const separator = '=>' - -router.use((req, res, next) => { - debug('celo route:', Date.now()) - next() -}) - -router.get('/', (req, res) => { - res.status(200).send(network) -}) - -router.get('/status', (req, res) => { - /* - return if the celocli ultralight node is synced - */ - - const nodeSync = spawn(celocli, ['node:synced']); - - let err_message = [], out_message = [] - - nodeSync.stdout.on( 'data', out => { - out_message.push(out.toString().trim()) - debug('out_message', out_message) - }) - - nodeSync.stderr.on( 'data', err => { - err_message.push(err.toString().trim()) - debug('err_message', err_message) - }) - - nodeSync.on( 'close', code => { - if (code === 0) { - res.status(200).json({ - synced: out_message[0].toLowerCase() === 'true', - message: err_message.join('') - }) - } else { - res.status(401).json({ - error: err_message.join('') - }) - } - }) -}) - - -router.get('/price', (req, res) => { - /* - api request format: - /price?trading_pair=CELO-CUSD&trade_type=sell&amount=1.2345 - */ - const keyFormat = ['trading_pair', 'trade_type', 'amount'] - - const initTime = Date.now() - - const paramData = hbUtils.getParamData(req.query, keyFormat) - const tradingPair = paramData.trading_pair - const tradeType = paramData.trade_type - const requestAmount = paramData.amount - const amount = parseFloat(requestAmount) * DENOM_UNIT_MULTIPLIER - debug('params', req.params) - debug('paramData', paramData) - - const nodeSync = spawn(celocli, ["exchange:show", "--amount", amount]); - - let err_message = [], out_message = [] - - nodeSync.stdout.on( 'data', out => { - out_message.push(out.toString().trim()) - }) - - nodeSync.stderr.on( 'data', err => { - err_message.push(err.toString().trim()) - }) - - nodeSync.on( 'close', code => { - - let exchange_rates = {} - let price - - if (code === 0) { - // extract exchange rate from cli output - out_message.forEach((item, index) => { - if (item.includes(separator)) { - let exchangeInfo = item.split(separator) - let base = exchangeInfo[0].trim().split(' ') - let quote = exchangeInfo[1].trim().split(' ') - let market = [base[1].toUpperCase(), quote[1].toUpperCase()].join('-') - exchange_rates[market] = quote[0]/DENOM_UNIT_MULTIPLIER - debug (exchangeInfo, exchange_rates) - } - }) - - price = exchange_rates[tradingPair] - - const result = Object.assign(paramData, { - price: price, - timestamp: initTime, - latency: hbUtils.latency(initTime, Date.now()), - } - ) - res.status(200).json(result) - } - }) - -}) - -router.get('/balance', (req, res) => { - /* - api request format: - /balance?address=0x87A4...b120 - */ - const keyFormat = ['address'] - const paramData = hbUtils.getParamData(req.query, keyFormat) - const address = paramData.address - debug(paramData) - - const balance = spawn(celocli, ["account:balance", address]); - - let err_message = [], out_message = [] - let walletBalances = {} - - balance.stdout.on( 'data', out => { - out_message.push(out.toString().trim()) - debug(out_message) - }) - - balance.stderr.on( 'data', err => { - err_message.push(err.toString().trim()) - debug(err_message) - }) - - balance.on( 'close', code => { - if (code === 0) { - out_message.forEach((item, index) => { - // key indicator in balance result: "celo", "gold", "lockedcelo", "lockedgold", "usd", "pending" - if (item.toLowerCase().includes( "lockedcelo") || item.toLowerCase().includes("lockedgold")) { - let balanceArray = item.split('\n') - balanceArray.forEach((x) => { - let keyValue = x.split(':') - walletBalances[keyValue[0].trim()] = keyValue[1].trim()/DENOM_UNIT_MULTIPLIER - } - ) - debug('walletBalances', walletBalances) - } - }) - - res.status(200).json({ - address: address, - balance: walletBalances, - timestamp: Date.now() - }) - } else { - res.status(401).json({ - error: err_message, - }) - } - }) -}) - - -router.post('/unlock', (req, res) => { - /* - api request format: - POST: /balance - data: { - "address": "0x87A4...b120", - "secret": "mysupersecret" - } - */ - const keyFormat = ['address', 'secret'] - const paramData = hbUtils.getParamData(req.body, keyFormat) - const address = paramData.address - const secret = paramData.secret - - debug(paramData) - debug(req.body) - - const lockStatus = spawn(celocli, ["account:unlock", address, "--password", secret]); - - let err_message = [], out_message = [] - - lockStatus.stdout.on( 'data', out => { - out_message.push(out.toString().trim()) - debug(out_message) - }) - - lockStatus.stderr.on( 'data', err => { - err_message.push(err.toString().trim()) - debug(err_message) - }) - - lockStatus.on( 'close', code => { - let unlocked = false - if (code === 0) { - if (out_message.length > 0) { - out_message.forEach((item, index) => { - if (item.includes(separator)) { - debug('item', item) - } - }) - } else { - unlocked = true - } - res.status(200).json({ - unlocked: unlocked, - message: out_message.join(), - timestamp: Date.now() - }) - } else { - res.status(401).json({ - error: err_message.join(), - }) - } - }) -}) - -router.post('/trade', (req, res) => { - /* - api request format: - POST: /trade - data: { - "trading_pair": "CELO-CUSD", - "trade_type": "buy", - "amount": 1.234, - "price": 3.512 - } - */ - const keyFormat = ['trading_pair', 'trade_type', 'amount', 'price'] - const paramData = hbUtils.getParamData(req.body, keyFormat) - debug(paramData) - // const result = Object.assign(paramData, { - // message: 'WIP', - // timestamp: Date.now() - // }) - res.status(200).json({"status": "WIP"}) -}) - - -module.exports = router diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js deleted file mode 100644 index 53dfe79..0000000 --- a/src/routes/eth.route.js +++ /dev/null @@ -1,428 +0,0 @@ -import { ethers, BigNumber } from 'ethers'; -import express from 'express'; - -import { getParamData, latency, statusMessages } from '../services/utils'; -import Ethereum from '../services/eth'; -import Fees from '../services/fees'; -import { logger } from '../services/logger'; - -const debug = require('debug')('router') -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) -const spenders = { - balancer: process.env.EXCHANGE_PROXY, - uniswap: process.env.UNISWAP_ROUTER -} -const fees = new Fees() - -router.post('/', async (req, res) => { - /* - POST / - */ - res.status(200).json({ - network: eth.network, - rpcUrl: eth.provider.connection.url, - connection: true, - timestamp: Date.now(), - }) -}) - -router.post('/balances', async (req, res) => { - /* - POST: /balances - x-www-form-urlencoded: { - privateKey:{{privateKey}} - tokenList:{{tokenList}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet - try { - wallet = new ethers.Wallet(privateKey, eth.provider) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - - // populate token contract info using token symbol list - const tokenContractList = [] - const tokenList = JSON.parse(paramData.tokenList) - tokenList.forEach(symbol => { - const tokenContractInfo = eth.getERC20TokenAddresses(symbol) - tokenContractList[symbol] = tokenContractInfo - }); - - const balances = {} - balances.ETH = await eth.getETHBalance(wallet, privateKey) - try { - Promise.all( - Object.keys(tokenContractList).map(async (symbol, index) => { - if (tokenContractList[symbol] !== undefined) { - const address = tokenContractList[symbol].address - const decimals = tokenContractList[symbol].decimals - balances[symbol] = await eth.getERC20Balance(wallet, address, decimals) - } else { - const err = `Token contract info for ${symbol} not found` - logger.error('Token info not found', { message: err }) - debug(err) - } - } - )).then(() => { - console.log('eth.route - Get Account Balance', { message: JSON.stringify(tokenList) }) - res.status(200).json({ - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - balances: balances - }) - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/allowances', async (req, res) => { - /* - POST: /allowances - x-www-form-urlencoded: { - privateKey:{{privateKey}} - tokenAddressList:{{tokenAddressList}} - connector:{{connector_name}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const spender = spenders[paramData.connector] - let wallet - try { - wallet = new ethers.Wallet(privateKey, eth.provider) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - - // populate token contract info using token symbol list - const tokenContractList = [] - const tokenList = JSON.parse(paramData.tokenList) - tokenList.forEach(symbol => { - const tokenContractInfo = eth.getERC20TokenAddresses(symbol) - tokenContractList[symbol] = tokenContractInfo - }); - - const approvals = {} - try { - Promise.all( - Object.keys(tokenContractList).map(async (symbol, index) => { - const address = tokenContractList[symbol].address - const decimals = tokenContractList[symbol].decimals - approvals[symbol] = await eth.getERC20Allowance(wallet, spender, address, decimals) - } - )).then(() => { - logger.info('eth.route - Getting allowances', { message: JSON.stringify(tokenList) }) - res.status(200).json({ - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - spender: spender, - approvals: approvals, - }) - } - ) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/balances-2', async (req, res) => { - /* - POST: /balances - x-www-form-urlencoded: { - privateKey:{{privateKey}} - tokenAddressList:{{tokenAddressList}} - tokenDecimalList:{{tokenDecimalList}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet - try { - wallet = new ethers.Wallet(privateKey, eth.provider) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - let tokenAddressList - if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(',') - } - let tokenDecimalList - if (paramData.tokenDecimalList) { - tokenDecimalList = paramData.tokenDecimalList.split(',') - } - - const balances = {} - balances.ETH = await eth.getETHBalance(wallet, privateKey) - try { - Promise.all( - tokenAddressList.map(async (value, index) => - balances[value] = await eth.getERC20Balance(wallet, value, tokenDecimalList[index]) - )).then(() => { - res.status(200).json({ - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - balances: balances - }) - }) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/allowances-2', async (req, res) => { - /* - POST: /allowances - x-www-form-urlencoded: { - privateKey:{{privateKey}} - tokenAddressList:{{tokenAddressList}} - tokenDecimalList:{{tokenDecimalList}} - connector:{{connector_name}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const spender = spenders[paramData.connector] - let wallet - try { - wallet = new ethers.Wallet(privateKey, eth.provider) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - let tokenAddressList - if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(',') - } - let tokenDecimalList - if (paramData.tokenDecimalList) { - tokenDecimalList = paramData.tokenDecimalList.split(',') - } - - const approvals = {} - try { - Promise.all( - tokenAddressList.map(async (value, index) => - approvals[value] = await eth.getERC20Allowance(wallet, spender, value, tokenDecimalList[index]) - )).then(() => { - res.status(200).json({ - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - spender: spender, - approvals: approvals, - }) - } - ) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/approve', async (req, res) => { - /* - POST: /approve - x-www-form-urlencoded: { - privateKey:{{privateKey}} - tokenAddress:"0x....." - decimals: {{token_decimals}} - connector:{{connector_name}} - amount:{{amount}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const spender = spenders[paramData.connector] - let wallet - try { - wallet = new ethers.Wallet(privateKey, eth.provider) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - const token = paramData.token - const tokenContractInfo = eth.getERC20TokenAddresses(token) - const tokenAddress = tokenContractInfo.address - const decimals = tokenContractInfo.decimals - - let amount - paramData.amount ? amount = ethers.utils.parseUnits(paramData.amount, decimals) - : amount = ethers.utils.parseUnits('1000000000', decimals) // approve for 1 billion units if no amount specified - let gasPrice - if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) - } else { - gasPrice = fees.ethGasPrice - } - - try { - // call approve function - const approval = await eth.approveERC20(wallet, spender, tokenAddress, amount, gasPrice) - // console.log('eth.route - Approving allowance', { message: approval }) - // submit response - res.status(200).json({ - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - tokenAddress: tokenAddress, - spender: spender, - amount: amount / 1e18.toString(), - approval: approval - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/poll', async (req, res) => { - const initTime = Date.now() - const paramData = getParamData(req.body) - const txHash = paramData.txHash - const txReceipt = await eth.provider.getTransactionReceipt(txHash) - const receipt = {} - const confirmed = txReceipt && txReceipt.blockNumber ? true : false - if (confirmed) { - receipt.gasUsed = BigNumber.from(txReceipt.gasUsed).toNumber() - receipt.blockNumber = txReceipt.blockNumber - receipt.confirmations = txReceipt.confirmations - receipt.status = txReceipt.status - } - logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }) - res.status(200).json({ - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - txHash: txHash, - confirmed: confirmed, - receipt: receipt, - }) - return txReceipt -}) - -// Kovan faucet to get test tokens (wip) & weth conversion -// router.post('/get-weth', async (req, res) => { -// /* -// POST: /get-weth -// x-www-form-urlencoded: { -// gasPrice:{gasPrice} -// amount:{{amount}} -// privateKey:{{privateKey}} -// } -// */ -// const initTime = Date.now() -// const paramData = getParamData(req.body) -// const privateKey = paramData.privateKey -// let wallet -// try { -// wallet = new ethers.Wallet(privateKey, eth.provider) -// } catch (err) { -// logger.error(req.originalUrl, { message: err }) -// let reason -// err.reason ? reason = err.reason : reason = 'Error getting wallet' -// res.status(500).json({ -// error: reason, -// message: err -// }) -// return -// } -// const amount = ethers.utils.parseEther(paramData.amount) -// const tokenAddress = eth.getERC20TokenAddresses('WETH').address -// let gasPrice -// if (paramData.gasPrice) { -// gasPrice = parseFloat(paramData.gasPrice) -// } - -// try { -// // call deposit function -// const response = await eth.deposit(wallet, tokenAddress, amount, gasPrice) - -// // submit response -// res.status(200).json({ -// network: eth.network, -// timestamp: initTime, -// amount: parseFloat(amount), -// result: response -// }) -// } catch (err) { -// logger.error(req.originalUrl, { message: err }) -// let reason -// err.reason ? reason = err.reason : reason = statusMessages.operation_error -// res.status(500).json({ -// error: reason, -// message: err -// }) -// } -// }) - -module.exports = router; diff --git a/src/routes/index.route.js b/src/routes/index.route.js deleted file mode 100644 index 1ea698f..0000000 --- a/src/routes/index.route.js +++ /dev/null @@ -1,16 +0,0 @@ -import { loadConfig } from '../services/utils'; - -const express = require('express'); - -const router = express.Router(); - -router.get('/', (req, res) => { - res.status(200).json({ - app: process.env.APPNAME, - image: process.env.IMAGE, - config: loadConfig(), - status: 'ok', - }); -}) - -module.exports = router; diff --git a/src/routes/perpetual_finance.route.js b/src/routes/perpetual_finance.route.js deleted file mode 100644 index ae96622..0000000 --- a/src/routes/perpetual_finance.route.js +++ /dev/null @@ -1,519 +0,0 @@ -import { ethers, BigNumber } from 'ethers'; -import express from 'express'; - -import { getParamData, latency, statusMessages } from '../services/utils'; -import { logger } from '../services/logger'; -import PerpetualFinance from '../services/perpetual_finance'; - -// require('dotenv').config() - -const router = express.Router() -const perpFi = new PerpetualFinance(process.env.ETHEREUM_CHAIN) -setTimeout(perpFi.update_price_loop.bind(perpFi), 2000) - -const getErrorMessage = (err) => { - /* - [WIP] Custom error message based-on string match - */ - let message = err - return message -} - -router.get('/', async (req, res) => { - /* - GET / - */ - res.status(200).json({ - network: perpFi.network, - provider: perpFi.provider.connection.url, - loadedMetadata: perpFi.loadedMetadata, - connection: true, - timestamp: Date.now(), - }) -}) - -router.get('/load-metadata', async (req, res) => { - /* - GET / - */ - const loadedMetadata = await perpFi.load_metadata() - res.status(200).json({ - network: perpFi.network, - provider: perpFi.provider.connection.url, - loadedMetadata: loadedMetadata, - connection: true, - timestamp: Date.now(), - }) -}) - -router.post('/balances', async (req, res) => { - /* - POST: /balances - x-www-form-urlencoded: { - privateKey:{{privateKey}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet - try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - - const balances = {} - balances["XDAI"] = await perpFi.getXdaiBalance(wallet) - balances["USDC"] = await perpFi.getUSDCBalance(wallet) - try { - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - balances: balances - }) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/allowances', async (req, res) => { - /* - POST: /allowances - x-www-form-urlencoded: { - privateKey:{{privateKey}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet - try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - - const approvals = {} - approvals["USDC"] = await perpFi.getAllowance(wallet) - try { - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - approvals: approvals - }) - } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/approve', async (req, res) => { - /* - POST: /approve - x-www-form-urlencoded: { - privateKey:{{privateKey}} - amount:{{amount}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let amount - paramData.amount ? amount = paramData.amount - : amount = '1000000000' - let wallet - try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - - try { - // call approve function - const approval = await perpFi.approve(wallet, amount) - logger.info('perpFi.route - Approving allowance') - // submit response - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - amount: amount, - approval: approval - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/open', async (req, res) => { - /* - POST: /open - x-www-form-urlencoded: { - side:{{side}} - pair:{{pair}} - margin:{{margin}} - leverage:{{leverage}} - minBaseAssetAmount:{{minBaseAssetAmount}} - privateKey:{{privateKey}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const side = paramData.side - const pair = paramData.pair - const margin = paramData.margin - const leverage = paramData.leverage - const minBaseAssetAmount = paramData.minBaseAssetAmount - console.log(minBaseAssetAmount) - const privateKey = paramData.privateKey - let wallet - try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - - try { - // call openPosition function - const tx = await perpFi.openPosition(side, margin, leverage, pair, minBaseAssetAmount, wallet) - logger.info('perpFi.route - Opening position') - // submit response - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - margin: margin, - side: side, - leverage: leverage, - minBaseAssetAmount: minBaseAssetAmount, - txHash: tx.hash - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/close', async (req, res) => { - /* - POST: /close - x-www-form-urlencoded: { - minimalQuoteAsset:{{minimalQuoteAsset}} - privateKey:{{privateKey}} - pair:{{pair}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const minimalQuoteAsset = paramData.minimalQuoteAsset - const privateKey = paramData.privateKey - const pair = paramData.pair - let wallet - try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - - try { - // call closePosition function - const tx = await perpFi.closePosition(wallet, pair, minimalQuoteAsset) - logger.info('perpFi.route - Closing position') - // submit response - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - minimalQuoteAsset: minimalQuoteAsset, - txHash: tx.hash - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - - -router.post('/position', async (req, res) => { - /* - POST: /position - x-www-form-urlencoded: { - privateKey:{{privateKey}} - pair:{{pair}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const pair = paramData.pair - let wallet - try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - - try { - // call getPosition function - const position = await perpFi.getPosition(wallet, pair) - logger.info('perpFi.route - getting active position') - // submit response - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - position: position - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/margin', async (req, res) => { - /* - POST: /margin - x-www-form-urlencoded: { - privateKey:{{privateKey}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet - try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' - res.status(500).json({ - error: reason, - message: err - }) - return - } - - try { - // call getAllBalances function - const allBalances = await perpFi.getActiveMargin(wallet) - logger.info('perpFi.route - Getting all balances') - // submit response - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - margin: allBalances - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/receipt', async (req, res) => { - /* - POST: /receipt - x-www-form-urlencoded: { - txHash:{{txHash}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const txHash = paramData.txHash - const txReceipt = await perpFi.provider.getTransactionReceipt(txHash) - const receipt = {} - const confirmed = txReceipt && txReceipt.blockNumber ? true : false - if (txReceipt !== null) { - receipt.gasUsed = ethers.utils.formatEther(txReceipt.gasUsed) - receipt.blockNumber = txReceipt.blockNumber - receipt.confirmations = txReceipt.confirmations - receipt.status = txReceipt.status - } - logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }) - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - txHash: txHash, - confirmed: confirmed, - receipt: receipt, - }) - return txReceipt -}) - -router.post('/price', async (req, res) => { - /* - POST: /price - x-www-form-urlencoded: { - side:{{side}} - pair:{{pair}} - amount:{{amount}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const side = paramData.side - const pair = paramData.pair - const amount = paramData.amount - - try { - // call getPrice function - const price = await perpFi.getPrice(side, amount, pair) - logger.info('perpFi.route - Getting price') - // submit response - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - side: side, - price: price - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - - -router.get('/pairs', async (req, res) => { - /* - GET - */ - const initTime = Date.now() - - try { - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - pairs: Object.keys(perpFi.amm) - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/funding', async (req, res) => { - /* - POST: /funding - x-www-form-urlencoded: { - pair:{{pair}} - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const pair = paramData.pair - - try { - // call getFundingRate function - const fr = await perpFi.getFundingRate(pair) - logger.info('perpFi.route - Getting funding info') - // submit response - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - fr: fr - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -export default router; diff --git a/src/routes/terra.route.js b/src/routes/terra.route.js deleted file mode 100644 index f2c64c3..0000000 --- a/src/routes/terra.route.js +++ /dev/null @@ -1,228 +0,0 @@ -'use strict' - -import express from 'express' -import { getParamData, latency, reportConnectionError, statusMessages } from '../services/utils'; -import { logger } from '../services/logger'; - -import Terra from '../services/terra'; - -const debug = require('debug')('router') -const router = express.Router(); -const terra = new Terra() - -// constants -const network = terra.lcd.config.chainID -const denomUnitMultiplier = terra.denomUnitMultiplier - -router.post('/', async (req, res) => { - /* - POST / - */ - res.status(200).json({ - network: network, - lcdUrl: terra.lcd.config.URL, - gasPrices: terra.lcd.config.gasPrices, - gasAdjustment: terra.lcd.config.gasAdjustment, - connection: true, - timestamp: Date.now() - }) -}) - -router.post('/balances', async (req, res) => { - /* - POST: - address:{{address}} - */ - const initTime = Date.now() - - const paramData = getParamData(req.body) - const address = paramData.address - - let balances = {} - - try { - await terra.lcd.bank.balance(address).then(bal => { - bal.toArray().forEach(async (x) => { - const item = x.toData() - const denom = item.denom - const amount = item.amount / denomUnitMultiplier - const symbol = terra.tokens[denom].symbol - balances[symbol] = amount - }) - }) - logger.info('terra.route - Get Account Balance') - res.status(200).json({ - network: network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - balances: balances, - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let message - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - const isAxiosError = err.isAxiosError - if (isAxiosError) { - reason = err.response.status - message = err.response.statusText - } else { - message = err - } - res.status(500).json({ - error: reason, - message: message - }) - } -}) - -router.post('/start', async (req, res) => { - /* - POST: /terra/start - x-www-form-urlencoded: { - "base":"UST" - "quote":"KRT" - "amount":1 - } - */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const baseTokenSymbol = paramData.base - const quoteTokenSymbol = paramData.quote - - const result = { - network: network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - success: true, - base: baseTokenSymbol, - quote: quoteTokenSymbol, - } - res.status(200).json(result) -}) - -router.post('/price', async (req, res) => { - /* - POST: - x-www-form-urlencoded: { - "base":"UST" - "quote":"KRT" - "side":"buy" or "sell" - "amount":1 - } - */ - const initTime = Date.now() - - const paramData = getParamData(req.body) - const baseToken = paramData.base - const quoteToken = paramData.quote - const tradeType = paramData.side.toUpperCase() - const amount = parseFloat(paramData.amount) - - let exchangeRate - - try { - await terra.getSwapRate(baseToken, quoteToken, amount, tradeType).then((rate) => { - exchangeRate = rate - }).catch((err) => { - reportConnectionError(res, err) - }) - - res.status(200).json( - { - network: network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseToken, - quote: quoteToken, - amount: amount, - tradeType: tradeType, - price: exchangeRate.price.amount, - cost: exchangeRate.cost.amount, - txFee: exchangeRate.txFee.amount, - } - ) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let message - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - const isAxiosError = err.isAxiosError - if (isAxiosError) { - reason = err.response.status - message = err.response.statusText - } else { - message = err - } - res.status(500).json({ - error: reason, - message: message - }) - } -}) - -router.post('/trade', async (req, res) => { - /* - POST: /trade - data: { - "base":"UST" - "quote":"KRT" - "side":"buy" or "sell" - "amount":1 - "secret": "mysupersecret" - } - */ - const initTime = Date.now() - - const paramData = getParamData(req.body) - const baseToken = paramData.base - const quoteToken = paramData.quote - const tradeType = paramData.side.toUpperCase() - const amount = parseFloat(paramData.amount) - const gasPrice = parseFloat(paramData.gas_price) || terra.lcd.config.gasPrices.uluna - const gasAdjustment = paramData.gas_adjustment || terra.lcd.config.gasAdjustment - const secret = paramData.privateKey - - let tokenSwaps - - try { - await terra.swapTokens(baseToken, quoteToken, amount, tradeType, gasPrice, gasAdjustment, secret).then((swap) => { - tokenSwaps = swap - }).catch((err) => { - reportConnectionError(res, err) - }) - - const swapResult = { - network: network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseToken, - tradeType: tradeType, - quote: quoteToken, - amount: amount, - } - Object.assign(swapResult, tokenSwaps); - logger.info(`terra.route - ${tradeType}: ${baseToken}-${quoteToken} - Amount: ${amount}`) - res.status(200).json( - swapResult - ) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let message - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - const isAxiosError = err.isAxiosError - if (isAxiosError) { - reason = err.response.status - message = err.response.statusText - } else { - message = err - } - res.status(500).json({ - error: reason, - message: message - }) - } -}) - -module.exports = router; diff --git a/src/routes/uniswap.route.js b/src/routes/uniswap.route.js deleted file mode 100644 index 2ef7b64..0000000 --- a/src/routes/uniswap.route.js +++ /dev/null @@ -1,367 +0,0 @@ -import { ethers } from 'ethers'; -import express from 'express'; - -import { getParamData, latency, statusMessages } from '../services/utils'; -import { logger } from '../services/logger'; -import Ethereum from '../services/eth'; -import Uniswap from '../services/uniswap'; -import Fees from '../services/fees'; - -// require('dotenv').config() - -const debug = require('debug')('router') -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) -const uniswap = new Uniswap(process.env.ETHEREUM_CHAIN) -uniswap.generate_tokens() -setTimeout(uniswap.update_pairs.bind(uniswap), 2000) -const fees = new Fees() - -const swapMoreThanMaxPriceError = 'Price too high' -const swapLessThanMaxPriceError = 'Price too low' - -const estimateGasLimit = () => { - return uniswap.gasLimit -} - -const getErrorMessage = (err) => { - /* - [WIP] Custom error message based-on string match - */ - let message = err - if (err.includes('failed to meet quorum')) { - message = 'Failed to meet quorum in Uniswap' - } else if (err.includes('Invariant failed: ADDRESSES')) { - message = 'Invariant failed: ADDRESSES' - } else if (err.includes('"call revert exception')) { - message = statusMessages.no_pool_available - } else if (err.includes('"trade" is read-only')) { - message = statusMessages.no_pool_available - } - return message -} - -router.post('/', async (req, res) => { - /* - POST / - */ - res.status(200).json({ - network: uniswap.network, - provider: uniswap.provider.connection.url, - uniswap_router: uniswap.router, - connection: true, - timestamp: Date.now(), - }) -}) - -router.post('/gas-limit', async (req, res) => { - /* - POST: /buy-price - */ - const gasLimit = estimateGasLimit() - - try { - res.status(200).json({ - network: uniswap.network, - gasLimit: gasLimit, - timestamp: Date.now(), - }) - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.get('/start', async (req, res) => { - /* - POST: /eth/uniswap/start - x-www-form-urlencoded: { - "pairs":"[ETH-USDT, ...]" - "gasPrice":30 - } - */ - const initTime = Date.now() - const paramData = getParamData(req.query) - const pairs = JSON.parse(paramData.pairs) - let gasPrice - if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) - } else { - gasPrice = fees.ethGasPrice - } - - // get token contract address and cache paths - for (let pair of pairs){ - pair = pair.split("-") - const baseTokenSymbol = pair[0] - const quoteTokenSymbol = pair[1] - const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) - - // check for valid token symbols - if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { - const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol - res.status(500).json({ - error: `Token ${undefinedToken} contract address not found`, - message: `Token contract address not found for ${undefinedToken}. Check token list source`, - }) - return - } - await Promise.allSettled([uniswap.extend_update_pairs([baseTokenContractInfo.address, quoteTokenContractInfo.address])]) - } - - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) - - - const result = { - network: eth.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - success: true, - pairs: pairs, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - } - res.status(200).json(result) -}) - -router.post('/trade', async (req, res) => { - /* - POST: /trade - x-www-form-urlencoded: { - "quote":"BAT" - "base":"DAI" - "amount":0.1 - "limitPrice":1 - "gasPrice":10 - "privateKey":{{privateKey}} - "side":{buy|sell} - } - */ - const initTime = Date.now() - // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) - const amount = paramData.amount - - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() - - let limitPrice - if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice) - } - let gasPrice - if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) - } else { - gasPrice = fees.ethGasPrice - } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) - - try { - // fetch the optimal pool mix from uniswap - const { trade, expectedAmount } = side === 'BUY' - ? await uniswap.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount - ) - : await uniswap.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount - ) - - if (side === 'BUY') { - const price = trade.executionPrice.invert().toSignificant(8) - logger.info(`uniswap.route - Price: ${price.toString()}`) - if (!limitPrice || price <= limitPrice) { - // pass swaps to exchange-proxy to complete trade - const tx = await uniswap.swapExactOut( - wallet, - trade, - baseTokenAddress, - gasPrice, - ) - // submit response - res.status(200).json({ - network: uniswap.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseTokenAddress, - quote: quoteTokenAddress, - amount: amount, - expectedIn: expectedAmount.toSignificant(8), - price: price, - gasPrice: gasPrice, - gasLimit, gasLimit, - gasCost, gasCost, - txHash: tx.hash, - }) - } else { - res.status(200).json({ - error: swapMoreThanMaxPriceError, - message: `Swap price ${price} exceeds limitPrice ${limitPrice}` - }) - logger.info(`uniswap.route - Swap price ${price} exceeds limitPrice ${limitPrice}`) - } - } else { - // sell - const price = trade.executionPrice.toSignificant(8) - logger.info(`Price: ${price.toString()}`) - if (!limitPrice || price >= limitPrice) { - // pass swaps to exchange-proxy to complete trade - const tx = await uniswap.swapExactIn( - wallet, - trade, - baseTokenAddress, - gasPrice, - ) - // submit response - res.status(200).json({ - network: uniswap.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseTokenAddress, - quote: quoteTokenAddress, - amount: parseFloat(paramData.amount), - expectedOut: expectedAmount.toSignificant(8), - price: parseFloat(price), - gasPrice: gasPrice, - gasLimit, gasLimit, - gasCost: gasCost, - txHash: tx.hash, - }) - } else { - res.status(200).json({ - error: swapLessThanMaxPriceError, - message: `Swap price ${price} lower than limitPrice ${limitPrice}` - }) - logger.info(`uniswap.route - Swap price ${price} lower than limitPrice ${limitPrice}`) - } - } - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - res.status(500).json({ - error: reason, - message: err - }) - } -}) - -router.post('/price', async (req, res) => { - /* - POST: /price - x-www-form-urlencoded: { - "quote":"BAT" - "base":"DAI" - "amount":1 - } - */ - const initTime = Date.now() - // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body) - const amount = paramData.amount - - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() - let gasPrice - if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) - } else { - gasPrice = fees.ethGasPrice - } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) - - - try { - // fetch the optimal pool mix from uniswap - const { trade, expectedAmount } = side === 'BUY' - ? await uniswap.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount - ) - : await uniswap.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount - ) - - if (trade !== null && expectedAmount !== null) { - const price = side === 'BUY' - ? trade.executionPrice.invert().toSignificant(8) - : trade.executionPrice.toSignificant(8) - - const tradeAmount = parseFloat(amount) - const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)) - const tradePrice = parseFloat(price) - - const result = { - network: uniswap.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseTokenAddress, - quote: quoteTokenAddress, - amount: tradeAmount, - expectedAmount: expectedTradeAmount, - price: tradePrice, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - trade: trade, - } - debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) - res.status(200).json(result) - } else { // no pool available - res.status(200).json({ - info: statusMessages.no_pool_available, - message: '' - }) - } - } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - let errCode = 500 - if (Object.keys(err).includes('isInsufficientReservesError')) { - errCode = 200 - reason = statusMessages.insufficient_reserves + ' in ' + side + ' at Uniswap' - } else if (Object.getOwnPropertyNames(err).includes('message')) { - reason = getErrorMessage(err.message) - if (reason === statusMessages.no_pool_available) { - errCode = 200 - res.status(errCode).json({ - info: reason, - message: err - }) - } - } else { - err.reason ? reason = err.reason : reason = statusMessages.operation_error - } - res.status(errCode).json({ - error: reason, - message: err - }) - } -}) - -export default router; diff --git a/src/services/access.js b/src/services/access.js deleted file mode 100644 index 708f3aa..0000000 --- a/src/services/access.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - middleware for validating mutual authentication access -*/ - -import { logger } from './logger'; -import { statusMessages } from './utils'; -const debug = require('debug')('router') - -export const validateAccess = (req, res, next) => { - const cert = req.connection.getPeerCertificate() - if (req.client.authorized) { - const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress - const method = req.method - const url = req.url - const requestInfo = 'Request from IP: ' + ip + ' ' + method + ' ' + url - console.log(requestInfo) - next() - } else if (cert.subject) { - logger.error(statusMessages.ssl_cert_invalid) - res.status(403).send({ error: statusMessages.ssl_cert_invalid }) - } else { - logger.error(statusMessages.ssl_cert_required) - res.status(401).send({ error: statusMessages.ssl_cert_required }) - } -} diff --git a/src/services/balancer.js b/src/services/balancer.js deleted file mode 100644 index 375fc7b..0000000 --- a/src/services/balancer.js +++ /dev/null @@ -1,206 +0,0 @@ -import { logger } from '../services/logger'; -const debug = require('debug')('router') -// require('dotenv').config() // DO NOT REMOVE. needed to configure REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor -const sor = require('@balancer-labs/sor') -const BigNumber = require('bignumber.js') -const ethers = require('ethers') -const proxyArtifact = require('../static/ExchangeProxy.json') - -// constants -const MULTI = '0xeefba1e63905ef1d7acba5a8513c70307c1ce441'; -const MULTI_KOVAN = ' 0x2cc8688C5f75E365aaEEb4ea8D6a480405A48D2A'; -const MAX_UINT = ethers.constants.MaxUint256; -const GAS_BASE = process.env.BALANCER_GAS_BASE || 200688; -const GAS_PER_SWAP = process.env.BALANCER_GAS_PER_SWAP || 100000; - -export default class Balancer { - constructor (network = 'kovan') { - const providerUrl = process.env.ETHEREUM_RPC_URL - this.network = process.env.ETHEREUM_CHAIN - this.provider = new ethers.providers.JsonRpcProvider(providerUrl) - this.subgraphUrl = process.env.REACT_APP_SUBGRAPH_URL - this.gasBase = GAS_BASE - this.gasPerSwap = GAS_PER_SWAP - this.maxSwaps = process.env.BALANCER_MAX_SWAPS || 4 - this.exchangeProxy = process.env.EXCHANGE_PROXY; - this.cachedPools = [] - - switch (network) { - case 'mainnet': - this.multiCall = MULTI; - break; - case 'kovan': - this.multiCall = MULTI_KOVAN; - break; - default: - const err = `Invalid network ${network}` - logger.error(err) - throw Error(err) - } - } - - async fetchPool (tokenIn, tokenOut) { - const pools = await sor.getPoolsWithTokens(tokenIn, tokenOut) - this.cachedPools[tokenIn + tokenOut] = pools - - if (pools.pools.length === 0) { - debug('>>> No pools contain the tokens provided.', { message: this.network }); - return {}; - } - debug(`>>> ${pools.pools.length} Pools Retrieved.`, { message: this.network }) - } - - async getCachedPools (tokenIn, tokenOut) { - const cachePools = this.cachedPools[tokenIn + tokenOut].pools - debug(`>>> get cached Pools. ${tokenIn + tokenOut}`, { message: `total pools: ${cachePools.length}` }) - return cachePools - } - - async priceSwapIn (tokenIn, tokenOut, tokenInAmount, maxSwaps = this.maxSwaps) { - // Fetch all the pools that contain the tokens provided - try { - // Get current on-chain data about the fetched pools - await this.fetchPool(tokenIn, tokenOut) - - let poolData - const cachedPools = await this.getCachedPools(tokenIn, tokenOut) - if (this.network === 'mainnet') { - poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider) - } else { - // Kovan multicall throws an ENS error - poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) - } - - // Parse the pools and pass them to smart order outer to get the swaps needed - const sorSwaps = sor.smartOrderRouter( - poolData, // balancers: Pool[] - 'swapExactIn', // swapType: string - tokenInAmount, // targetInputAmount: BigNumber - new BigNumber(maxSwaps.toString()), // maxBalancers: number - 0 // costOutputToken: BigNumber - ) - - const swapsFormatted = sor.formatSwapsExactAmountIn(sorSwaps, MAX_UINT, 0) - const expectedAmount = sor.calcTotalOutput(swapsFormatted, poolData) - debug(`Expected Out: ${expectedAmount.toString()} (${tokenOut})`); - - // Create correct swap format for new proxy - let swaps = []; - for (let i = 0; i < swapsFormatted.length; i++) { - let swap = { - pool: swapsFormatted[i].pool, - tokenIn: tokenIn, - tokenOut: tokenOut, - swapAmount: swapsFormatted[i].tokenInParam, - limitReturnAmount: swapsFormatted[i].tokenOutParam, - maxPrice: swapsFormatted[i].maxPrice.toString(), - }; - swaps.push(swap); - } - return { swaps, expectedAmount } - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error in swapExactOut' - return reason - } - } - - async priceSwapOut (tokenIn, tokenOut, tokenOutAmount, maxSwaps = this.maxSwaps) { - // Fetch all the pools that contain the tokens provided - try { - // Get current on-chain data about the fetched pools - await this.fetchPool(tokenIn, tokenOut) - - let poolData - const cachedPools = await this.getCachedPools(tokenIn, tokenOut) - if (this.network === 'mainnet') { - poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider) - } else { - // Kovan multicall throws an ENS error - poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) - } - - // Parse the pools and pass them to smart order outer to get the swaps needed - const sorSwaps = sor.smartOrderRouter( - poolData, // balancers: Pool[] - 'swapExactOut', // swapType: string - tokenOutAmount, // targetInputAmount: BigNumber - new BigNumber(maxSwaps.toString()), // maxBalancers: number - 0 // costOutputToken: BigNumber - ) - const swapsFormatted = sor.formatSwapsExactAmountOut(sorSwaps, MAX_UINT, MAX_UINT) - const expectedAmount = sor.calcTotalInput(swapsFormatted, poolData) - debug(`Expected In: ${expectedAmount.toString()} (${tokenIn})`); - - // Create correct swap format for new proxy - let swaps = []; - for (let i = 0; i < swapsFormatted.length; i++) { - let swap = { - pool: swapsFormatted[i].pool, - tokenIn: tokenIn, - tokenOut: tokenOut, - swapAmount: swapsFormatted[i].tokenOutParam, - limitReturnAmount: swapsFormatted[i].tokenInParam, - maxPrice: swapsFormatted[i].maxPrice.toString(), - }; - swaps.push(swap); - } - return { swaps, expectedAmount } - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error in swapExactOut' - return reason - } - } - - async swapExactIn (wallet, swaps, tokenIn, tokenOut, amountIn, minAmountOut, gasPrice) { - debug(`Number of swaps: ${swaps.length}`) - try { - const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet) - const tx = await contract.batchSwapExactIn( - swaps, - tokenIn, - tokenOut, - amountIn, - 0, - { - gasPrice: gasPrice * 1e9, - gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP, - } - ) - debug(`Tx Hash: ${tx.hash}`); - return tx - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error in swapExactIn' - return reason - } - } - - async swapExactOut (wallet, swaps, tokenIn, tokenOut, expectedIn, gasPrice) { - debug(`Number of swaps: ${swaps.length}`) - try { - const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet) - const tx = await contract.batchSwapExactOut( - swaps, - tokenIn, - tokenOut, - expectedIn, - { - gasPrice: gasPrice * 1e9, - gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP, - } - ) - debug(`Tx Hash: ${tx.hash}`) - return tx - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error in swapExactOut' - return reason - } - } -} diff --git a/src/services/eth.js b/src/services/eth.js deleted file mode 100644 index 3a9d20e..0000000 --- a/src/services/eth.js +++ /dev/null @@ -1,167 +0,0 @@ -import { logger } from './logger'; -import axios from 'axios' - -const debug = require('debug')('router') -require('dotenv').config() -const fs = require('fs'); -const ethers = require('ethers') -const abi = require('../static/abi') - - -// constants -const APPROVAL_GAS_LIMIT = process.env.ETH_APPROVAL_GAS_LIMIT || 50000; - -export default class Ethereum { - constructor (network = 'mainnet') { - // network defaults to kovan - const providerUrl = process.env.ETHEREUM_RPC_URL - this.provider = new ethers.providers.JsonRpcProvider(providerUrl) - this.erc20TokenListURL = process.env.ETHEREUM_TOKEN_LIST_URL - this.network = network - this.spenders = { - balancer: process.env.EXCHANGE_PROXY, - uniswap: process.env.UNISWAP_ROUTER - } - // update token list - this.getERC20TokenList() // erc20TokenList - } - - // get ETH balance - async getETHBalance (wallet) { - try { - const balance = await wallet.getBalance() - return balance / 1e18.toString() - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error ETH balance lookup' - return reason - } - } - - // get ERC-20 token balance - async getERC20Balance (wallet, tokenAddress, decimals = 18) { - // instantiate a contract and pass in provider for read-only access - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider) - try { - const balance = await contract.balanceOf(wallet.address) - return balance / Math.pow(10, decimals).toString() - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error balance lookup' - return reason - } - } - - // get ERC-20 token allowance - async getERC20Allowance (wallet, spender, tokenAddress, decimals = 18) { - // instantiate a contract and pass in provider for read-only access - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider) - try { - const allowance = await contract.allowance(wallet.address, spender) - return allowance / Math.pow(10, decimals).toString() - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error allowance lookup' - return reason - } - } - - // approve a spender to transfer tokens from a wallet address - async approveERC20 (wallet, spender, tokenAddress, amount, gasPrice = this.gasPrice, gasLimit) { - try { - // fixate gas limit to prevent overwriting - const approvalGasLimit = APPROVAL_GAS_LIMIT - // instantiate a contract and pass in wallet, which act on behalf of that signer - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, wallet) - return await contract.approve( - spender, - amount, { - gasPrice: gasPrice * 1e9, - gasLimit: approvalGasLimit - } - ) - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error approval' - return reason - } - } - - // get current Gas - async getCurrentGasPrice () { - try { - this.provider.getGasPrice().then(function (gas) { - // gasPrice is a BigNumber; convert it to a decimal string - const gasPrice = gas.toString(); - return gasPrice - }) - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error gas lookup' - return reason - } - } - - async deposit (wallet, tokenAddress, amount, gasPrice = this.gasPrice, gasLimit = this.approvalGasLimit) { - // deposit ETH to a contract address - try { - const contract = new ethers.Contract(tokenAddress, abi.KovanWETHAbi, wallet) - return await contract.deposit( - { value: amount, - gasPrice: gasPrice * 1e9, - gasLimit: gasLimit - } - ) - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error deposit' - return reason - } - } - - // get ERC20 Token List - async getERC20TokenList () { - let tokenListSource - try { - if (this.network === 'kovan') { - tokenListSource = 'src/static/erc20_tokens_kovan.json' - this.erc20TokenList = JSON.parse(fs.readFileSync(tokenListSource)) - } else if (this.network === 'mainnet') { - tokenListSource = this.erc20TokenListURL - if (tokenListSource === undefined || tokenListSource === null) { - const errMessage = 'Token List source not found' - logger.error('ERC20 Token List Error', { message: errMessage}) - console.log('eth - Error: ', errMessage) - } - if (this.erc20TokenList === undefined || this.erc20TokenList === null || this.erc20TokenList === {}) { - const response = await axios.get(tokenListSource) - if (response.status === 200 && response.data) { - this.erc20TokenList = response.data - } - } - } else { - throw Error(`Invalid network ${this.network}`) - } - console.log('get ERC20 Token List', this.network, 'source', tokenListSource) - } catch (err) { - console.log(err); - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error ERC 20 Token List' - return reason - } - } - - getERC20TokenAddresses (tokenSymbol) { - const tokenContractAddress = this.erc20TokenList.tokens.filter(obj => { - return obj.symbol === tokenSymbol.toUpperCase() - }) - return tokenContractAddress[0] - } -} diff --git a/src/services/fees.js b/src/services/fees.js deleted file mode 100644 index f987346..0000000 --- a/src/services/fees.js +++ /dev/null @@ -1,53 +0,0 @@ -import { logger } from './logger'; -import axios from 'axios' -import BigNumber from 'bignumber.js' - -//require('dotenv').config() - -const debug = require('debug')('router') -// constants -const ethGasStationHost = 'https://ethgasstation.info' -const ethGasStationEnabled = process.env.ENABLE_ETH_GAS_STATION || false -const ethGasStationApiKey = process.env.ETH_GAS_STATION_API_KEY -const ethManualGasPrice = parseInt(process.env.MANUAL_GAS_PRICE) -const ethGasStationURL = ethGasStationHost + '/api/ethgasAPI.json?api-key=' + ethGasStationApiKey -const defaultRefreshInterval = 120 -const denom = BigNumber('1e+9') - -export default class Fees { - constructor () { - this.ethGasStationGasLevel = process.env.ETH_GAS_STATION_GAS_LEVEL - this.ethGasStationRefreshTime = (process.env.ETH_GAS_STATION_REFRESH_TIME || defaultRefreshInterval) * 1000 - this.getETHGasStationFee(this.ethGasStationGasLevel, 0) - } - - // get ETH Gas Station - async getETHGasStationFee (gasLevel = this.ethGasStationGasLevel, interval = defaultRefreshInterval) { - try { - if (ethGasStationEnabled === true || ethGasStationEnabled.toLowerCase() === 'true') { - const response = await axios.get(ethGasStationURL) - // divite by 10 to convert it to Gwei) - this.ethGasPrice = response.data[gasLevel] / 10 - console.log(`get ETHGasStation gas price (${gasLevel}): ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) - } else { - this.ethGasPrice = ethManualGasPrice - console.log(`get manual fixed gas price: ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) - } - } catch (err) { - console.log(err); - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error ETH gas fee lookup' - return reason - } - if (interval > 0) { // set to '0' for one-time retrieval - setTimeout(this.getETHGasStationFee.bind(this), this.ethGasStationRefreshTime); // update every x seconds - } - } - - // get gas cost - async getGasCost (gasPrice, gasLimit, inGwei = false) { - const cost = gasPrice * gasLimit - return inGwei ? cost : cost / denom - } -} diff --git a/src/services/logger.js b/src/services/logger.js deleted file mode 100644 index eca9d94..0000000 --- a/src/services/logger.js +++ /dev/null @@ -1,44 +0,0 @@ -import { getLocalDate } from './utils' -// require('dotenv').config() -const appRoot = require('app-root-path') -const winston = require('winston') -require('winston-daily-rotate-file'); - -const logFormat = winston.format.combine( - winston.format.timestamp(), - winston.format.align(), - winston.format.printf( - info => { - const localDate = getLocalDate() - return `${localDate} | ${info.level} | ${info.message}` - } - ), -) - -const getLogPath = () => { - let logPath = process.env.LOG_PATH - if (typeof logPath === 'undefined' || logPath == null || logPath === '') { - logPath = [appRoot.path, 'logs'].join('/') - } - return logPath -} - -const config = { - file: { - level: 'info', - filename: `${getLogPath()}/logs_gateway_app.log.%DATE%`, - datePattern: 'YYYY-MM-DD', - handleExceptions: true, - handleRejections: true - } -} - -const allLogsFileTransport = new winston.transports.DailyRotateFile(config.file) - -const options = { - format: logFormat, - transports: [allLogsFileTransport], - exitOnError: false, -} - -export const logger = winston.createLogger(options) diff --git a/src/services/perpetual_finance.js b/src/services/perpetual_finance.js deleted file mode 100644 index f2d482e..0000000 --- a/src/services/perpetual_finance.js +++ /dev/null @@ -1,298 +0,0 @@ -import { logger } from './logger'; - -const fetch = require('cross-fetch'); - -const Ethers = require('ethers') -const AmmArtifact = require("@perp/contract/build/contracts/Amm.json") -const ClearingHouseArtifact = require("@perp/contract/build/contracts/ClearingHouse.json") -const RootBridgeArtifact = require("@perp/contract/build/contracts/RootBridge.json") -const ClientBridgeArtifact = require("@perp/contract/build/contracts/ClientBridge.json") -const ClearingHouseViewerArtifact = require("@perp/contract/build/contracts/ClearingHouseViewer.json") -const TetherTokenArtifact = require("@perp/contract/build/contracts/TetherToken.json") - -const GAS_LIMIT = 2123456; -const DEFAULT_DECIMALS = 18; -const CONTRACT_ADDRESSES = 'https://metadata.perp.exchange/'; -const XDAI_PROVIDER = process.env.XDAI_PROVIDER || 'https://dai.poa.network'; -const PNL_OPTION_SPOT_PRICE = 0; -const UPDATE_PERIOD = 60000; // stop updating prices after 30 secs from last request - - -export default class PerpetualFinance { - constructor (network = 'mainnet') { - this.providerUrl = XDAI_PROVIDER - this.network = network - this.provider = new Ethers.providers.JsonRpcProvider(this.providerUrl) - this.gasLimit = GAS_LIMIT - this.contractAddressesUrl = CONTRACT_ADDRESSES - this.amm = {} - this.priceCache = {} - this.cacheExpirary = {} - this.pairAmountCache = {} - - - switch (network) { - case 'mainnet': - this.contractAddressesUrl += 'production.json'; - break; - case 'kovan': - this.contractAddressesUrl += 'staging.json'; - break; - default: - const err = `Invalid network ${network}` - logger.error(err) - throw Error(err) - } - - this.loadedMetadata = this.load_metadata() - - } - - async load_metadata() { - try{ - const metadata = await fetch(this.contractAddressesUrl).then(res => res.json()) - const layer2 = Object.keys(metadata.layers.layer2.contracts) - - for (var key of layer2){ - if (metadata.layers.layer2.contracts[key].name === "Amm") { - this.amm[key] = metadata.layers.layer2.contracts[key].address; - } else{ - this[key] = metadata.layers.layer2.contracts[key].address; - } - } - - this.layer2AmbAddr = metadata.layers.layer2.externalContracts.ambBridgeOnXDai - this.xUsdcAddr = metadata.layers.layer2.externalContracts.usdc - this.loadedMetadata = true - return true - } catch(err) { - return false - } - - } - - async update_price_loop() { - if (Object.keys(this.cacheExpirary).length > 0) { - for (let pair in this.cacheExpirary){ - if (this.cacheExpirary[pair] <= Date.now()) { - delete this.cacheExpirary[pair]; - delete this.priceCache[pair]; - } - } - - for (let pair in this.cacheExpirary){ - let amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider) - await Promise.allSettled([amm.getInputPrice(0, {d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) }), - amm.getOutputPrice(0, {d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) })]) - .then(values => {if (!this.priceCache.hasOwnProperty(pair)) { this.priceCache[pair] = [] }; - this.priceCache[pair][0] = this.pairAmountCache[pair] / Ethers.utils.formatUnits(values[0].value.d); - this.priceCache[pair][1] = Ethers.utils.formatUnits(values[1].value.d) / this.pairAmountCache[pair];})} - - } - setTimeout(this.update_price_loop.bind(this), 10000); // update every 10 seconds - } - - // get XDai balance - async getXdaiBalance (wallet) { - try { - const xDaiBalance = await wallet.getBalance() - return Ethers.utils.formatEther(xDaiBalance) - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error xDai balance lookup' - return reason - } - } - - // get XDai USDC balance - async getUSDCBalance (wallet) { - try { - const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet) - let layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address) - const layer2UsdcDecimals = await layer2Usdc.decimals() - return Ethers.utils.formatUnits(layer2UsdcBalance, layer2UsdcDecimals) - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error balance lookup' - return reason - } - } - - // get allowance - async getAllowance (wallet) { - // instantiate a contract and pass in provider for read-only access - const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet) - - try { - const allowanceForClearingHouse = await layer2Usdc.allowance( - wallet.address, - this.ClearingHouse - ) - - return Ethers.utils.formatUnits(allowanceForClearingHouse, DEFAULT_DECIMALS) - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error allowance lookup' - return reason - } - } - - // approve - async approve (wallet, amount) { - try { - // instantiate a contract and pass in wallet - const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet) - const tx = await layer2Usdc.approve(this.ClearingHouse, Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS)) - // TO-DO: We may want to supply custom gasLimit value above - return tx.hash - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error approval' - return reason - } - } - - //open Position - async openPosition(side, margin, levrg, pair, minBaseAmount, wallet) { - try { - const quoteAssetAmount = { d: Ethers.utils.parseUnits(margin, DEFAULT_DECIMALS) } - const leverage = { d: Ethers.utils.parseUnits(levrg, DEFAULT_DECIMALS) } - const minBaseAssetAmount = { d: Ethers.utils.parseUnits(minBaseAmount, DEFAULT_DECIMALS) } - const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet) - const tx = await clearingHouse.openPosition( - this.amm[pair], - side, - quoteAssetAmount, - leverage, - minBaseAssetAmount, - { gasLimit: this.gasLimit } - ) - return tx - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error opening position' - return reason - } - } - - //close Position - async closePosition(wallet, pair, minimalQuote) { - try { - const minimalQuoteAsset = { d: Ethers.utils.parseUnits(minimalQuote, DEFAULT_DECIMALS) } - const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet) - const tx = await clearingHouse.closePosition(this.amm[pair], minimalQuoteAsset, { gasLimit: this.gasLimit } ) - return tx - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error closing position' - return reason - } - } - - //get active position - async getPosition(wallet, pair) { - try { - const positionValues = {} - const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet) - let premIndex = 0 - await Promise.allSettled([clearingHouse.getPosition(this.amm[pair], - wallet.address), - clearingHouse.getLatestCumulativePremiumFraction(this.amm[pair]), - clearingHouse.getPositionNotionalAndUnrealizedPnl(this.amm[pair], - wallet.address, - Ethers.BigNumber.from(PNL_OPTION_SPOT_PRICE))]) - .then(values => {positionValues.openNotional = Ethers.utils.formatUnits(values[0].value.openNotional.d, DEFAULT_DECIMALS); - positionValues.size = Ethers.utils.formatUnits(values[0].value.size.d, DEFAULT_DECIMALS); - positionValues.margin = Ethers.utils.formatUnits(values[0].value.margin.d, DEFAULT_DECIMALS); - positionValues.cumulativePremiumFraction = Ethers.utils.formatUnits(values[0].value.lastUpdatedCumulativePremiumFraction.d, DEFAULT_DECIMALS); - premIndex = Ethers.utils.formatUnits(values[1].value.d, DEFAULT_DECIMALS); - positionValues.pnl = Ethers.utils.formatUnits(values[2].value.unrealizedPnl.d, DEFAULT_DECIMALS); - positionValues.positionNotional = Ethers.utils.formatUnits(values[2].value.positionNotional.d, DEFAULT_DECIMALS);}) - - positionValues.entryPrice = Math.abs(positionValues.openNotional / positionValues.size) - positionValues.fundingPayment = (premIndex - positionValues.cumulativePremiumFraction) * positionValues.size // * -1 - return positionValues - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error getting active position' - return reason - } - } - - //get active margin - async getActiveMargin(wallet) { - try { - const clearingHouseViewer = new Ethers.Contract(this.ClearingHouseViewer, ClearingHouseViewerArtifact.abi, wallet) - const activeMargin = await clearingHouseViewer.getPersonalBalanceWithFundingPayment( - this.xUsdcAddr, - wallet.address) - return activeMargin / 1e18.toString() - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error getting active position' - return reason - } - } - - // get Price - async getPrice(side, amount, pair) { - try { - let price - this.cacheExpirary[pair] = Date.now() + UPDATE_PERIOD - this.pairAmountCache[pair] = amount - if (!this.priceCache.hasOwnProperty(pair)){ - const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider) - if (side === "buy") { - price = await amm.getInputPrice(0, {d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }) - price = amount / Ethers.utils.formatUnits(price.d) - } else { - price = await amm.getOutputPrice(0, {d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }) - price = Ethers.utils.formatUnits(price.d) / amount - } - } else { - if (side === "buy") { - price = this.priceCache[pair][0] - } else { price = this.priceCache[pair][1] } - } - return price - } catch (err) { - console.log(err) - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error getting Price' - return reason - } - } - - // get getFundingRate - async getFundingRate(pair) { - try { - let funding = {} - const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider) - await Promise.allSettled([amm.getUnderlyingTwapPrice(3600), - amm.getTwapPrice(3600), - amm.nextFundingTime()]) - .then(values => {funding.indexPrice = parseFloat(Ethers.utils.formatUnits(values[0].value.d)); - funding.markPrice = parseFloat(Ethers.utils.formatUnits(values[1].value.d)); - funding.nextFundingTime = parseInt(values[2].value.toString());}) - - funding.rate = ((funding.markPrice - funding.indexPrice) / 24) / funding.indexPrice - return funding - } catch (err) { - console.log(err) - logger.error(err)() - let reason - err.reason ? reason = err.reason : reason = 'error getting fee' - return reason - } - } - -} diff --git a/src/services/terra.js b/src/services/terra.js deleted file mode 100644 index ef17ba9..0000000 --- a/src/services/terra.js +++ /dev/null @@ -1,316 +0,0 @@ -import { logger } from './logger'; -import { LCDClient, Coin, MsgSwap, StdTx, StdFee, Dec, MnemonicKey, isTxError, Coins } from '@terra-money/terra.js' -import BigNumber from 'bignumber.js' -import { getHummingbotMemo } from './utils'; - -const debug = require('debug')('router') -// require('dotenv').config() - -// constants -const TERRA_TOKENS = { - uluna: { symbol: 'LUNA' }, - uusd: { symbol: 'UST' }, - ukrw: { symbol: 'KRT' }, - usdr: { symbol: 'SDT' }, - umnt: { symbol: 'MNT' }, -} -const DENOM_UNIT = BigNumber('1e+6') -const TOBIN_TAX = 0.0025 // a Tobin Tax (set at 0.25%) for spot-converting Terra<>Terra swaps -const MIN_SPREAD = 0.02 // a minimum spread (set at 2%) for Terra<>Luna swaps -const GAS_PRICE = { uluna: 0.16 } -const GAS_ADJUSTMENT = 1.4 - -export default class Terra { - constructor () { - this.lcdUrl = process.env.TERRA_LCD_URL; - this.network = process.env.TERRA_CHAIN; - this.tokens = TERRA_TOKENS - this.denomUnitMultiplier = DENOM_UNIT - this.tobinTax = TOBIN_TAX - this.minSpread = MIN_SPREAD - this.memo = getHummingbotMemo() - - try { - this.lcd = this.connect() - - this.lcd.market.parameters().catch(() => { - throw new Error('Connection error') - }) - // set gas & fee - this.lcd.config.gasAdjustment = GAS_ADJUSTMENT - this.lcd.config.gasPrices = GAS_PRICE - } catch (err) { - logger.error(err) - throw Error(`Connection failed: ${this.network}`) - } - } - - // connect Terra LCD - connect () { - try { - const lcd = new LCDClient({ - URL: this.lcdUrl, - chainID: this.network, - }) - lcd.config.gasAdjustment = GAS_ADJUSTMENT - lcd.config.gasPrices = GAS_PRICE - return lcd - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra LCD connect' - return reason - } - } - - // get Token Denom - getTokenDenom (symbol) { - try { - let denom - Object.keys(TERRA_TOKENS).forEach((item) => { - if (TERRA_TOKENS[item].symbol === symbol) { - denom = item - } - }) - return denom - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra Denom lookup' - return reason - } - } - - // get Token Symbol - getTokenSymbol (denom) { - try { - const symbol = TERRA_TOKENS[denom].symbol - return symbol - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra Denom lookup' - return reason - } - } - - getTxAttributes (attributes) { - let attrib = {} - attributes.forEach((item) => { - attrib[item.key] = item.value - }) - return attrib - } - - async getEstimateFee (tx) { - try { - const fee = await this.lcd.tx.estimateFee(tx) - return fee - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra estimate fee lookup' - return reason - } - } - - async getExchangeRate (denom) { - try { - const exchangeRates = await this.lcd.oracle.exchangeRates() - return exchangeRates.get(denom) - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup' - return reason - } - } - - async getTxFee () { - try { - const lunaFee = GAS_PRICE.uluna * GAS_ADJUSTMENT - let feeList = { uluna: lunaFee } - await this.lcd.oracle.exchangeRates().then(rates => { - Object.keys(rates._coins).forEach(key => { - feeList[key] = rates._coins[key].amount * lunaFee - }) - }) - debug('lunaFee', lunaFee, feeList) - - return feeList - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup' - return reason - } - } - - // get Terra Swap Rate - async getSwapRate (baseToken, quoteToken, amount, tradeType) { - try { - let exchangeRate, offerCoin, offerDenom, swapDenom, cost, costAmount, offer - let swaps = {} - - if (tradeType.toLowerCase() === 'sell') { - // sell base - offerDenom = this.getTokenDenom(baseToken) - swapDenom = this.getTokenDenom(quoteToken) - - offerCoin = new Coin(offerDenom, amount * DENOM_UNIT); - await this.lcd.market.swapRate(offerCoin, swapDenom).then(swapCoin => { - offer = { amount: amount } - exchangeRate = { - amount: (swapCoin.amount / DENOM_UNIT) / amount, - token: quoteToken - } - costAmount = amount * exchangeRate.amount - cost = { - amount: costAmount, - token: quoteToken - } - }) - } else { - // buy base - offerDenom = this.getTokenDenom(quoteToken) - swapDenom = this.getTokenDenom(baseToken) - - offerCoin = new Coin(offerDenom, 1 * DENOM_UNIT); - await this.lcd.market.swapRate(offerCoin, swapDenom).then(swapCoin => { - exchangeRate = { - amount: (amount / parseInt(swapCoin.amount) * DENOM_UNIT) / amount, // adjusted amount - token: quoteToken - } - costAmount = amount * exchangeRate.amount - cost = { - amount: costAmount, - token: quoteToken - } - offer = { amount: cost.amount } - }) - } - - let txFee - await this.getTxFee().then(fee => { - // fee in quote - txFee = { amount: parseFloat(fee[this.getTokenDenom(quoteToken)]), token: quoteToken } - }) - - swaps.offer = offer - swaps.price = exchangeRate - swaps.cost = cost - swaps.txFee = txFee - debug('swaps', swaps) - return swaps - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error swap rate lookup' - return reason - } - } - - // Swap tokens - async swapTokens (baseToken, quoteToken, amount, tradeType, gasPrice, gasAdjustment, secret) { - let swapResult - try { - // connect to lcd - const lcd = this.connect() - - const mk = new MnemonicKey({ - mnemonic: secret, - }); - let wallet - try { - wallet = lcd.wallet(mk); - } catch (err) { - logger.error(err) - throw Error('Wallet access error') - } - - const address = wallet.key.accAddress - - // get the current swap rate - const baseDenom = this.getTokenDenom(baseToken) - const quoteDenom = this.getTokenDenom(quoteToken) - - let offerDenom, swapDenom - let swaps, txAttributes - let tokenSwap = {} - - if (tradeType.toLowerCase() === 'sell') { - offerDenom = baseDenom - swapDenom = quoteDenom - } else { - offerDenom = quoteDenom - swapDenom = baseDenom - } - - await this.getSwapRate(baseToken, quoteToken, amount, tradeType, secret).then((rate) => { - swaps = rate - }) - - const offerAmount = parseInt((swaps.offer.amount) * DENOM_UNIT) - const offerCoin = new Coin(offerDenom, offerAmount) - - // Create and Sign Transaction - const msgSwap = new MsgSwap(address, offerCoin, swapDenom); - - let txOptions - if (gasPrice !== null && gasPrice !== null) { // ignore gasAdjustment when gasPrice is not set - txOptions = { - msgs: [msgSwap], - gasPrices: { uluna: parseFloat(gasPrice) }, - gasAdjustment: gasAdjustment, - memo: this.memo - } - } else { - txOptions = { - msgs: [msgSwap], - memo: this.memo - } - } - - await wallet.createAndSignTx(txOptions).then(tx => lcd.tx.broadcast(tx)).then((txResult) => { - swapResult = txResult - - const swapSuccess = !isTxError(txResult) - if (swapSuccess) { - tokenSwap.txSuccess = swapSuccess - } else { - tokenSwap.txSuccess = !swapSuccess - throw new Error(`encountered an error while running the transaction: ${txResult.code} ${txResult.codespace}`); - } - const txHash = txResult.txhash - const events = JSON.parse(txResult.raw_log)[0].events - const swap = events.find(obj => { - return obj.type === 'swap' - }) - txAttributes = this.getTxAttributes(swap.attributes) - const offer = Coin.fromString(txAttributes.offer) - const ask = Coin.fromString(txAttributes.swap_coin) - const fee = Coin.fromString(txAttributes.swap_fee) - - tokenSwap.expectedIn = { - amount: parseFloat(offer.amount) / DENOM_UNIT, - token: TERRA_TOKENS[offer.denom].symbol - } - tokenSwap.expectedOut = { - amount: parseFloat(ask.amount) / DENOM_UNIT, - token: TERRA_TOKENS[ask.denom].symbol - } - tokenSwap.fee = { - amount: parseFloat(fee.amount) / DENOM_UNIT, - token: TERRA_TOKENS[fee.denom].symbol - } - tokenSwap.txHash = txHash - }) - return tokenSwap - } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = swapResult - return { txSuccess: false, message: reason } - } - } -} diff --git a/src/services/uniswap.js b/src/services/uniswap.js deleted file mode 100644 index 8fe7bbb..0000000 --- a/src/services/uniswap.js +++ /dev/null @@ -1,217 +0,0 @@ -import { logger } from './logger'; - -const debug = require('debug')('router') -const math = require('mathjs') -const uni = require('@uniswap/sdk') -const ethers = require('ethers') -const proxyArtifact = require('../static/uniswap_v2_router_abi.json') -const routeTokens = require('../static/uniswap_route_tokens.json') - -// constants -const ROUTER = process.env.UNISWAP_ROUTER -const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 150688; -const TTL = process.env.UNISWAP_TTL || 300; -const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request - -export default class Uniswap { - constructor (network = 'mainnet') { - this.providerUrl = process.env.ETHEREUM_RPC_URL - this.network = process.env.ETHEREUM_CHAIN - this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) - this.router = ROUTER; - this.slippage = math.fraction(process.env.UNISWAP_ALLOWED_SLIPPAGE) - this.allowedSlippage = new uni.Percent(this.slippage.n, (this.slippage.d * 100)) - this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME - this.gasLimit = GAS_LIMIT - this.expireTokenPairUpdate = UPDATE_PERIOD - this.zeroReserveCheckInterval = process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL - this.zeroReservePairs = {} // No reserve pairs - this.tokenList = {} - this.pairs = [] - this.tokenSwapList = {} - this.cachedRoutes = {} - - switch (network) { - case 'mainnet': - this.chainID = uni.ChainId.MAINNET; - break; - case 'kovan': - this.chainID = uni.ChainId.KOVAN; - break; - default: - const err = `Invalid network ${network}` - logger.error(err) - throw Error(err) - } - } - - async fetch_route(tIn, tOut){ - var route, pair, pairOne, pairTwo - - try { - pair = await uni.Fetcher.fetchPairData(tIn, tOut); - route = new uni.Route([pair], tIn, tOut); - } - catch(err) { - logger.error(err); - } - return route; - } - - - generate_tokens(){ - for (let token of routeTokens[this.network]){ - this.tokenList[token["address"]] = new uni.Token(this.chainID, token["address"], token["decimals"], token["symbol"], token["name"]); - } - } - - async extend_update_pairs(tokens=[]){ - for (let token of tokens){ - if (!this.tokenList.hasOwnProperty(token)){ - this.tokenList[token] = await uni.Fetcher.fetchTokenData(this.chainID, token); - } - this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate; - } - } - - async update_pairs(){ - // Remove banned pairs after ban period - if (Object.keys(this.zeroReservePairs).length > 0){ - for (let pair in this.zeroReservePairs){ - if (this.zeroReservePairs[pair] <= Date.now()) { - delete this.zeroReservePairs[pair]; - // delete this.tokenList[token]; - } - } - } - // Generate all possible pair combinations of tokens - // This is done by generating an upper triangular matrix or right triangular matrix - if (Object.keys(this.tokenSwapList).length > 0){ - for (let token in this.tokenSwapList){ - if (this.tokenSwapList[token] <= Date.now()) { - delete this.tokenSwapList[token]; - // delete this.tokenList[token]; - } - } - - let tokens = Object.keys(this.tokenList); - var firstToken, secondToken, position; - let length = tokens.length; - let pairs = []; - let pairAddressRequests = []; - let pairAddressResponses = []; - for (firstToken = 0; firstToken < length; firstToken++){ - for (secondToken = firstToken + 1; secondToken < length; secondToken++){ - try{ - let pairString = this.tokenList[tokens[firstToken]].address + '-' + this.tokenList[tokens[secondToken]].address; - if (!this.zeroReservePairs.hasOwnProperty(pairString)){ - pairs.push(pairString); - pairAddressRequests.push(uni.Fetcher.fetchPairData(this.tokenList[tokens[firstToken]], this.tokenList[tokens[secondToken]])); - } - } - catch(err) { - logger.error(err); - } - } - } - - await Promise.allSettled(pairAddressRequests).then(values => { for (position = 0; position < pairAddressRequests.length; position++) { - if (values[position].status === "fulfilled"){pairAddressResponses.push(values[position].value)} - else {this.zeroReservePairs[pairs[position]] = Date.now() + this.zeroReserveCheckInterval;}}}) - this.pairs = pairAddressResponses; - } - setTimeout(this.update_pairs.bind(this), 1000); - } - - async priceSwapIn (tokenIn, tokenOut, tokenInAmount) { - await this.extend_update_pairs([tokenIn, tokenOut]); - const tIn = this.tokenList[tokenIn]; - const tOut = this.tokenList[tokenOut]; - const tokenAmountIn = new uni.TokenAmount(tIn, ethers.utils.parseUnits(tokenInAmount, tIn.decimals)); - if (this.pairs.length === 0){ - const route = await this.fetch_route(tIn, tOut); - const trade = uni.Trade.exactIn(route, tokenAmountIn); - if ( trade !== undefined ){ - const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; - return { trade, expectedAmount } - } - return "Can't find route to swap, kindly update " - } - const trade = uni.Trade.bestTradeExactIn(this.pairs, tokenAmountIn, this.tokenList[tokenOut], { maxHops: 5 })[0]; - if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} - else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} - const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); - return { trade, expectedAmount } - } - - async priceSwapOut (tokenIn, tokenOut, tokenOutAmount) { - await this.extend_update_pairs([tokenIn, tokenOut]); - const tOut = this.tokenList[tokenOut]; - const tIn = this.tokenList[tokenIn]; - const tokenAmountOut = new uni.TokenAmount(tOut, ethers.utils.parseUnits(tokenOutAmount, tOut.decimals)); - if (this.pairs.length === 0){ - const route = await this.fetch_route(tIn, tOut); - const trade = uni.Trade.exactOut(route, tokenAmountOut); - if ( trade !== undefined ){ - const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; - return { trade, expectedAmount } - } - return - } - const trade = uni.Trade.bestTradeExactOut(this.pairs, this.tokenList[tokenIn], tokenAmountOut, { maxHops: 5 })[0]; - if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} - else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} - const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); - return { trade, expectedAmount } - } - - async swapExactIn (wallet, trade, tokenAddress, gasPrice) { - const result = uni.Router.swapCallParameters( - trade, - { - ttl: TTL, - recipient: wallet.address, - allowedSlippage: this.allowedSlippage - } - ) - - const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) - const tx = await contract.[result.methodName]( - ...result.args, - { - gasPrice: gasPrice * 1e9, - gasLimit: GAS_LIMIT, - value: result.value - } - ) - - debug(`Tx Hash: ${tx.hash}`); - return tx - } - - async swapExactOut (wallet, trade, tokenAddress, gasPrice) { - const result = uni.Router.swapCallParameters( - trade, - { - ttl: TTL, - recipient: wallet.address, - allowedSlippage: this.allowedSlippage - } - ) - - const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) - const tx = await contract.[result.methodName]( - ...result.args, - { - gasPrice: gasPrice * 1e9, - gasLimit: GAS_LIMIT, - value: result.value - } - ) - - debug(`Tx Hash: ${tx.hash}`); - return tx - } -} diff --git a/src/services/utils.js b/src/services/utils.js deleted file mode 100644 index 23182cc..0000000 --- a/src/services/utils.js +++ /dev/null @@ -1,110 +0,0 @@ -/* - Hummingbot Utils -*/ -const lodash = require('lodash') -const moment = require('moment') - -export const statusMessages = { - ssl_cert_required: 'SSL Certificate required', - ssl_cert_invalid: 'Invalid SSL Certificate', - operation_error: 'Operation Error', - no_pool_available: 'No Pool Available', - invalid_token_symbol: 'Invalid Token Symbol', - insufficient_reserves: 'Insufficient Liquidity Reserves', - page_not_found: 'Page not found. Invalid path', -} - -export const latency = (startTime, endTime) => parseFloat((endTime - startTime) / 1000) - -export const isValidParams = (params) => { - const values = Object.values(params) - for (let i = 0; i < values.length; i++) { // DO NOT use forEach, it returns callback without breaking the loop - if (typeof values[i] === 'undefined') { - throw new Error('Invalid input params') - } - } - return true -} - -export const isValidData = (data, format) => { - if (typeof data !== 'undefined' && Object.keys(data).length !== 0 && lodash.isEqual(Object.keys(data).sort(), format.sort())) { - return true - } - return false -} - -export const getParamData = (data, format = null) => { - const dataObject = {} - if (format !== null) { - if (isValidData(data, format)) { - format.forEach((key, index) => { - dataObject[key] = data[key] - }) - } - } else { - Object.keys(data).forEach((key, index) => { - dataObject[key] = data[key] - }) - } - return dataObject -} - -export const splitParamData = (param, separator = ',') => { - const dataArray = param.split(separator) - return dataArray -} - -export const getSymbols = (tradingPair) => { - const symbols = tradingPair.split('-') - const baseQuotePair = { - base: symbols[0].toUpperCase(), - quote: symbols[1].toUpperCase() - } - return baseQuotePair -} - -export const reportConnectionError = (res, error) => { - res.json({ - error: error.errno, - code: error.code, - }) -} - -export const strToDecimal = (str) => parseInt(str) / 100; - -export const getHummingbotMemo = () => { - const prefix = 'hbot' - const clientId = process.env.HUMMINGBOT_INSTANCE_ID - if ((typeof clientId !== 'undefined' && clientId != null) && clientId !== '') { - return [prefix, clientId].join('-') - } - return prefix -} - -export const loadConfig = () => { - const config = { - ethereum_rpc_url: process.env.ETHEREUM_RPC_URL, - ethereum_chain: process.env.ETHEREUM_CHAIN, - exchange_proxy: process.env.EXCHANGE_PROXY, - ethereum_token_list_url: process.env.ETHEREUM_TOKEN_LIST_URL, - enable_eth_gas_station: process.env.ENABLE_ETH_GAS_STATION != null ? (process.env.ENABLE_ETH_GAS_STATION.toLowerCase() == 'true') : false, - eth_gas_station_gas_level: process.env.ETH_GAS_STATION_GAS_LEVEL, - eth_gas_station_refresh_time: process.env.ETH_GAS_STATION_REFRESH_TIME != null ? parseFloat(process.env.ETH_GAS_STATION_REFRESH_TIME) : null, - manual_gas_price: process.env.MANUAL_GAS_PRICE != null ? parseFloat(process.env.MANUAL_GAS_PRICE) : null, - react_app_subgraph_url: process.env.REACT_APP_SUBGRAPH_URL, - balancer_max_swaps: process.env.BALANCER_MAX_SWAPS != null ? parseInt(process.env.BALANCER_MAX_SWAPS) : null, - uniswap_router: process.env.UNISWAP_ROUTER, - terra_lcd_url: process.env.TERRA_LCD_URL, - terra_chain: process.env.TERRA_CHAIN - } - return config -} - -export const getLocalDate = () => { - const gmtOffset = process.env.GMT_OFFSET - let newDate = moment().format('YYYY-MM-DD hh:mm:ss').trim() - if (typeof gmtOffset !== 'undefined' && gmtOffset !== null && gmtOffset !== '') { - newDate = moment().utcOffset(gmtOffset, false).format('YYYY-MM-DD hh:mm:ss').trim() - } - return newDate -} diff --git a/src/static/ExchangeProxy.json b/src/static/ExchangeProxy.json deleted file mode 100644 index 0e5d20b..0000000 --- a/src/static/ExchangeProxy.json +++ /dev/null @@ -1,624 +0,0 @@ -{ - "contractName": "ExchangeProxy", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_weth", - "type": "address" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "constant": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limitReturnAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPrice", - "type": "uint256" - } - ], - "internalType": "struct ExchangeProxy.Swap[]", - "name": "swaps", - "type": "tuple[]" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "totalAmountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minTotalAmountOut", - "type": "uint256" - } - ], - "name": "batchSwapExactIn", - "outputs": [ - { - "internalType": "uint256", - "name": "totalAmountOut", - "type": "uint256" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limitReturnAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPrice", - "type": "uint256" - } - ], - "internalType": "struct ExchangeProxy.Swap[]", - "name": "swaps", - "type": "tuple[]" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxTotalAmountIn", - "type": "uint256" - } - ], - "name": "batchSwapExactOut", - "outputs": [ - { - "internalType": "uint256", - "name": "totalAmountIn", - "type": "uint256" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "isOwner", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limitReturnAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPrice", - "type": "uint256" - } - ], - "internalType": "struct ExchangeProxy.Swap[][]", - "name": "swapSequences", - "type": "tuple[][]" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "totalAmountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minTotalAmountOut", - "type": "uint256" - } - ], - "name": "multihopBatchSwapExactIn", - "outputs": [ - { - "internalType": "uint256", - "name": "totalAmountOut", - "type": "uint256" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limitReturnAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPrice", - "type": "uint256" - } - ], - "internalType": "struct ExchangeProxy.Swap[][]", - "name": "swapSequences", - "type": "tuple[][]" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxTotalAmountIn", - "type": "uint256" - } - ], - "name": "multihopBatchSwapExactOut", - "outputs": [ - { - "internalType": "uint256", - "name": "totalAmountIn", - "type": "uint256" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_registry", - "type": "address" - } - ], - "name": "setRegistry", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "contract TokenInterface", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "totalAmountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minTotalAmountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "nPools", - "type": "uint256" - } - ], - "name": "smartSwapExactIn", - "outputs": [ - { - "internalType": "uint256", - "name": "totalAmountOut", - "type": "uint256" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "contract TokenInterface", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "contract TokenInterface", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "totalAmountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxTotalAmountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "nPools", - "type": "uint256" - } - ], - "name": "smartSwapExactOut", - "outputs": [ - { - "internalType": "uint256", - "name": "totalAmountIn", - "type": "uint256" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "nPools", - "type": "uint256" - } - ], - "name": "viewSplitExactIn", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limitReturnAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPrice", - "type": "uint256" - } - ], - "internalType": "struct ExchangeProxy.Swap[]", - "name": "swaps", - "type": "tuple[]" - }, - { - "internalType": "uint256", - "name": "totalOutput", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "nPools", - "type": "uint256" - } - ], - "name": "viewSplitExactOut", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limitReturnAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPrice", - "type": "uint256" - } - ], - "internalType": "struct ExchangeProxy.Swap[]", - "name": "swaps", - "type": "tuple[]" - }, - { - "internalType": "uint256", - "name": "totalOutput", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x60806040523480156200001157600080fd5b506040516200358a3803806200358a8339810160408190526200003491620000d0565b6000620000496001600160e01b03620000b916565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b0319166001600160a01b039290921691909117905562000125565b3390565b8051620000ca816200010b565b92915050565b600060208284031215620000e357600080fd5b6000620000f18484620000bd565b949350505050565b60006001600160a01b038216620000ca565b6200011681620000f9565b81146200012257600080fd5b50565b61345580620001356000396000f3fe6080604052600436106100c25760003560e01c80638743ad581161007f578063a91ee0dc11610059578063a91ee0dc146101cd578063b40f39ee146101ed578063e2b3974614610200578063f2fde38b14610213576100c2565b80638743ad58146101765780638da5cb5b146101895780638f32d59b146101ab576100c2565b806321b0eb85146100c45780632db58134146100ed578063368bb1fc146101005780634b0f93fb1461012e578063715018a61461014e57806386b2ecc414610163575b005b6100d76100d2366004612d41565b610233565b6040516100e491906132b5565b60405180910390f35b6100d76100fb366004612caf565b6102b4565b34801561010c57600080fd5b5061012061011b366004612b32565b61059a565b6040516100e49291906131f6565b34801561013a57600080fd5b50610120610149366004612b32565b610947565b34801561015a57600080fd5b506100c2610c37565b6100d7610171366004612bc8565b610ca5565b6100d7610184366004612ce8565b611632565b34801561019557600080fd5b5061019e611908565b6040516100e491906130ec565b3480156101b757600080fd5b506101c0611917565b6040516100e49190613216565b3480156101d957600080fd5b506100c26101e8366004612b14565b61193b565b6100d76101fb366004612d41565b611981565b6100d761020e366004612c23565b6119f6565b34801561021f57600080fd5b506100c261022e366004612b14565b611cd2565b6000606061024087611d02565b156102655760015461025d906001600160a01b0316878786610947565b50905061029c565b61026e86611d02565b1561028c5760015461025d9088906001600160a01b03168786610947565b61029887878786610947565b5090505b6102a98188888888611632565b979650505050505050565b60006102c08483611d28565b5060005b8551811015610547576102d56127e4565b8682815181106102e157fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e906103299030908690600401613108565b60206040518083038186803b15801561034157600080fd5b505afa158015610355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103799190810190612d87565b111561040357825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b3916103af9190600090600401613181565b602060405180830381600087803b1580156103c957600080fd5b505af11580156103dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104019190810190612d23565b505b8251608084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b3926104349260040161319c565b602060405180830381600087803b15801561044e57600080fd5b505af1158015610462573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104869190810190612d23565b5060208301516080840151604080860151606087015160a08801519251631f17a7a960e21b81526000956001600160a01b03881695637c5e9ea4956104d195929491936004016131aa565b6040805180830381600087803b1580156104ea57600080fd5b505af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105229190810190612da5565b509050610535818763ffffffff611e4a16565b955050600190930192506102c4915050565b50818111156105715760405162461bcd60e51b815260040161056890613265565b60405180910390fd5b6105838361057e85611e76565b611f39565b506105918461057e86611e76565b50949350505050565b60025460405163bfdbfc4360e01b815260609160009183916001600160a01b03169063bfdbfc43906105d4908a908a908990600401613166565b60006040518083038186803b1580156105ec57600080fd5b505afa158015610600573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106289190810190612b93565b90506060815160405190808252806020026020018201604052801561066757816020015b610654612835565b81526020019060019003908161064c5790505b5090506000805b83518110156106e0576106958a8a86848151811061068857fe5b6020026020010151612068565b8382815181106106a157fe5b60200260200101819052506106d68382815181106106bb57fe5b602002602001015160c0015183611e4a90919063ffffffff16565b915060010161066e565b506060825160405190808252806020026020018201604052801561070e578160200160208202803883390190505b5090506000805b84518110156107a0576107588461074c87848151811061073157fe5b602002602001015160c001518d61234890919063ffffffff16565b9063ffffffff61238216565b83828151811061076457fe5b60200260200101818152505061079683828151811061077f57fe5b602002602001015183611e4a90919063ffffffff16565b9150600101610715565b50888110156107fd576107df6107bc8a8363ffffffff6123c416565b836000815181106107c957fe5b6020026020010151611e4a90919063ffffffff16565b826000815181106107ec57fe5b60200260200101818152505061084d565b610833610810828b63ffffffff6123c416565b8360008151811061081d57fe5b60200260200101516123c490919063ffffffff16565b8260008151811061084057fe5b6020026020010181815250505b835160405190808252806020026020018201604052801561088857816020015b6108756127e4565b81526020019060019003908161086d5790505b50965060005b845181101561092c576040518060c001604052808683815181106108ae57fe5b6020026020010151600001516001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b031681526020018483815181106108f257fe5b60200260200101518152602001600019815260200160001981525088828151811061091957fe5b602090810291909101015260010161088e565b506109378285612406565b9550505050505094509492505050565b60025460405163bfdbfc4360e01b815260609160009183916001600160a01b03169063bfdbfc4390610981908a908a908990600401613166565b60006040518083038186803b15801561099957600080fd5b505afa1580156109ad573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109d59190810190612b93565b905060608151604051908082528060200260200182016040528015610a1457816020015b610a01612835565b8152602001906001900390816109f95790505b5090506000805b8351811015610a6557610a358a8a86848151811061068857fe5b838281518110610a4157fe5b6020026020010181905250610a5b8382815181106106bb57fe5b9150600101610a1b565b5060608251604051908082528060200260200182016040528015610a93578160200160208202803883390190505b5090506000805b8451811015610ae757610ab68461074c87848151811061073157fe5b838281518110610ac257fe5b602002602001018181525050610add83828151811061077f57fe5b9150600101610a9a565b5088811015610b2157610b036107bc8a8363ffffffff6123c416565b82600081518110610b1057fe5b602002602001018181525050610b4e565b610b34610810828b63ffffffff6123c416565b82600081518110610b4157fe5b6020026020010181815250505b8351604051908082528060200260200182016040528015610b8957816020015b610b766127e4565b815260200190600190039081610b6e5790505b50965060005b8451811015610c2c576040518060c00160405280868381518110610baf57fe5b6020026020010151600001516001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b03168152602001848381518110610bf357fe5b6020026020010151815260200160008152602001600019815250888281518110610c1957fe5b6020908102919091010152600101610b8f565b50610937828561255c565b610c3f611917565b610c5b5760405162461bcd60e51b815260040161056890613285565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000610cb18483611d28565b5060005b8551811015610547576000868281518110610ccc57fe5b60200260200101515160011415610f5057610ce56127e4565b878381518110610cf157fe5b6020026020010151600081518110610d0557fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e90610d4d9030908690600401613108565b60206040518083038186803b158015610d6557600080fd5b505afa158015610d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d9d9190810190612d87565b1115610e2757825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b391610dd39190600090600401613181565b602060405180830381600087803b158015610ded57600080fd5b505af1158015610e01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e259190810190612d23565b505b8251608084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b392610e589260040161319c565b602060405180830381600087803b158015610e7257600080fd5b505af1158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610eaa9190810190612d23565b50806001600160a01b0316637c5e9ea484602001518560800151866040015187606001518860a001516040518663ffffffff1660e01b8152600401610ef39594939291906131aa565b6040805180830381600087803b158015610f0c57600080fd5b505af1158015610f20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f449190810190612da5565b50935061161792505050565b6000610f5a6127e4565b888481518110610f6657fe5b6020026020010151600181518110610f7a57fe5b60209081029190910181015180519181015160405163f8b2cb4f60e01b81529193506001600160a01b0383169163f8d6aed491839163f8b2cb4f91610fc1916004016130ec565b60206040518083038186803b158015610fd957600080fd5b505afa158015610fed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110119190810190612d87565b6020850151604051634a46c67360e11b81526001600160a01b0386169163948d8ce69161104191906004016130ec565b60206040518083038186803b15801561105957600080fd5b505afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110919190810190612d87565b604080870151905163f8b2cb4f60e01b81526001600160a01b0387169163f8b2cb4f916110c191906004016130ec565b60206040518083038186803b1580156110d957600080fd5b505afa1580156110ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111119190810190612d87565b6040808801519051634a46c67360e11b81526001600160a01b0388169163948d8ce69161114191906004016130ec565b60206040518083038186803b15801561115957600080fd5b505afa15801561116d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111919190810190612d87565b8760600151876001600160a01b031663d4cadf686040518163ffffffff1660e01b815260040160206040518083038186803b1580156111cf57600080fd5b505afa1580156111e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112079190810190612d87565b6040518763ffffffff1660e01b8152600401611228969594939291906132c3565b60206040518083038186803b15801561124057600080fd5b505afa158015611254573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112789190810190612d87565b92506112826127e4565b8a868151811061128e57fe5b60200260200101516000815181106112a257fe5b602090810291909101810151908101518151604051636eb1769f60e11b81529293509091600019906001600160a01b0384169063dd62ed3e906112eb9030908690600401613108565b60206040518083038186803b15801561130357600080fd5b505afa158015611317573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061133b9190810190612d87565b10156113c657825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b39161137291906000199060040161319c565b602060405180830381600087803b15801561138c57600080fd5b505af11580156113a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c49190810190612d23565b505b806001600160a01b0316637c5e9ea48460200151856080015186604001518a8860a001516040518663ffffffff1660e01b815260040161140a9594939291906131aa565b6040805180830381600087803b15801561142357600080fd5b505af1158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061145b9190810190612da5565b5060208601518651604051636eb1769f60e11b81529299509091600019916001600160a01b0384169163dd62ed3e9161149991309190600401613108565b60206040518083038186803b1580156114b157600080fd5b505afa1580156114c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114e99190810190612d87565b101561157457855160405163095ea7b360e01b81526001600160a01b0383169163095ea7b39161152091906000199060040161319c565b602060405180830381600087803b15801561153a57600080fd5b505af115801561154e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115729190810190612d23565b505b846001600160a01b0316637c5e9ea48760200151886080015189604001518a606001518b60a001516040518663ffffffff1660e01b81526004016115bc9594939291906131aa565b6040805180830381600087803b1580156115d557600080fd5b505af11580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061160d9190810190612da5565b5050505050505050505b611627818463ffffffff611e4a16565b925050600101610cb5565b600061163e8584611d28565b5060005b86518110156118c5576116536127e4565b87828151811061165f57fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e906116a79030908690600401613108565b60206040518083038186803b1580156116bf57600080fd5b505afa1580156116d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116f79190810190612d87565b111561178157825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b39161172d9190600090600401613181565b602060405180830381600087803b15801561174757600080fd5b505af115801561175b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061177f9190810190612d23565b505b8251606084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b3926117b29260040161319c565b602060405180830381600087803b1580156117cc57600080fd5b505af11580156117e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118049190810190612d23565b5060208301516060840151604080860151608087015160a08801519251638201aa3f60e01b81526000956001600160a01b03881695638201aa3f9561184f95929491936004016131aa565b6040805180830381600087803b15801561186857600080fd5b505af115801561187c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118a09190810190612da5565b5090506118b3818763ffffffff611e4a16565b95505060019093019250611642915050565b50818110156118e65760405162461bcd60e51b815260040161056890613255565b6118f08482611f39565b506118fe8561057e87611e76565b5095945050505050565b6000546001600160a01b031690565b600080546001600160a01b031661192c6126ab565b6001600160a01b031614905090565b611943611917565b61195f5760405162461bcd60e51b815260040161056890613285565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000606061198e87611d02565b156119b3576001546119ab906001600160a01b031687878661059a565b5090506119ea565b6119bc86611d02565b156119da576001546119ab9088906001600160a01b0316878661059a565b6119e68787878661059a565b5090505b6102a9818888876102b4565b6000611a028584611d28565b5060005b86518110156118c5576000805b888381518110611a1f57fe5b602002602001015151811015611cb657611a376127e4565b898481518110611a4357fe5b60200260200101518281518110611a5657fe5b602002602001015190506000816020015190508260011415611a7a57606082018490525b8151604051636eb1769f60e11b81526000906001600160a01b0384169063dd62ed3e90611aad9030908690600401613108565b60206040518083038186803b158015611ac557600080fd5b505afa158015611ad9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611afd9190810190612d87565b1115611b8757825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b391611b339190600090600401613181565b602060405180830381600087803b158015611b4d57600080fd5b505af1158015611b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b859190810190612d23565b505b8251606084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b392611bb89260040161319c565b602060405180830381600087803b158015611bd257600080fd5b505af1158015611be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c0a9190810190612d23565b50806001600160a01b0316638201aa3f84602001518560600151866040015187608001518860a001516040518663ffffffff1660e01b8152600401611c539594939291906131aa565b6040805180830381600087803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ca49190810190612da5565b5094505060019092019150611a139050565b50611cc7818463ffffffff611e4a16565b925050600101611a06565b611cda611917565b611cf65760405162461bcd60e51b815260040161056890613285565b611cff816126af565b50565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b919050565b6000611d3383611d02565b15611da657600160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d8857600080fd5b505af1158015611d9c573d6000803e3d6000fd5b5050505050611e44565b6040516323b872dd60e01b81526001600160a01b038416906323b872dd90611dd690339030908790600401613123565b602060405180830381600087803b158015611df057600080fd5b505af1158015611e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e289190810190612d23565b611e445760405162461bcd60e51b8152600401610568906132a5565b92915050565b600082820183811015611e6f5760405162461bcd60e51b815260040161056890613245565b9392505050565b6000611e8182611d02565b15611f0d576001546040516370a0823160e01b81526001600160a01b03909116906370a0823190611eb69030906004016130fa565b60206040518083038186803b158015611ece57600080fd5b505afa158015611ee2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f069190810190612d87565b9050611d23565b6040516370a0823160e01b81526001600160a01b038316906370a0823190611eb69030906004016130fa565b600081611f4857506001611e44565b611f5183611d02565b1561203a57600154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90611f869085906004016132b5565b600060405180830381600087803b158015611fa057600080fd5b505af1158015611fb4573d6000803e3d6000fd5b505050506000336001600160a01b031683604051611fd1906130e1565b60006040518083038185875af1925050503d806000811461200e576040519150601f19603f3d011682016040523d82523d6000602084013e612013565b606091505b50509050806120345760405162461bcd60e51b815260040161056890613295565b50611e44565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb90611dd6903390869060040161314b565b612070612835565b60405163f8b2cb4f60e01b815282906000906001600160a01b0383169063f8b2cb4f906120a19089906004016130ec565b60206040518083038186803b1580156120b957600080fd5b505afa1580156120cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120f19190810190612d87565b90506000826001600160a01b031663f8b2cb4f876040518263ffffffff1660e01b815260040161212191906130ec565b60206040518083038186803b15801561213957600080fd5b505afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121719190810190612d87565b90506000836001600160a01b031663948d8ce6896040518263ffffffff1660e01b81526004016121a191906130ec565b60206040518083038186803b1580156121b957600080fd5b505afa1580156121cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121f19190810190612d87565b90506000846001600160a01b031663948d8ce6896040518263ffffffff1660e01b815260040161222191906130ec565b60206040518083038186803b15801561223957600080fd5b505afa15801561224d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122719190810190612d87565b90506000856001600160a01b031663d4cadf686040518163ffffffff1660e01b815260040160206040518083038186803b1580156122ae57600080fd5b505afa1580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122e69190810190612d87565b905060006122f5848685612730565b90506122ff612835565b506040805160e0810182526001600160a01b038b16815260208101979097528601939093526060850193909352608084015260a083019190915260c08201529150509392505050565b60008261235757506000611e44565b8282028284828161236457fe5b0414611e6f5760405162461bcd60e51b815260040161056890613275565b6000611e6f83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612781565b6000611e6f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506127b8565b6000805b835181101561255557600083828151811061242157fe5b6020026020010151600001516001600160a01b031663f8d6aed485848151811061244757fe5b60200260200101516020015186858151811061245f57fe5b60200260200101516040015187868151811061247757fe5b60200260200101516060015188878151811061248f57fe5b6020026020010151608001518a88815181106124a757fe5b60200260200101518a89815181106124bb57fe5b602002602001015160a001516040518763ffffffff1660e01b81526004016124e8969594939291906132c3565b60206040518083038186803b15801561250057600080fd5b505afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125389190810190612d87565b905061254a838263ffffffff611e4a16565b92505060010161240a565b5092915050565b6000805b835181101561255557600083828151811061257757fe5b6020026020010151600001516001600160a01b031663ba9530a685848151811061259d57fe5b6020026020010151602001518685815181106125b557fe5b6020026020010151604001518786815181106125cd57fe5b6020026020010151606001518887815181106125e557fe5b6020026020010151608001518a88815181106125fd57fe5b60200260200101518a898151811061261157fe5b602002602001015160a001516040518763ffffffff1660e01b815260040161263e969594939291906132c3565b60206040518083038186803b15801561265657600080fd5b505afa15801561266a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061268e9190810190612d87565b90506126a0838263ffffffff611e4a16565b925050600101612560565b3390565b6001600160a01b0381166126d55760405162461bcd60e51b815260040161056890613235565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612779670de0b6b3a764000061074c8561276d612755878a63ffffffff611e4a16565b61074c8a670de0b6b3a764000063ffffffff61234816565b9063ffffffff61234816565b949350505050565b600081836127a25760405162461bcd60e51b81526004016105689190613224565b5060008385816127ae57fe5b0495945050505050565b600081848411156127dc5760405162461bcd60e51b81526004016105689190613224565b505050900390565b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b6040518060e0016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8035611e44816133e3565b8051611e44816133e3565b600082601f8301126128a257600080fd5b81516128b56128b082613339565b613312565b915081818352602084019350602081019050838560208402820111156128da57600080fd5b60005b8381101561290657816128f08882612886565b84525060209283019291909101906001016128dd565b5050505092915050565b600082601f83011261292157600080fd5b813561292f6128b082613339565b81815260209384019390925082018360005b838110156129065781358601612957888261296d565b8452506020928301929190910190600101612941565b600082601f83011261297e57600080fd5b813561298c6128b082613339565b915081818352602084019350602081019050838560c08402820111156129b157600080fd5b60005b8381101561290657816129c78882612a67565b84525060209092019160c091909101906001016129b4565b600082601f8301126129f057600080fd5b81356129fe6128b082613339565b915081818352602084019350602081019050838560c0840282011115612a2357600080fd5b60005b838110156129065781612a398882612a67565b84525060209092019160c09190910190600101612a26565b8051611e44816133f7565b8035611e4481613400565b600060c08284031215612a7957600080fd5b612a8360c0613312565b90506000612a91848461287b565b8252506020612aa28484830161287b565b6020830152506040612ab68482850161287b565b6040830152506060612aca84828501612afe565b6060830152506080612ade84828501612afe565b60808301525060a0612af284828501612afe565b60a08301525092915050565b8035611e4481613409565b8051611e4481613409565b600060208284031215612b2657600080fd5b6000612779848461287b565b60008060008060808587031215612b4857600080fd5b6000612b54878761287b565b9450506020612b658782880161287b565b9350506040612b7687828801612afe565b9250506060612b8787828801612afe565b91505092959194509250565b600060208284031215612ba557600080fd5b815167ffffffffffffffff811115612bbc57600080fd5b61277984828501612891565b60008060008060808587031215612bde57600080fd5b843567ffffffffffffffff811115612bf557600080fd5b612c0187828801612910565b9450506020612c1287828801612a5c565b9350506040612b7687828801612a5c565b600080600080600060a08688031215612c3b57600080fd5b853567ffffffffffffffff811115612c5257600080fd5b612c5e88828901612910565b9550506020612c6f88828901612a5c565b9450506040612c8088828901612a5c565b9350506060612c9188828901612afe565b9250506080612ca288828901612afe565b9150509295509295909350565b60008060008060808587031215612cc557600080fd5b843567ffffffffffffffff811115612cdc57600080fd5b612c01878288016129df565b600080600080600060a08688031215612d0057600080fd5b853567ffffffffffffffff811115612d1757600080fd5b612c5e888289016129df565b600060208284031215612d3557600080fd5b60006127798484612a51565b600080600080600060a08688031215612d5957600080fd5b6000612d658888612a5c565b9550506020612d7688828901612a5c565b9450506040612c8088828901612afe565b600060208284031215612d9957600080fd5b60006127798484612b09565b60008060408385031215612db857600080fd5b6000612dc48585612b09565b9250506020612dd585828601612b09565b9150509250929050565b6000612deb8383613062565b505060c00190565b612dfc81613397565b82525050565b612dfc8161336d565b6000612e1682613360565b612e208185613364565b9350612e2b8361335a565b8060005b83811015612e59578151612e438882612ddf565b9750612e4e8361335a565b925050600101612e2f565b509495945050505050565b612dfc81613378565b612dfc816133a2565b6000612e8182613360565b612e8b8185613364565b9350612e9b8185602086016133ad565b612ea4816133d9565b9093019392505050565b6000612ebb602683613364565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000612f03601b83613364565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000612f3c600d83613364565b6c11549497d31253525517d3d555609a1b815260200192915050565b6000612f65600c83613364565b6b22a9292fa624a6a4aa2fa4a760a11b815260200192915050565b6000612f8d602183613364565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000612fd0602083613364565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613009600e83613364565b6d11549497d1551217d1905253115160921b815260200192915050565b6000611e44600083611d23565b6000613040601383613364565b7211549497d514905394d1915497d19052531151606a1b815260200192915050565b805160c08301906130738482612e02565b5060208201516130866020850182612e02565b5060408201516130996040850182612e02565b5060608201516130ac60608501826130d8565b5060808201516130bf60808501826130d8565b5060a08201516130d260a08501826130d8565b50505050565b612dfc81613394565b6000611e4482613026565b60208101611e448284612e02565b60208101611e448284612df3565b604081016131168285612df3565b611e6f6020830184612e02565b606081016131318286612df3565b61313e6020830185612df3565b61277960408301846130d8565b604081016131598285612df3565b611e6f60208301846130d8565b606081016131748286612e02565b61313e6020830185612e02565b6040810161318f8285612e02565b611e6f6020830184612e6d565b604081016131598285612e02565b60a081016131b88288612e02565b6131c560208301876130d8565b6131d26040830186612e02565b6131df60608301856130d8565b6131ec60808301846130d8565b9695505050505050565b604080825281016132078185612e0b565b9050611e6f60208301846130d8565b60208101611e448284612e64565b60208082528101611e6f8184612e76565b60208082528101611e4481612eae565b60208082528101611e4481612ef6565b60208082528101611e4481612f2f565b60208082528101611e4481612f58565b60208082528101611e4481612f80565b60208082528101611e4481612fc3565b60208082528101611e4481612ffc565b60208082528101611e4481613033565b60208101611e4482846130d8565b60c081016132d182896130d8565b6132de60208301886130d8565b6132eb60408301876130d8565b6132f860608301866130d8565b61330560808301856130d8565b6102a960a08301846130d8565b60405181810167ffffffffffffffff8111828210171561333157600080fd5b604052919050565b600067ffffffffffffffff82111561335057600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b6000611e4482613388565b151590565b6000611e448261336d565b6001600160a01b031690565b90565b6000611e448261337d565b6000611e4482613394565b60005b838110156133c85781810151838201526020016133b0565b838111156130d25750506000910152565b601f01601f191690565b6133ec8161336d565b8114611cff57600080fd5b6133ec81613378565b6133ec8161337d565b6133ec8161339456fea365627a7a723158207d8b781f026c8e7032775d04416bdecff0427eb53e69ad3ff924bf75be9fe5216c6578706572696d656e74616cf564736f6c634300050c0040", - "deployedBytecode": "0x6080604052600436106100c25760003560e01c80638743ad581161007f578063a91ee0dc11610059578063a91ee0dc146101cd578063b40f39ee146101ed578063e2b3974614610200578063f2fde38b14610213576100c2565b80638743ad58146101765780638da5cb5b146101895780638f32d59b146101ab576100c2565b806321b0eb85146100c45780632db58134146100ed578063368bb1fc146101005780634b0f93fb1461012e578063715018a61461014e57806386b2ecc414610163575b005b6100d76100d2366004612d41565b610233565b6040516100e491906132b5565b60405180910390f35b6100d76100fb366004612caf565b6102b4565b34801561010c57600080fd5b5061012061011b366004612b32565b61059a565b6040516100e49291906131f6565b34801561013a57600080fd5b50610120610149366004612b32565b610947565b34801561015a57600080fd5b506100c2610c37565b6100d7610171366004612bc8565b610ca5565b6100d7610184366004612ce8565b611632565b34801561019557600080fd5b5061019e611908565b6040516100e491906130ec565b3480156101b757600080fd5b506101c0611917565b6040516100e49190613216565b3480156101d957600080fd5b506100c26101e8366004612b14565b61193b565b6100d76101fb366004612d41565b611981565b6100d761020e366004612c23565b6119f6565b34801561021f57600080fd5b506100c261022e366004612b14565b611cd2565b6000606061024087611d02565b156102655760015461025d906001600160a01b0316878786610947565b50905061029c565b61026e86611d02565b1561028c5760015461025d9088906001600160a01b03168786610947565b61029887878786610947565b5090505b6102a98188888888611632565b979650505050505050565b60006102c08483611d28565b5060005b8551811015610547576102d56127e4565b8682815181106102e157fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e906103299030908690600401613108565b60206040518083038186803b15801561034157600080fd5b505afa158015610355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103799190810190612d87565b111561040357825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b3916103af9190600090600401613181565b602060405180830381600087803b1580156103c957600080fd5b505af11580156103dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104019190810190612d23565b505b8251608084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b3926104349260040161319c565b602060405180830381600087803b15801561044e57600080fd5b505af1158015610462573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104869190810190612d23565b5060208301516080840151604080860151606087015160a08801519251631f17a7a960e21b81526000956001600160a01b03881695637c5e9ea4956104d195929491936004016131aa565b6040805180830381600087803b1580156104ea57600080fd5b505af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105229190810190612da5565b509050610535818763ffffffff611e4a16565b955050600190930192506102c4915050565b50818111156105715760405162461bcd60e51b815260040161056890613265565b60405180910390fd5b6105838361057e85611e76565b611f39565b506105918461057e86611e76565b50949350505050565b60025460405163bfdbfc4360e01b815260609160009183916001600160a01b03169063bfdbfc43906105d4908a908a908990600401613166565b60006040518083038186803b1580156105ec57600080fd5b505afa158015610600573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106289190810190612b93565b90506060815160405190808252806020026020018201604052801561066757816020015b610654612835565b81526020019060019003908161064c5790505b5090506000805b83518110156106e0576106958a8a86848151811061068857fe5b6020026020010151612068565b8382815181106106a157fe5b60200260200101819052506106d68382815181106106bb57fe5b602002602001015160c0015183611e4a90919063ffffffff16565b915060010161066e565b506060825160405190808252806020026020018201604052801561070e578160200160208202803883390190505b5090506000805b84518110156107a0576107588461074c87848151811061073157fe5b602002602001015160c001518d61234890919063ffffffff16565b9063ffffffff61238216565b83828151811061076457fe5b60200260200101818152505061079683828151811061077f57fe5b602002602001015183611e4a90919063ffffffff16565b9150600101610715565b50888110156107fd576107df6107bc8a8363ffffffff6123c416565b836000815181106107c957fe5b6020026020010151611e4a90919063ffffffff16565b826000815181106107ec57fe5b60200260200101818152505061084d565b610833610810828b63ffffffff6123c416565b8360008151811061081d57fe5b60200260200101516123c490919063ffffffff16565b8260008151811061084057fe5b6020026020010181815250505b835160405190808252806020026020018201604052801561088857816020015b6108756127e4565b81526020019060019003908161086d5790505b50965060005b845181101561092c576040518060c001604052808683815181106108ae57fe5b6020026020010151600001516001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b031681526020018483815181106108f257fe5b60200260200101518152602001600019815260200160001981525088828151811061091957fe5b602090810291909101015260010161088e565b506109378285612406565b9550505050505094509492505050565b60025460405163bfdbfc4360e01b815260609160009183916001600160a01b03169063bfdbfc4390610981908a908a908990600401613166565b60006040518083038186803b15801561099957600080fd5b505afa1580156109ad573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109d59190810190612b93565b905060608151604051908082528060200260200182016040528015610a1457816020015b610a01612835565b8152602001906001900390816109f95790505b5090506000805b8351811015610a6557610a358a8a86848151811061068857fe5b838281518110610a4157fe5b6020026020010181905250610a5b8382815181106106bb57fe5b9150600101610a1b565b5060608251604051908082528060200260200182016040528015610a93578160200160208202803883390190505b5090506000805b8451811015610ae757610ab68461074c87848151811061073157fe5b838281518110610ac257fe5b602002602001018181525050610add83828151811061077f57fe5b9150600101610a9a565b5088811015610b2157610b036107bc8a8363ffffffff6123c416565b82600081518110610b1057fe5b602002602001018181525050610b4e565b610b34610810828b63ffffffff6123c416565b82600081518110610b4157fe5b6020026020010181815250505b8351604051908082528060200260200182016040528015610b8957816020015b610b766127e4565b815260200190600190039081610b6e5790505b50965060005b8451811015610c2c576040518060c00160405280868381518110610baf57fe5b6020026020010151600001516001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b03168152602001848381518110610bf357fe5b6020026020010151815260200160008152602001600019815250888281518110610c1957fe5b6020908102919091010152600101610b8f565b50610937828561255c565b610c3f611917565b610c5b5760405162461bcd60e51b815260040161056890613285565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000610cb18483611d28565b5060005b8551811015610547576000868281518110610ccc57fe5b60200260200101515160011415610f5057610ce56127e4565b878381518110610cf157fe5b6020026020010151600081518110610d0557fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e90610d4d9030908690600401613108565b60206040518083038186803b158015610d6557600080fd5b505afa158015610d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d9d9190810190612d87565b1115610e2757825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b391610dd39190600090600401613181565b602060405180830381600087803b158015610ded57600080fd5b505af1158015610e01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e259190810190612d23565b505b8251608084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b392610e589260040161319c565b602060405180830381600087803b158015610e7257600080fd5b505af1158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610eaa9190810190612d23565b50806001600160a01b0316637c5e9ea484602001518560800151866040015187606001518860a001516040518663ffffffff1660e01b8152600401610ef39594939291906131aa565b6040805180830381600087803b158015610f0c57600080fd5b505af1158015610f20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f449190810190612da5565b50935061161792505050565b6000610f5a6127e4565b888481518110610f6657fe5b6020026020010151600181518110610f7a57fe5b60209081029190910181015180519181015160405163f8b2cb4f60e01b81529193506001600160a01b0383169163f8d6aed491839163f8b2cb4f91610fc1916004016130ec565b60206040518083038186803b158015610fd957600080fd5b505afa158015610fed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110119190810190612d87565b6020850151604051634a46c67360e11b81526001600160a01b0386169163948d8ce69161104191906004016130ec565b60206040518083038186803b15801561105957600080fd5b505afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110919190810190612d87565b604080870151905163f8b2cb4f60e01b81526001600160a01b0387169163f8b2cb4f916110c191906004016130ec565b60206040518083038186803b1580156110d957600080fd5b505afa1580156110ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111119190810190612d87565b6040808801519051634a46c67360e11b81526001600160a01b0388169163948d8ce69161114191906004016130ec565b60206040518083038186803b15801561115957600080fd5b505afa15801561116d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111919190810190612d87565b8760600151876001600160a01b031663d4cadf686040518163ffffffff1660e01b815260040160206040518083038186803b1580156111cf57600080fd5b505afa1580156111e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112079190810190612d87565b6040518763ffffffff1660e01b8152600401611228969594939291906132c3565b60206040518083038186803b15801561124057600080fd5b505afa158015611254573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112789190810190612d87565b92506112826127e4565b8a868151811061128e57fe5b60200260200101516000815181106112a257fe5b602090810291909101810151908101518151604051636eb1769f60e11b81529293509091600019906001600160a01b0384169063dd62ed3e906112eb9030908690600401613108565b60206040518083038186803b15801561130357600080fd5b505afa158015611317573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061133b9190810190612d87565b10156113c657825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b39161137291906000199060040161319c565b602060405180830381600087803b15801561138c57600080fd5b505af11580156113a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c49190810190612d23565b505b806001600160a01b0316637c5e9ea48460200151856080015186604001518a8860a001516040518663ffffffff1660e01b815260040161140a9594939291906131aa565b6040805180830381600087803b15801561142357600080fd5b505af1158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061145b9190810190612da5565b5060208601518651604051636eb1769f60e11b81529299509091600019916001600160a01b0384169163dd62ed3e9161149991309190600401613108565b60206040518083038186803b1580156114b157600080fd5b505afa1580156114c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114e99190810190612d87565b101561157457855160405163095ea7b360e01b81526001600160a01b0383169163095ea7b39161152091906000199060040161319c565b602060405180830381600087803b15801561153a57600080fd5b505af115801561154e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115729190810190612d23565b505b846001600160a01b0316637c5e9ea48760200151886080015189604001518a606001518b60a001516040518663ffffffff1660e01b81526004016115bc9594939291906131aa565b6040805180830381600087803b1580156115d557600080fd5b505af11580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061160d9190810190612da5565b5050505050505050505b611627818463ffffffff611e4a16565b925050600101610cb5565b600061163e8584611d28565b5060005b86518110156118c5576116536127e4565b87828151811061165f57fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e906116a79030908690600401613108565b60206040518083038186803b1580156116bf57600080fd5b505afa1580156116d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116f79190810190612d87565b111561178157825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b39161172d9190600090600401613181565b602060405180830381600087803b15801561174757600080fd5b505af115801561175b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061177f9190810190612d23565b505b8251606084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b3926117b29260040161319c565b602060405180830381600087803b1580156117cc57600080fd5b505af11580156117e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118049190810190612d23565b5060208301516060840151604080860151608087015160a08801519251638201aa3f60e01b81526000956001600160a01b03881695638201aa3f9561184f95929491936004016131aa565b6040805180830381600087803b15801561186857600080fd5b505af115801561187c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118a09190810190612da5565b5090506118b3818763ffffffff611e4a16565b95505060019093019250611642915050565b50818110156118e65760405162461bcd60e51b815260040161056890613255565b6118f08482611f39565b506118fe8561057e87611e76565b5095945050505050565b6000546001600160a01b031690565b600080546001600160a01b031661192c6126ab565b6001600160a01b031614905090565b611943611917565b61195f5760405162461bcd60e51b815260040161056890613285565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000606061198e87611d02565b156119b3576001546119ab906001600160a01b031687878661059a565b5090506119ea565b6119bc86611d02565b156119da576001546119ab9088906001600160a01b0316878661059a565b6119e68787878661059a565b5090505b6102a9818888876102b4565b6000611a028584611d28565b5060005b86518110156118c5576000805b888381518110611a1f57fe5b602002602001015151811015611cb657611a376127e4565b898481518110611a4357fe5b60200260200101518281518110611a5657fe5b602002602001015190506000816020015190508260011415611a7a57606082018490525b8151604051636eb1769f60e11b81526000906001600160a01b0384169063dd62ed3e90611aad9030908690600401613108565b60206040518083038186803b158015611ac557600080fd5b505afa158015611ad9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611afd9190810190612d87565b1115611b8757825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b391611b339190600090600401613181565b602060405180830381600087803b158015611b4d57600080fd5b505af1158015611b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b859190810190612d23565b505b8251606084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b392611bb89260040161319c565b602060405180830381600087803b158015611bd257600080fd5b505af1158015611be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c0a9190810190612d23565b50806001600160a01b0316638201aa3f84602001518560600151866040015187608001518860a001516040518663ffffffff1660e01b8152600401611c539594939291906131aa565b6040805180830381600087803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ca49190810190612da5565b5094505060019092019150611a139050565b50611cc7818463ffffffff611e4a16565b925050600101611a06565b611cda611917565b611cf65760405162461bcd60e51b815260040161056890613285565b611cff816126af565b50565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b919050565b6000611d3383611d02565b15611da657600160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d8857600080fd5b505af1158015611d9c573d6000803e3d6000fd5b5050505050611e44565b6040516323b872dd60e01b81526001600160a01b038416906323b872dd90611dd690339030908790600401613123565b602060405180830381600087803b158015611df057600080fd5b505af1158015611e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e289190810190612d23565b611e445760405162461bcd60e51b8152600401610568906132a5565b92915050565b600082820183811015611e6f5760405162461bcd60e51b815260040161056890613245565b9392505050565b6000611e8182611d02565b15611f0d576001546040516370a0823160e01b81526001600160a01b03909116906370a0823190611eb69030906004016130fa565b60206040518083038186803b158015611ece57600080fd5b505afa158015611ee2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f069190810190612d87565b9050611d23565b6040516370a0823160e01b81526001600160a01b038316906370a0823190611eb69030906004016130fa565b600081611f4857506001611e44565b611f5183611d02565b1561203a57600154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90611f869085906004016132b5565b600060405180830381600087803b158015611fa057600080fd5b505af1158015611fb4573d6000803e3d6000fd5b505050506000336001600160a01b031683604051611fd1906130e1565b60006040518083038185875af1925050503d806000811461200e576040519150601f19603f3d011682016040523d82523d6000602084013e612013565b606091505b50509050806120345760405162461bcd60e51b815260040161056890613295565b50611e44565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb90611dd6903390869060040161314b565b612070612835565b60405163f8b2cb4f60e01b815282906000906001600160a01b0383169063f8b2cb4f906120a19089906004016130ec565b60206040518083038186803b1580156120b957600080fd5b505afa1580156120cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120f19190810190612d87565b90506000826001600160a01b031663f8b2cb4f876040518263ffffffff1660e01b815260040161212191906130ec565b60206040518083038186803b15801561213957600080fd5b505afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121719190810190612d87565b90506000836001600160a01b031663948d8ce6896040518263ffffffff1660e01b81526004016121a191906130ec565b60206040518083038186803b1580156121b957600080fd5b505afa1580156121cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121f19190810190612d87565b90506000846001600160a01b031663948d8ce6896040518263ffffffff1660e01b815260040161222191906130ec565b60206040518083038186803b15801561223957600080fd5b505afa15801561224d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122719190810190612d87565b90506000856001600160a01b031663d4cadf686040518163ffffffff1660e01b815260040160206040518083038186803b1580156122ae57600080fd5b505afa1580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122e69190810190612d87565b905060006122f5848685612730565b90506122ff612835565b506040805160e0810182526001600160a01b038b16815260208101979097528601939093526060850193909352608084015260a083019190915260c08201529150509392505050565b60008261235757506000611e44565b8282028284828161236457fe5b0414611e6f5760405162461bcd60e51b815260040161056890613275565b6000611e6f83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612781565b6000611e6f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506127b8565b6000805b835181101561255557600083828151811061242157fe5b6020026020010151600001516001600160a01b031663f8d6aed485848151811061244757fe5b60200260200101516020015186858151811061245f57fe5b60200260200101516040015187868151811061247757fe5b60200260200101516060015188878151811061248f57fe5b6020026020010151608001518a88815181106124a757fe5b60200260200101518a89815181106124bb57fe5b602002602001015160a001516040518763ffffffff1660e01b81526004016124e8969594939291906132c3565b60206040518083038186803b15801561250057600080fd5b505afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125389190810190612d87565b905061254a838263ffffffff611e4a16565b92505060010161240a565b5092915050565b6000805b835181101561255557600083828151811061257757fe5b6020026020010151600001516001600160a01b031663ba9530a685848151811061259d57fe5b6020026020010151602001518685815181106125b557fe5b6020026020010151604001518786815181106125cd57fe5b6020026020010151606001518887815181106125e557fe5b6020026020010151608001518a88815181106125fd57fe5b60200260200101518a898151811061261157fe5b602002602001015160a001516040518763ffffffff1660e01b815260040161263e969594939291906132c3565b60206040518083038186803b15801561265657600080fd5b505afa15801561266a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061268e9190810190612d87565b90506126a0838263ffffffff611e4a16565b925050600101612560565b3390565b6001600160a01b0381166126d55760405162461bcd60e51b815260040161056890613235565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612779670de0b6b3a764000061074c8561276d612755878a63ffffffff611e4a16565b61074c8a670de0b6b3a764000063ffffffff61234816565b9063ffffffff61234816565b949350505050565b600081836127a25760405162461bcd60e51b81526004016105689190613224565b5060008385816127ae57fe5b0495945050505050565b600081848411156127dc5760405162461bcd60e51b81526004016105689190613224565b505050900390565b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b6040518060e0016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8035611e44816133e3565b8051611e44816133e3565b600082601f8301126128a257600080fd5b81516128b56128b082613339565b613312565b915081818352602084019350602081019050838560208402820111156128da57600080fd5b60005b8381101561290657816128f08882612886565b84525060209283019291909101906001016128dd565b5050505092915050565b600082601f83011261292157600080fd5b813561292f6128b082613339565b81815260209384019390925082018360005b838110156129065781358601612957888261296d565b8452506020928301929190910190600101612941565b600082601f83011261297e57600080fd5b813561298c6128b082613339565b915081818352602084019350602081019050838560c08402820111156129b157600080fd5b60005b8381101561290657816129c78882612a67565b84525060209092019160c091909101906001016129b4565b600082601f8301126129f057600080fd5b81356129fe6128b082613339565b915081818352602084019350602081019050838560c0840282011115612a2357600080fd5b60005b838110156129065781612a398882612a67565b84525060209092019160c09190910190600101612a26565b8051611e44816133f7565b8035611e4481613400565b600060c08284031215612a7957600080fd5b612a8360c0613312565b90506000612a91848461287b565b8252506020612aa28484830161287b565b6020830152506040612ab68482850161287b565b6040830152506060612aca84828501612afe565b6060830152506080612ade84828501612afe565b60808301525060a0612af284828501612afe565b60a08301525092915050565b8035611e4481613409565b8051611e4481613409565b600060208284031215612b2657600080fd5b6000612779848461287b565b60008060008060808587031215612b4857600080fd5b6000612b54878761287b565b9450506020612b658782880161287b565b9350506040612b7687828801612afe565b9250506060612b8787828801612afe565b91505092959194509250565b600060208284031215612ba557600080fd5b815167ffffffffffffffff811115612bbc57600080fd5b61277984828501612891565b60008060008060808587031215612bde57600080fd5b843567ffffffffffffffff811115612bf557600080fd5b612c0187828801612910565b9450506020612c1287828801612a5c565b9350506040612b7687828801612a5c565b600080600080600060a08688031215612c3b57600080fd5b853567ffffffffffffffff811115612c5257600080fd5b612c5e88828901612910565b9550506020612c6f88828901612a5c565b9450506040612c8088828901612a5c565b9350506060612c9188828901612afe565b9250506080612ca288828901612afe565b9150509295509295909350565b60008060008060808587031215612cc557600080fd5b843567ffffffffffffffff811115612cdc57600080fd5b612c01878288016129df565b600080600080600060a08688031215612d0057600080fd5b853567ffffffffffffffff811115612d1757600080fd5b612c5e888289016129df565b600060208284031215612d3557600080fd5b60006127798484612a51565b600080600080600060a08688031215612d5957600080fd5b6000612d658888612a5c565b9550506020612d7688828901612a5c565b9450506040612c8088828901612afe565b600060208284031215612d9957600080fd5b60006127798484612b09565b60008060408385031215612db857600080fd5b6000612dc48585612b09565b9250506020612dd585828601612b09565b9150509250929050565b6000612deb8383613062565b505060c00190565b612dfc81613397565b82525050565b612dfc8161336d565b6000612e1682613360565b612e208185613364565b9350612e2b8361335a565b8060005b83811015612e59578151612e438882612ddf565b9750612e4e8361335a565b925050600101612e2f565b509495945050505050565b612dfc81613378565b612dfc816133a2565b6000612e8182613360565b612e8b8185613364565b9350612e9b8185602086016133ad565b612ea4816133d9565b9093019392505050565b6000612ebb602683613364565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000612f03601b83613364565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000612f3c600d83613364565b6c11549497d31253525517d3d555609a1b815260200192915050565b6000612f65600c83613364565b6b22a9292fa624a6a4aa2fa4a760a11b815260200192915050565b6000612f8d602183613364565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000612fd0602083613364565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613009600e83613364565b6d11549497d1551217d1905253115160921b815260200192915050565b6000611e44600083611d23565b6000613040601383613364565b7211549497d514905394d1915497d19052531151606a1b815260200192915050565b805160c08301906130738482612e02565b5060208201516130866020850182612e02565b5060408201516130996040850182612e02565b5060608201516130ac60608501826130d8565b5060808201516130bf60808501826130d8565b5060a08201516130d260a08501826130d8565b50505050565b612dfc81613394565b6000611e4482613026565b60208101611e448284612e02565b60208101611e448284612df3565b604081016131168285612df3565b611e6f6020830184612e02565b606081016131318286612df3565b61313e6020830185612df3565b61277960408301846130d8565b604081016131598285612df3565b611e6f60208301846130d8565b606081016131748286612e02565b61313e6020830185612e02565b6040810161318f8285612e02565b611e6f6020830184612e6d565b604081016131598285612e02565b60a081016131b88288612e02565b6131c560208301876130d8565b6131d26040830186612e02565b6131df60608301856130d8565b6131ec60808301846130d8565b9695505050505050565b604080825281016132078185612e0b565b9050611e6f60208301846130d8565b60208101611e448284612e64565b60208082528101611e6f8184612e76565b60208082528101611e4481612eae565b60208082528101611e4481612ef6565b60208082528101611e4481612f2f565b60208082528101611e4481612f58565b60208082528101611e4481612f80565b60208082528101611e4481612fc3565b60208082528101611e4481612ffc565b60208082528101611e4481613033565b60208101611e4482846130d8565b60c081016132d182896130d8565b6132de60208301886130d8565b6132eb60408301876130d8565b6132f860608301866130d8565b61330560808301856130d8565b6102a960a08301846130d8565b60405181810167ffffffffffffffff8111828210171561333157600080fd5b604052919050565b600067ffffffffffffffff82111561335057600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b6000611e4482613388565b151590565b6000611e448261336d565b6001600160a01b031690565b90565b6000611e448261337d565b6000611e4482613394565b60005b838110156133c85781810151838201526020016133b0565b838111156130d25750506000910152565b601f01601f191690565b6133ec8161336d565b8114611cff57600080fd5b6133ec81613378565b6133ec8161337d565b6133ec8161339456fea365627a7a723158207d8b781f026c8e7032775d04416bdecff0427eb53e69ad3ff924bf75be9fe5216c6578706572696d656e74616cf564736f6c634300050c0040", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/src/static/abi.js b/src/static/abi.js deleted file mode 100644 index 8762479..0000000 --- a/src/static/abi.js +++ /dev/null @@ -1,234 +0,0 @@ -/* eslint-disable */ - -const ERC20Abi = [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "balance", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - } -] - -const KovanWETHAbi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}] - -const KovanFaucetAddress = '0xb48Cc42C45d262534e46d5965a9Ac496F1B7a830' - -module.exports = { - ERC20Abi, - KovanWETHAbi, - KovanFaucetAddress, -}; diff --git a/src/static/erc20_tokens_kovan.json b/src/static/erc20_tokens_kovan.json deleted file mode 100644 index d4bb4e5..0000000 --- a/src/static/erc20_tokens_kovan.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "kovan", - "tokens": [ - { - "symbol": "BAT", - "address": "0x1f1f156E0317167c11Aa412E3d1435ea29Dc3cCE", - "decimals": 18 - }, - { - "symbol": "WETH", - "address": "0xd0A1E359811322d97991E03f863a0C30C2cF029C", - "decimals": 18 - }, - { - "symbol": "DAI", - "address": "0x1528F3FCc26d13F7079325Fb78D9442607781c8C", - "decimals": 18 - }, - { - "symbol": "MKR", - "address": "0xef13C0c8abcaf5767160018d268f9697aE4f5375", - "decimals": 18 - }, - { - "symbol": "USDC", - "address": "0x2F375e94FC336Cdec2Dc0cCB5277FE59CBf1cAe5", - "decimals": 6 - }, - { - "symbol": "REP", - "address": "0x8c9e6c40d3402480ACE624730524fACC5482798c", - "decimals": 18 - }, - { - "symbol": "WBTC", - "address": "0xe0C9275E44Ea80eF17579d33c55136b7DA269aEb", - "decimals": 18 - }, - { - "symbol": "SNX", - "address": "0x86436BcE20258a6DcfE48C9512d4d49A30C4d8c4", - "decimals": 18 - }, - { - "symbol": "ANT", - "address": "0x37f03a12241E9FD3658ad6777d289c3fb8512Bc9", - "decimals": 18 - }, - { - "symbol": "ZRX", - "address": "0xccb0F4Cf5D3F97f4a55bb5f5cA321C3ED033f244", - "decimals": 18 - } - ] -} diff --git a/src/static/uniswap_route_tokens.json b/src/static/uniswap_route_tokens.json deleted file mode 100644 index 08c66bf..0000000 --- a/src/static/uniswap_route_tokens.json +++ /dev/null @@ -1,15 +0,0 @@ -{"mainnet": [ - {"address":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","name":"WrappedEther","symbol":"WETH","decimals":18}, - {"address":"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599","name":"WrappedBTC","symbol":"WBTC","decimals":8}, - {"address":"0x6B175474E89094C44Da98b954EedeAC495271d0F","name":"DaiStablecoin","symbol":"DAI","decimals":18}, - {"address":"0xdAC17F958D2ee523a2206206994597C13D831ec7","name":"TetherUSD","symbol":"USDT","decimals":6}, - {"address":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","name":"USDCoin","symbol":"USDC","decimals":6}, - {"address":"0xba100000625a3754423978a60c9317c58a424e3D","name":"Balancer","symbol":"BAL","decimals":18}, - {"address":"0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD","name":"Loopring","symbol":"LRC","decimals":18} -], -"kovan":[ - {"address":"0xd0A1E359811322d97991E03f863a0C30C2cF029C","name":"WrappedEther","symbol":"WETH","decimals":18}, - {"address":"0xe0C9275E44Ea80eF17579d33c55136b7DA269aEb","name":"WrappedBTC","symbol":"WBTC","decimals":8}, - {"address":"0x1528F3FCc26d13F7079325Fb78D9442607781c8C","name":"DaiStablecoin","symbol":"DAI","decimals":18}, - {"address":"0x2F375e94FC336Cdec2Dc0cCB5277FE59CBf1cAe5","name":"USDCoin","symbol":"USDC","decimals":6} -]} diff --git a/src/static/uniswap_v2_router_abi.json b/src/static/uniswap_v2_router_abi.json deleted file mode 100644 index e2eac42..0000000 --- a/src/static/uniswap_v2_router_abi.json +++ /dev/null @@ -1,1924 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "name": "WETH", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountADesired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountBDesired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountAMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountBMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "addLiquidity", - "outputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountTokenDesired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "addLiquidityETH", - "outputs": [ - { - "internalType": "uint256", - "name": "amountToken", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" - } - ], - "name": "getAmountIn", - "outputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" - } - ], - "name": "getAmountOut", - "outputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - } - ], - "name": "getAmountsIn", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - } - ], - "name": "getAmountsOut", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveB", - "type": "uint256" - } - ], - "name": "quote", - "outputs": [ - { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountAMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountBMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "removeLiquidity", - "outputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "removeLiquidityETH", - "outputs": [ - { - "internalType": "uint256", - "name": "amountToken", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "removeLiquidityETHSupportingFeeOnTransferTokens", - "outputs": [ - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "approveMax", - "type": "bool" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "removeLiquidityETHWithPermit", - "outputs": [ - { - "internalType": "uint256", - "name": "amountToken", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "approveMax", - "type": "bool" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens", - "outputs": [ - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountAMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountBMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "approveMax", - "type": "bool" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "removeLiquidityWithPermit", - "outputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapETHForExactTokens", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactETHForTokens", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactETHForTokensSupportingFeeOnTransferTokens", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForETH", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForETHSupportingFeeOnTransferTokens", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForTokens", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForTokensSupportingFeeOnTransferTokens", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapTokensForExactETH", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapTokensForExactTokens", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "evm": { - "bytecode": { - "linkReferences": {}, - "object": "", - "opcodes": "", - "sourceMap": "" - }, - "deployedBytecode": { - "immutableReferences": {}, - "linkReferences": {}, - "object": "", - "opcodes": "", - "sourceMap": "" - } - }, - "interface": [ - { - "inputs": [], - "name": "WETH", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountADesired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountBDesired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountAMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountBMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "addLiquidity", - "outputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountTokenDesired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "addLiquidityETH", - "outputs": [ - { - "internalType": "uint256", - "name": "amountToken", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" - } - ], - "name": "getAmountIn", - "outputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveOut", - "type": "uint256" - } - ], - "name": "getAmountOut", - "outputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - } - ], - "name": "getAmountsIn", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - } - ], - "name": "getAmountsOut", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reserveB", - "type": "uint256" - } - ], - "name": "quote", - "outputs": [ - { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountAMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountBMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "removeLiquidity", - "outputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "removeLiquidityETH", - "outputs": [ - { - "internalType": "uint256", - "name": "amountToken", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "removeLiquidityETHSupportingFeeOnTransferTokens", - "outputs": [ - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "approveMax", - "type": "bool" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "removeLiquidityETHWithPermit", - "outputs": [ - { - "internalType": "uint256", - "name": "amountToken", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountTokenMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountETHMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "approveMax", - "type": "bool" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens", - "outputs": [ - { - "internalType": "uint256", - "name": "amountETH", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" - }, - { - "internalType": "uint256", - "name": "liquidity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountAMin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountBMin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "approveMax", - "type": "bool" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "removeLiquidityWithPermit", - "outputs": [ - { - "internalType": "uint256", - "name": "amountA", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountB", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapETHForExactTokens", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactETHForTokens", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactETHForTokensSupportingFeeOnTransferTokens", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForETH", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForETHSupportingFeeOnTransferTokens", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForTokens", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOutMin", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapExactTokensForTokensSupportingFeeOnTransferTokens", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapTokensForExactETH", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountInMax", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "path", - "type": "address[]" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swapTokensForExactTokens", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "" -} diff --git a/test/command.md b/test/command.md deleted file mode 100644 index 7ddb10c..0000000 --- a/test/command.md +++ /dev/null @@ -1,3 +0,0 @@ - -# test endpoint -curl --insecure --key /home/dev/bots/hbot_files/hummingbot_certs/client_key.pem --cert /home/dev/bots/hbot_files/hummingbot_certs/client_cert.pem https://localhost:5000/api diff --git a/test/conf/ca.cnf b/test/conf/ca.cnf deleted file mode 100644 index d415734..0000000 --- a/test/conf/ca.cnf +++ /dev/null @@ -1,25 +0,0 @@ -[ ca ] -default_ca = CA_default - -[ CA_default ] -serial = ca-serial -crl = ca-crl.pem -database = ca-database.txt -name_opt = CA_default -cert_opt = CA_default -default_crl_days = 365 -default_md = md5 - -[ req ] -default_bits = 4096 -days = 365 -distinguished_name = req_distinguished_name -attributes = req_attributes -prompt = no -output_password = password - -[ req_distinguished_name ] -CN = ca - -[ req_attributes ] -challengePassword = test diff --git a/test/conf/client.cnf b/test/conf/client.cnf deleted file mode 100644 index 4bf4921..0000000 --- a/test/conf/client.cnf +++ /dev/null @@ -1,13 +0,0 @@ -[ req ] -default_bits = 4096 -days = 365 -distinguished_name = req_distinguished_name -attributes = req_attributes -prompt = no - -[ req_distinguished_name ] -O = Hummingbot -CN = client - -[ req_attributes ] -challengePassword = password diff --git a/test/conf/server.cnf b/test/conf/server.cnf deleted file mode 100644 index 0dd2c3a..0000000 --- a/test/conf/server.cnf +++ /dev/null @@ -1,13 +0,0 @@ -[ req ] -default_bits = 4096 -days = 365 -distinguished_name = req_distinguished_name -attributes = req_attributes -prompt = no - -[ req_distinguished_name ] -O = Hummingbot -CN = localhost - -[ req_attributes ] -challengePassword = password diff --git a/test/index.js b/test/index.js deleted file mode 100644 index ff7bd09..0000000 --- a/test/index.js +++ /dev/null @@ -1 +0,0 @@ -// placeholder diff --git a/test/postman/Gateway-Ethereum-Base.postman_collection.json b/test/postman/Gateway-Ethereum-Base.postman_collection.json deleted file mode 100644 index 20622ac..0000000 --- a/test/postman/Gateway-Ethereum-Base.postman_collection.json +++ /dev/null @@ -1,1264 +0,0 @@ -{ - "info": { - "_postman_id": "e39af94e-6095-479e-8ba0-66930b12e364", - "name": "Gateway-Ethereum-Base", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "ethereum", - "item": [ - { - "name": "eth/balances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenAddressList", - "value": "{ \"{{WETH}}\": 18, \"{{DAI}}\": 18}", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "eth/allowances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenAddressList", - "value": "{ \"{{BAT}}\": 18, \"{{DAI}}\": 18 }", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/allowances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "allowances" - ] - } - }, - "response": [] - }, - { - "name": "eth/approve", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenAddress", - "value": "{{WETH}}", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "gasPrice", - "value": "23", - "type": "text" - }, - { - "key": "decimals", - "value": "18", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "amount", - "value": "999999", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/approve", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "approve" - ] - } - }, - "response": [] - }, - { - "name": "eth/get-weth", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "gasPrice", - "value": "31", - "type": "text" - }, - { - "key": "amount", - "value": "0.03", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "tokenAddress", - "value": "{{WETH}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/get-weth", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "get-weth" - ] - } - }, - "response": [] - }, - { - "name": "eth/get-receipt", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "txHash", - "value": "{{txHash}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/get-receipt", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "get-receipt" - ] - } - }, - "response": [] - } - ], - "protocolProfileBehavior": {} - }, - { - "name": "balancer", - "item": [ - { - "name": "balancer", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/balancer", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer" - ] - } - }, - "response": [] - }, - { - "name": "balancer/gas-limit", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "maxSwaps", - "value": "3", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/gas-limit", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "gas-limit" - ] - } - }, - "response": [] - }, - { - "name": "balancer/buy-price/", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "maxSwaps", - "value": "4", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/buy-price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "buy-price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "balancer/sell-price/", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "maxSwaps", - "value": "4", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/sell-price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "sell-price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "balancer/buy", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "maxSwaps", - "value": "4", - "type": "text" - }, - { - "key": "maxPrice", - "value": "0.19767217120251", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/buy", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "buy" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "balancer/sell", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "0.1", - "type": "text" - }, - { - "key": "maxSwaps", - "value": "4", - "type": "text" - }, - { - "key": "maxPrice", - "value": "0.2685681573104575", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/sell", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "sell" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - } - ], - "protocolProfileBehavior": {} - }, - { - "name": "uniswap", - "item": [ - { - "name": "uniswap", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/uniswap", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "uniswap" - ] - } - }, - "response": [] - }, - { - "name": "uniswap/gas-limit", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/uniswap/gas-limit", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "uniswap", - "gas-limit" - ] - } - }, - "response": [] - }, - { - "name": "uniswap/buy-price/", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/uniswap/buy-price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "uniswap", - "buy-price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "uniswap/sell-price/", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/uniswap/sell-price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "uniswap", - "sell-price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - } - ], - "protocolProfileBehavior": {} - } - ], - "protocolProfileBehavior": {} -} \ No newline at end of file diff --git a/test/postman/Gateway-Terra.postman_collection.json b/test/postman/Gateway-Terra.postman_collection.json deleted file mode 100644 index 40866b8..0000000 --- a/test/postman/Gateway-Terra.postman_collection.json +++ /dev/null @@ -1,328 +0,0 @@ -{ - "info": { - "_postman_id": "3cca9e73-0e1f-4e4f-8973-87c985a43219", - "name": "Gateway-Terra", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "terra", - "item": [ - { - "name": "terra/balances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "address", - "value": "{{address}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/terra/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "terra/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "SDT", - "type": "text" - }, - { - "key": "quote", - "value": "KRT", - "type": "text" - }, - { - "key": "trade_type", - "value": "buy", - "type": "text" - }, - { - "key": "amount", - "value": "3", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "terra/trade", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "SDT", - "type": "text" - }, - { - "key": "quote", - "value": "KRT", - "type": "text" - }, - { - "key": "trade_type", - "value": "buy", - "type": "text" - }, - { - "key": "amount", - "value": "3", - "type": "text" - }, - { - "key": "secret", - "value": "{{secret}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/trade", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "trade" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - } - ], - "protocolProfileBehavior": {} - } - ], - "protocolProfileBehavior": {} -} \ No newline at end of file diff --git a/test/postman/PERPFI.postman_collection.json b/test/postman/PERPFI.postman_collection.json deleted file mode 100644 index 513a083..0000000 --- a/test/postman/PERPFI.postman_collection.json +++ /dev/null @@ -1,454 +0,0 @@ -{ - "info": { - "_postman_id": "08bf4528-5e70-42cd-bf71-b97f81088b9c", - "name": "PERPFI", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "default", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "https://localhost:{{port}}/perpfi/", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/load-metadata", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "https://localhost:{{port}}/perpfi/load-metadata", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "load-metadata" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/pairs", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "https://localhost:{{port}}/perpfi/pairs", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "pairs" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/balances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/allowances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/allowances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "allowances" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/approve", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/approve", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "approve" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/open", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "margin", - "value": "15", - "type": "text" - }, - { - "key": "leverage", - "value": "2", - "type": "text" - }, - { - "key": "side", - "value": "{{SHORT}}", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/open", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "open" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/close", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/close", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "close" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/receipt", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "txHash", - "value": "0xd29120d947319c880f68a44b897c733c07ec313d670a7df55e523b501d7a03a2", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/receipt", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "receipt" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/position", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/position", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "position" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/margin", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/margin", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "margin" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/pnl", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/pnl", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "pnl" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/funding", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/funding", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "funding" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "side", - "value": "buy", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "price" - ] - } - }, - "response": [] - } - ] -} \ No newline at end of file diff --git a/test/postman/terra.postman_environment.json b/test/postman/terra.postman_environment.json deleted file mode 100644 index 735927a..0000000 --- a/test/postman/terra.postman_environment.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "id": "aebe7d1f-0e85-4441-8679-2ddc38d74350", - "name": "terra", - "values": [ - { - "key": "protocol", - "value": "terra", - "enabled": true - }, - { - "key": "port", - "value": "5000", - "enabled": true - }, - { - "key": "address", - "value": "myaddresss", - "enabled": true - }, - { - "key": "secret", - "value": "mysupersecret", - "enabled": true - } - ], - "_postman_variable_scope": "environment", - "_postman_exported_at": "2020-11-13T06:00:14.142Z", - "_postman_exported_using": "Postman/7.35.0" -} \ No newline at end of file diff --git a/test/postman/v2/Gateway.postman_collection.json b/test/postman/v2/Gateway.postman_collection.json deleted file mode 100644 index 949efe0..0000000 --- a/test/postman/v2/Gateway.postman_collection.json +++ /dev/null @@ -1,1001 +0,0 @@ -{ - "info": { - "_postman_id": "e39af94e-6095-479e-8ba0-66930b12e364", - "name": "Gateway", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "v2", - "item": [ - { - "name": "ethereum", - "item": [ - { - "name": "eth", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth" - ] - } - }, - "response": [] - }, - { - "name": "eth/balances", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenList", - "value": "[\"BAT\",\"USDC\",\"DAI\",\"WETH\",\"ZRX\"]", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "eth/allowances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenList", - "value": "[\"BAT\",\"USDC\",\"DAI\",\"WETH\",\"ZRX\"]", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/allowances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "allowances" - ] - } - }, - "response": [] - }, - { - "name": "eth/approve", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "token", - "value": "ZRX", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "gasPrice", - "value": "23", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "amount", - "value": "999", - "type": "text", - "disabled": true - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/approve", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "approve" - ] - } - }, - "response": [] - }, - { - "name": "eth/get-weth", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "gasPrice", - "value": "31", - "type": "text" - }, - { - "key": "amount", - "value": "0.03", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "tokenAddress", - "value": "{{WETH}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/get-weth", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "get-weth" - ] - } - }, - "response": [] - }, - { - "name": "eth/poll", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "txHash", - "value": "{{txHash}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/poll", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "poll" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "balancer", - "item": [ - { - "name": "eth/balancer", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer" - ] - } - }, - "response": [] - }, - { - "name": "eth/balancer/gas-limit", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer/gas-limit", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer", - "gas-limit" - ] - } - }, - "response": [] - }, - { - "name": "eth/balancer/start", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "BAT", - "type": "text" - }, - { - "key": "quote", - "value": "dai", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "approvalAmount", - "value": "1", - "type": "text", - "disabled": true - }, - { - "key": "gasPrice", - "value": "50", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer/start", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer", - "start" - ] - } - }, - "response": [] - }, - { - "name": "eth/balancer/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "BAT", - "type": "text" - }, - { - "key": "quote", - "value": "dai", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "side", - "value": "buy", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer", - "price" - ] - } - }, - "response": [] - }, - { - "name": "eth/balancer/trade", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "BAT", - "type": "text" - }, - { - "key": "quote", - "value": "USDC", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "limitPrice", - "value": "0.19767217120251", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "side", - "value": "sell", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer/trade", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer", - "trade" - ] - } - }, - "response": [] - } - ], - "event": [ - { - "listen": "prerequest", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - }, - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ] - }, - { - "name": "uniswap", - "item": [ - { - "name": "eth/uniswap", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/gas-limit", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/gas-limit", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "gas-limit" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/start", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "WETH", - "type": "text" - }, - { - "key": "quote", - "value": "USDC", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "approvalAmount", - "value": "1", - "type": "text", - "disabled": true - }, - { - "key": "gasPrice", - "value": "50", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/start", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "start" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "WETH", - "type": "text" - }, - { - "key": "quote", - "value": "DAI", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "side", - "value": "buy", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "price" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/trade", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "BAT", - "type": "text" - }, - { - "key": "quote", - "value": "DAI", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "limitPrice", - "value": "0.19767217120251", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "side", - "value": "sell", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/trade", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "trade" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "terra", - "item": [ - { - "name": "terra", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "address", - "value": "{{address}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/terra", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra" - ] - } - }, - "response": [] - }, - { - "name": "terra/balances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "address", - "value": "{{terraWalletAddress}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/terra/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "terra/start", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "LUNA", - "type": "text" - }, - { - "key": "quote", - "value": "UST", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/start", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "start" - ] - } - }, - "response": [] - }, - { - "name": "terra/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "UST", - "type": "text" - }, - { - "key": "quote", - "value": "KRT", - "type": "text" - }, - { - "key": "side", - "value": "buy", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "price" - ] - } - }, - "response": [] - }, - { - "name": "terra/trade", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "UST", - "type": "text" - }, - { - "key": "quote", - "value": "KRT", - "type": "text" - }, - { - "key": "side", - "value": "buy", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{terraSeeds}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/trade", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "trade" - ] - } - }, - "response": [] - } - ] - } - ] - }, - { - "name": "/api", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/api", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "api" - ] - } - }, - "response": [] - }, - { - "name": "/", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "" - ] - } - }, - "response": [] - } - ] -} \ No newline at end of file diff --git a/test/postman/v2/Gateway.postman_environment.json b/test/postman/v2/Gateway.postman_environment.json deleted file mode 100644 index 834026f..0000000 --- a/test/postman/v2/Gateway.postman_environment.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "id": "4436d04a-e8eb-451b-b7ef-851b171508e8", - "name": "Gateway", - "values": [ - { - "key": "port", - "value": "5000", - "enabled": true - }, - { - "key": "privateKey", - "value": "myprivatekey", - "enabled": true - }, - { - "key": "txHash", - "value": "transactionhash", - "enabled": true - }, - { - "key": "terraWalletAddress", - "value": "terrawalletaddress", - "enabled": true - }, - { - "key": "terraSeeds", - "value": "terraseeds", - "enabled": true - } - ], - "_postman_variable_scope": "environment", - "_postman_exported_at": "2021-01-30T13:04:21.323Z", - "_postman_exported_using": "Postman/8.0.3" -} \ No newline at end of file diff --git a/test/ssl-scripts.sh b/test/ssl-scripts.sh deleted file mode 100755 index 316f2ae..0000000 --- a/test/ssl-scripts.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -##### Server Ceritification Creation ##### -########################################## - -# CA configuration file: ca.cnf - -# create a new certificate authority using this configuration. -# we now have our certificate authority in ca_key.pem and ca_cert.pem -openssl req -new -x509 -days 9999 -config ./conf/ca.cnf -keyout ../certs/ca_key.pem -out ../certs/ca_cert.pem - -# generate a private key for the server. -openssl genrsa -out ../certs/server_key.pem 4096 - -# generate a certificate signing request -openssl req -new -config ./conf/server.cnf -key ../certs/server_key.pem -out ../certs/server_csr.pem - -# sign the request. -openssl x509 -req -extfile ./conf/server.cnf -days 999 -passin "pass:password" -in ../certs/server_csr.pem -CA ../certs/ca_cert.pem -CAkey ../certs/ca_key.pem -CAcreateserial -out ../certs/server_cert.pem - - -##### Client Ceritification Creation ##### -########################################## - -# create client key -openssl genrsa -out ../certs/client_key.pem 4096 - -# create certificate signing requests. -openssl req -new -config ./conf/client.cnf -key ../certs/client_key.pem -out ../certs/client_csr.pem - -# sign new client certs. -openssl x509 -req -extfile ./conf/client.cnf -days 999 -passin "pass:password" -in ../certs/client_csr.pem -CA ../certs/ca_cert.pem -CAkey ../certs/ca_key.pem -CAcreateserial -out ../certs/client_cert.pem - -# verify our certs -echo -echo "verifying server certs" -echo -openssl verify -CAfile ../certs/ca_cert.pem ../certs/server_cert.pem -echo -echo "verifying client certs" -openssl verify -CAfile ../certs/ca_cert.pem ../certs/client_cert.pem -echo - - -echo -echo "note: restart node server to load new certs" -echo - -# test after restarting node server -# use -v to see details in verbose mode -# curl --insecure --key ../certs/client_key.pem --cert ../certs/client_cert.pem https://localhost:5000/api -# curl --insecure --key ../certs/client_key.pem --cert ../certs/client_cert.pem https://localhost:5000/terra -# curl --insecure --key ../certs/client_key.pem --cert ../certs/client_cert.pem https://localhost:5000/balancer - diff --git a/yarn-error.log b/yarn-error.log deleted file mode 100644 index 4a426e3..0000000 --- a/yarn-error.log +++ /dev/null @@ -1,4329 +0,0 @@ -Arguments: - /usr/local/Cellar/node@10/10.21.0/bin/node /usr/local/Cellar/yarn/1.22.4/libexec/bin/yarn.js run dev - -PATH: - /Library/Frameworks/Python.framework/Versions/3.8/bin:/Users/yzhang1994/anaconda3/bin:/Users/yzhang1994/anaconda3/condabin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/usr/local/go/bin:/usr/local/MacGPG2/bin:/usr/local/share/dotnet:/opt/X11/bin:~/.dotnet/tools:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/usr/local/mysql/bin - -Yarn version: - 1.22.4 - -Node version: - 10.21.0 - -Platform: - darwin x64 - -Trace: - SyntaxError: /Users/yzhang1994/Documents/CoinAlpha/gateway-api/package.json: Unexpected token } in JSON at position 1179 - at JSON.parse () - at /usr/local/Cellar/yarn/1.22.4/libexec/lib/cli.js:1625:59 - at Generator.next () - at step (/usr/local/Cellar/yarn/1.22.4/libexec/lib/cli.js:310:30) - at /usr/local/Cellar/yarn/1.22.4/libexec/lib/cli.js:321:13 - -npm manifest: - { - "name": "gateway-api", - "version": "0.0.1", - "description": "Gateway API for protocol", - "main": "index.js", - "license": "MIT", - "scripts": { - "start": "node src/index.js", - "dev": "nodemon --exec babel-node src/index.js", - "debug": "DEBUG=*router nodemon --exec babel-node src/index.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "@balancer-labs/sor": "^0.3.3", - "@terra-money/terra.js": "^0.4.19-beta.1", - "bignumber.js": "^9.0.0", - "body-parser": "^1.19.0", - "capture-console": "^1.0.1", - "debug": "^4.2.0", - "dotenv": "^8.2.0", - "ethers": "^5.0.14", - "express": "^4.17.1", - "express-ipfilter": "^1.1.2", - "helmet": "^4.1.1", - "http-status-codes": "^2.1.3", - "lodash": "^4.17.20", - "util": "^0.12.3" - }, - "devDependencies": { - "@babel/core": "^7.11.6", - "@babel/node": "^7.10.5", - "@babel/preset-env": "^7.11.5", - "eslint": "^7.10.0", - "eslint-config-standard": "^14.1.1", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^4.0.1", - "nodemon": "^2.0.4" - }, - } - -yarn manifest: - No manifest - -Lockfile: - # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. - # yarn lockfile v1 - - - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== - dependencies: - "@babel/highlight" "^7.10.4" - - "@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" - integrity sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ== - dependencies: - browserslist "^4.12.0" - invariant "^2.2.4" - semver "^5.5.0" - - "@babel/core@^7.11.6": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" - integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.6" - "@babel/helper-module-transforms" "^7.11.0" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.5" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.5" - "@babel/types" "^7.11.5" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - - "@babel/generator@^7.11.5", "@babel/generator@^7.11.6": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" - integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== - dependencies: - "@babel/types" "^7.11.5" - jsesc "^2.5.1" - source-map "^0.5.0" - - "@babel/helper-annotate-as-pure@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" - integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== - dependencies: - "@babel/types" "^7.10.4" - - "@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" - integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.4" - "@babel/types" "^7.10.4" - - "@babel/helper-compilation-targets@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" - integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== - dependencies: - "@babel/compat-data" "^7.10.4" - browserslist "^4.12.0" - invariant "^2.2.4" - levenary "^1.1.1" - semver "^5.5.0" - - "@babel/helper-create-class-features-plugin@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" - integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.10.5" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - - "@babel/helper-create-regexp-features-plugin@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" - integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - regexpu-core "^4.7.0" - - "@babel/helper-define-map@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" - integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/types" "^7.10.5" - lodash "^4.17.19" - - "@babel/helper-explode-assignable-expression@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" - integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ== - dependencies: - "@babel/types" "^7.10.4" - - "@babel/helper-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" - integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - - "@babel/helper-get-function-arity@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" - integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== - dependencies: - "@babel/types" "^7.10.4" - - "@babel/helper-hoist-variables@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" - integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== - dependencies: - "@babel/types" "^7.10.4" - - "@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" - integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== - dependencies: - "@babel/types" "^7.11.0" - - "@babel/helper-module-imports@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" - integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== - dependencies: - "@babel/types" "^7.10.4" - - "@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" - integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/template" "^7.10.4" - "@babel/types" "^7.11.0" - lodash "^4.17.19" - - "@babel/helper-optimise-call-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" - integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== - dependencies: - "@babel/types" "^7.10.4" - - "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== - - "@babel/helper-regex@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" - integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== - dependencies: - lodash "^4.17.19" - - "@babel/helper-remap-async-to-generator@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz#4474ea9f7438f18575e30b0cac784045b402a12d" - integrity sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-wrap-function" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - - "@babel/helper-replace-supers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" - integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - - "@babel/helper-simple-access@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" - integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== - dependencies: - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - - "@babel/helper-skip-transparent-expression-wrappers@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" - integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== - dependencies: - "@babel/types" "^7.11.0" - - "@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" - integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== - dependencies: - "@babel/types" "^7.11.0" - - "@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== - - "@babel/helper-wrap-function@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" - integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - - "@babel/helpers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" - integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== - dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - - "@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - chalk "^2.0.0" - js-tokens "^4.0.0" - - "@babel/node@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.10.5.tgz#30866322aa2c0251a9bdd73d07a9167bd1f4ed64" - integrity sha512-suosS7zZ2roj+fYVCnDuVezUbRc0sdoyF0Gj/1FzWxD4ebbGiBGtL5qyqHH4NO34B5m4vWWYWgyNhSsrqS8vwA== - dependencies: - "@babel/register" "^7.10.5" - commander "^4.0.1" - core-js "^3.2.1" - lodash "^4.17.19" - node-environment-flags "^1.0.5" - regenerator-runtime "^0.13.4" - resolve "^1.13.1" - v8flags "^3.1.1" - - "@babel/parser@^7.10.4", "@babel/parser@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" - integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== - - "@babel/plugin-proposal-async-generator-functions@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" - integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.10.4" - "@babel/plugin-syntax-async-generators" "^7.8.0" - - "@babel/plugin-proposal-class-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" - integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-proposal-dynamic-import@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" - integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - - "@babel/plugin-proposal-export-namespace-from@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz#570d883b91031637b3e2958eea3c438e62c05f54" - integrity sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - - "@babel/plugin-proposal-json-strings@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" - integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.0" - - "@babel/plugin-proposal-logical-assignment-operators@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz#9f80e482c03083c87125dee10026b58527ea20c8" - integrity sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - - "@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" - integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - - "@babel/plugin-proposal-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" - integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - - "@babel/plugin-proposal-object-rest-spread@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" - integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.10.4" - - "@babel/plugin-proposal-optional-catch-binding@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" - integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - - "@babel/plugin-proposal-optional-chaining@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" - integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - - "@babel/plugin-proposal-private-methods@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" - integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" - integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-syntax-async-generators@^7.8.0": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-class-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" - integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-syntax-dynamic-import@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - - "@babel/plugin-syntax-json-strings@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-syntax-object-rest-spread@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-optional-catch-binding@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-optional-chaining@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-top-level-await@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" - integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-arrow-functions@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" - integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-async-to-generator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" - integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.10.4" - - "@babel/plugin-transform-block-scoped-functions@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" - integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-block-scoping@^7.10.4": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz#5b7efe98852bef8d652c0b28144cd93a9e4b5215" - integrity sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-classes@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" - integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-define-map" "^7.10.4" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - globals "^11.1.0" - - "@babel/plugin-transform-computed-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" - integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-destructuring@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" - integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" - integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-duplicate-keys@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" - integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-exponentiation-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" - integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-for-of@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" - integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" - integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" - integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-member-expression-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" - integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-modules-amd@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" - integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== - dependencies: - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helper-plugin-utils" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - - "@babel/plugin-transform-modules-commonjs@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" - integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== - dependencies: - "@babel/helper-module-transforms" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - - "@babel/plugin-transform-modules-systemjs@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85" - integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw== - dependencies: - "@babel/helper-hoist-variables" "^7.10.4" - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helper-plugin-utils" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - - "@babel/plugin-transform-modules-umd@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" - integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== - dependencies: - "@babel/helper-module-transforms" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" - integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - - "@babel/plugin-transform-new-target@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" - integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-object-super@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" - integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - - "@babel/plugin-transform-parameters@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a" - integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-property-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" - integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-regenerator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" - integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== - dependencies: - regenerator-transform "^0.14.2" - - "@babel/plugin-transform-reserved-words@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" - integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-shorthand-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" - integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-spread@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" - integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" - - "@babel/plugin-transform-sticky-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" - integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - - "@babel/plugin-transform-template-literals@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c" - integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-typeof-symbol@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" - integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-unicode-escapes@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" - integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-transform-unicode-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" - integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/preset-env@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272" - integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA== - dependencies: - "@babel/compat-data" "^7.11.0" - "@babel/helper-compilation-targets" "^7.10.4" - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-proposal-async-generator-functions" "^7.10.4" - "@babel/plugin-proposal-class-properties" "^7.10.4" - "@babel/plugin-proposal-dynamic-import" "^7.10.4" - "@babel/plugin-proposal-export-namespace-from" "^7.10.4" - "@babel/plugin-proposal-json-strings" "^7.10.4" - "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" - "@babel/plugin-proposal-numeric-separator" "^7.10.4" - "@babel/plugin-proposal-object-rest-spread" "^7.11.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" - "@babel/plugin-proposal-optional-chaining" "^7.11.0" - "@babel/plugin-proposal-private-methods" "^7.10.4" - "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.0" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.10.4" - "@babel/plugin-transform-arrow-functions" "^7.10.4" - "@babel/plugin-transform-async-to-generator" "^7.10.4" - "@babel/plugin-transform-block-scoped-functions" "^7.10.4" - "@babel/plugin-transform-block-scoping" "^7.10.4" - "@babel/plugin-transform-classes" "^7.10.4" - "@babel/plugin-transform-computed-properties" "^7.10.4" - "@babel/plugin-transform-destructuring" "^7.10.4" - "@babel/plugin-transform-dotall-regex" "^7.10.4" - "@babel/plugin-transform-duplicate-keys" "^7.10.4" - "@babel/plugin-transform-exponentiation-operator" "^7.10.4" - "@babel/plugin-transform-for-of" "^7.10.4" - "@babel/plugin-transform-function-name" "^7.10.4" - "@babel/plugin-transform-literals" "^7.10.4" - "@babel/plugin-transform-member-expression-literals" "^7.10.4" - "@babel/plugin-transform-modules-amd" "^7.10.4" - "@babel/plugin-transform-modules-commonjs" "^7.10.4" - "@babel/plugin-transform-modules-systemjs" "^7.10.4" - "@babel/plugin-transform-modules-umd" "^7.10.4" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" - "@babel/plugin-transform-new-target" "^7.10.4" - "@babel/plugin-transform-object-super" "^7.10.4" - "@babel/plugin-transform-parameters" "^7.10.4" - "@babel/plugin-transform-property-literals" "^7.10.4" - "@babel/plugin-transform-regenerator" "^7.10.4" - "@babel/plugin-transform-reserved-words" "^7.10.4" - "@babel/plugin-transform-shorthand-properties" "^7.10.4" - "@babel/plugin-transform-spread" "^7.11.0" - "@babel/plugin-transform-sticky-regex" "^7.10.4" - "@babel/plugin-transform-template-literals" "^7.10.4" - "@babel/plugin-transform-typeof-symbol" "^7.10.4" - "@babel/plugin-transform-unicode-escapes" "^7.10.4" - "@babel/plugin-transform-unicode-regex" "^7.10.4" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.11.5" - browserslist "^4.12.0" - core-js-compat "^3.6.2" - invariant "^2.2.2" - levenary "^1.1.1" - semver "^5.5.0" - - "@babel/preset-modules@^0.1.3": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" - integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - - "@babel/register@^7.10.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.11.5.tgz#79becf89e0ddd0fba8b92bc279bc0f5d2d7ce2ea" - integrity sha512-CAml0ioKX+kOAvBQDHa/+t1fgOt3qkTIz0TrRtRAT6XY0m5qYZXR85k6/sLCNPMGhYDlCFHCYuU0ybTJbvlC6w== - dependencies: - find-cache-dir "^2.0.0" - lodash "^4.17.19" - make-dir "^2.1.0" - pirates "^4.0.0" - source-map-support "^0.5.16" - - "@babel/runtime@^7.8.4": - version "7.11.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" - integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== - dependencies: - regenerator-runtime "^0.13.4" - - "@babel/template@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" - - "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" - integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.5" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.11.5" - "@babel/types" "^7.11.5" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.19" - - "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.4": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" - integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - - "@balancer-labs/sor@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-0.3.3.tgz#726a589094e4b9d25116cde5a1c0e154f132713e" - integrity sha512-hdPp55A2Hw+Koq81nhqTy15jNRCDW1k5ZT47nk2uEx7N5D9GiAx4BCNDzTiuJLErj6QHJTbEKK7Y5jei702c4g== - dependencies: - bignumber.js "^9.0.0" - isomorphic-fetch "^2.2.1" - - "@eslint/eslintrc@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.1.3.tgz#7d1a2b2358552cc04834c0979bd4275362e37085" - integrity sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA== - dependencies: - ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - lodash "^4.17.19" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - - "@ethersproject/abi@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.5.tgz#6e7bbf9d014791334233ba18da85331327354aa1" - integrity sha512-FNx6UMm0LnmCMFzN3urohFwZpjbUHPvc/O60h4qkF4yiJxLJ/G7QOSPjkHQ/q/QibagR4S7OKQawRy0NcvWa9w== - dependencies: - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - - "@ethersproject/abstract-provider@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.4.tgz#ef12df8cb5e66d0d47b567ad6ed642d682043773" - integrity sha512-EOCHUTS8jOE3WZlA1pq9b/vQwKDyDzMy4gXeAv0wZecH1kwUkD0++x8avxeSYoWI+aJn62P1FVV9B6r9pM56kQ== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" - - "@ethersproject/abstract-signer@^5.0.4": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.5.tgz#d1cdea6b0b82fb8e4a83f6899ba84d3dc3bb6e66" - integrity sha512-nwSZKtCTKhJADlW42c+a//lWxQlnA7jYLTnabJ3YCfgGU6ic9jnT9nRDlAyT1U3kCMeqPL7fTcKbdWCVrM0xsw== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - - "@ethersproject/address@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.4.tgz#8669bcbd02f4b64f4cede0a10e84df6d964ec9d3" - integrity sha512-CIjAeG6zNehbpJTi0sgwUvaH2ZICiAV9XkCBaFy5tjuEVFpQNeqd6f+B7RowcNO7Eut+QbhcQ5CVLkmP5zhL9A== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/rlp" "^5.0.3" - bn.js "^4.4.0" - - "@ethersproject/base64@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.3.tgz#d0aaa32c9ab08e2d62a6238581607ab6e929297e" - integrity sha512-sFq+/UwGCQsLxMvp7yO7yGWni87QXoV3C3IfjqUSY2BHkbZbCDm+PxZviUkiKf+edYZ2Glp0XnY7CgKSYUN9qw== - dependencies: - "@ethersproject/bytes" "^5.0.4" - - "@ethersproject/basex@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.3.tgz#f8c9bc449a089131f52cfa8698cf77bc22e27e32" - integrity sha512-EvoER+OXsMAZlvbC0M/9UTxjvbBvTccYCI+uCAhXw+eS1+SUdD4v7ekAFpVX78rPLrLZB1vChKMm6vPHIu3WRA== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/properties" "^5.0.3" - - "@ethersproject/bignumber@^5.0.7": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.7.tgz#720b3e3df3e125a99669ee869478106d0afe7b76" - integrity sha512-wwKgDJ+KA7IpgJwc8Fc0AjKIRuDskKA2cque29/+SgII9/1K/38JpqVNPKIovkLwTC2DDofIyzHcxeaKpMFouQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - bn.js "^4.4.0" - - "@ethersproject/bytes@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.4.tgz#328d9d929a3e970964ecf5d62e12568a187189f1" - integrity sha512-9R6A6l9JN8x1U4s1dJCR+9h3MZTT3xQofr/Xx8wbDvj6NnY4CbBB0o8ZgHXvR74yV90pY2EzCekpkMBJnRzkSw== - dependencies: - "@ethersproject/logger" "^5.0.5" - - "@ethersproject/constants@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.4.tgz#9ddaa5f3c738a94e5adc4b3f71b36206fa5cdf88" - integrity sha512-Df32lcXDHPgZRPgp1dgmByNbNe4Ki1QoXR+wU61on5nggQGTqWR1Bb7pp9VtI5Go9kyE/JflFc4Te6o9MvYt8A== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - - "@ethersproject/contracts@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.0.4.tgz#27a2d7e3a7eef9bd8d006824ac2a74157b523988" - integrity sha512-gfOZNgLiO9e1D/hmQ4sEyqoolw6jDFVfqirGJv3zyFKNyX+lAXLN7YAZnnWVmp4GU1jiMtSqQKjpWp7r6ihs3Q== - dependencies: - "@ethersproject/abi" "^5.0.5" - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - - "@ethersproject/hash@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.4.tgz#385642786405d236f3d2f1acdfaf250ab519cdac" - integrity sha512-VCs/bFBU8AQFhHcT1cQH6x7a4zjulR6fJmAOcPxUgrN7bxOQ7QkpBKF+YCDJhFtkLdaljIsr/r831TuWU4Ysfg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/strings" "^5.0.4" - - "@ethersproject/hdnode@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.0.4.tgz#9c07a87781b24b9cae3507fe9404361c5870f1b7" - integrity sha512-eHmpNLvasfB4xbmQUvKXOsGF4ekjIKJH/eZm7fc6nIdMci9u5ERooSSRLjs9Dsa5QuJf6YD4DbqeJsT71n47iw== - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - - "@ethersproject/json-wallets@^5.0.6": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.0.6.tgz#c6c1818dcab18ecf3f37fa59ca504b9bc162d559" - integrity sha512-BPCfyGdwOUSp6+xA59IaZ/2pUWrUOL5Z9HuCh8YLsJzkuyBJQN0j+z/PmhIiZ7X8ilhuE+pRUwXb42U/R39fig== - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - aes-js "3.0.0" - scrypt-js "3.0.1" - - "@ethersproject/keccak256@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.3.tgz#f094a8fca3bb913c044593c4f382be424292e588" - integrity sha512-VhW3mgZMBZlETV6AyOmjNeNG+Pg68igiKkPpat8/FZl0CKnfgQ+KZQZ/ee1vT+X0IUM8/djqnei6btmtbA27Ug== - dependencies: - "@ethersproject/bytes" "^5.0.4" - js-sha3 "0.5.7" - - "@ethersproject/logger@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.5.tgz#e3ba3d0bcf9f5be4da5f043b1e328eb98b80002f" - integrity sha512-gJj72WGzQhUtCk6kfvI8elTaPOQyMvrMghp/nbz0ivTo39fZ7IjypFh/ySDeUSdBNplAwhzWKKejQhdpyefg/w== - - "@ethersproject/networks@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.3.tgz#c4ebe56e79ca399247382627e50a022aa68ece55" - integrity sha512-Gjpejul6XFetJXyvHCd37IiCC00203kYGU9sMaRMZcAcYKszCkbOeo/Q7Mmdr/fS7YBbB5iTOahDJWiRLu/b7A== - dependencies: - "@ethersproject/logger" "^5.0.5" - - "@ethersproject/pbkdf2@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.0.3.tgz#f9eca284a458cd11179d407884c595412d8d2775" - integrity sha512-asc+YgJn7v7GKWYXGz3GM1d9XYI2HvdCw1cLEow2niEC9BfYA29rr1exz100zISk95GIU1YP2zV//zHsMtWE5Q== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/sha2" "^5.0.3" - - "@ethersproject/properties@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.3.tgz#991aef39a5f87d4645cee76cec4df868bfb08be6" - integrity sha512-wLCSrbywkQgTO6tIF9ZdKsH9AIxPEqAJF/z5xcPkz1DK4mMAZgAXRNw1MrKYhyb+7CqNHbj3vxenNKFavGY/IA== - dependencies: - "@ethersproject/logger" "^5.0.5" - - "@ethersproject/providers@^5.0.8": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.0.9.tgz#88b48596dcfb0848a89da3160d2e2a055fc899f6" - integrity sha512-UtGrlJxekFNV7lriPOxQbnYminyiwTgjHMPX83pG7N/W/t+PekQK8V9rdlvMr2bRyGgafHml0ZZMaTV4FxiBYg== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" - bech32 "1.1.4" - ws "7.2.3" - - "@ethersproject/random@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.0.3.tgz#ec16546fffdc10b9082f1207bd3a09f54cbcf5e6" - integrity sha512-pEhWRbgNeAY1oYk4nIsEtCTh9TtLsivIDbOX11n+DLZLYM3c8qCLxThXtsHwVsMs1JHClZr5auYC4YxtVVzO/A== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - - "@ethersproject/rlp@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.3.tgz#841a5edfdf725f92155fe74424f5510c9043c13a" - integrity sha512-Hz4yyA/ilGafASAqtTlLWkA/YqwhQmhbDAq2LSIp1AJNx+wtbKWFAKSckpeZ+WG/xZmT+fw5OFKK7a5IZ4DR5g== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - - "@ethersproject/sha2@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.0.3.tgz#52c16edc1135d0ec7d242d88eed035dae72800c0" - integrity sha512-B1U9UkgxhUlC1J4sFUL2GwTo33bM2i/aaD3aiYdTh1FEXtGfqYA89KN1DJ83n+Em8iuvyiBRk6u30VmgqlHeHA== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - hash.js "1.1.3" - - "@ethersproject/signing-key@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.4.tgz#a5334ce8a52d4e9736dc8fb6ecc384704ecf8783" - integrity sha512-I6pJoga1IvhtjYK5yXzCjs4ZpxrVbt9ZRAlpEw0SW9UuV020YfJH5EIVEGR2evdRceS3nAQIggqbsXSkP8Y1Dg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - elliptic "6.5.3" - - "@ethersproject/solidity@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.0.4.tgz#67022cbfb50cb73b72d1739178537a9e798945bf" - integrity sha512-cUq1l8A+AgRkIItRoztC98Qx7b0bMNMzKX817fszDuGNsT2POAyP5knvuEt4Fx4IBcJREXoOjsGYFfjyK5Sa+w== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - - "@ethersproject/strings@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.4.tgz#67cda604eee3ffcc004cb9f3bd03516e1c7b09a0" - integrity sha512-azXFHaNkDXzefhr4LVVzzDMFwj3kH9EOKlATu51HjxabQafuUyVLPFgmxRFmCynnAi0Bmmp7nr+qK1pVDgRDLQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - - "@ethersproject/transactions@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.5.tgz#9a966f9ef4817b1752265d4efee0f1e9fd6aeaad" - integrity sha512-1Ga/QmbcB74DItggP8/DK1tggu4ErEvwTkIwIlUXUcvIAuRNXXE7kgQhlp+w1xA/SAQFhv56SqCoyqPiiLCvVA== - dependencies: - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - - "@ethersproject/units@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.0.4.tgz#e08876b54e1f6b362a841dcd986496a425875735" - integrity sha512-80d6skjDgiHLdbKOA9FVpzyMEPwbif40PbGd970JvcecVf48VjB09fUu37d6duG8DhRVyefRdX8nuVQLzcGGPw== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - - "@ethersproject/wallet@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.0.4.tgz#b414ae2870fc0ea10808330f0ab3c5a1ac9e34e1" - integrity sha512-h/3mdy6HZVketHbs6ZP/WjHDz+rtTIE3qZrko2MVeafjgDcYWaHcVmhsPq4LGqxginhr191a4dkJDNeQrQZWOw== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/json-wallets" "^5.0.6" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - - "@ethersproject/web@^5.0.6": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.7.tgz#ab8ccffa9cee9469a8b49af8b8fee30e384e59d8" - integrity sha512-BM8FdGrzdcULYaOIyMXDKvxv+qOwGne8FKpPxUrifZIWAWPrq/y+oBOZlzadIKsP3wvYbAcMN2CgOLO1E3yIfw== - dependencies: - "@ethersproject/base64" "^5.0.3" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - - "@ethersproject/wordlists@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.0.4.tgz#76a7e1dfd95aea645f6be2c1932b3f89b7f0c4ce" - integrity sha512-z/NsGqdYFvpeG6vPLxuD0pYNR5lLhQAy+oLVqg6G0o1c/OoL5J/a0iDOAFvnacQphc3lMP52d1LEX3YGoy2oBQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - - "@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - - "@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - - "@terra-money/terra.js@^0.4.19-beta.1": - version "0.4.19-beta.1" - resolved "https://registry.yarnpkg.com/@terra-money/terra.js/-/terra.js-0.4.19-beta.1.tgz#2b85e2c508041d1b874da9304c9e3553ce766358" - integrity sha512-ipaOIi5XJUJyLyv+o04fupytJrh4bgd7BwU+FDhrIWjT0s4UHJWgYI9iqYonKbiy1gTw0t/8y80XRXuQ47pUqw== - dependencies: - axios "^0.20.0" - bech32 "^1.1.4" - bip32 "^2.0.5" - bip39 "^3.0.2" - crypto-js "3.3.0" - decimal.js "^10.2.0" - post-message-stream "^3.0.0" - secp256k1 "^4.0.2" - - "@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== - - "@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - - "@types/node@10.12.18": - version "10.12.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" - integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== - - "@types/node@11.11.6": - version "11.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" - integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== - - abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - - accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - - acorn-jsx@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== - - acorn@^7.4.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" - integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== - - aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= - - ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4: - version "6.12.5" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" - integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - - ansi-align@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" - integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== - dependencies: - string-width "^3.0.0" - - ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - - ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - - ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - - ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - - ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - - anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - - argle@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/argle/-/argle-1.1.1.tgz#0cfe3bc032c36b2f48ba42b9c17f89f70607e994" - integrity sha1-DP47wDLDay9IukK5wX+J9wYH6ZQ= - dependencies: - lodash.isfunction "^3.0.8" - lodash.isnumber "^3.0.3" - - argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - - array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - - array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - - array-includes@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" - integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0" - is-string "^1.0.5" - - array-uniq@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.2.tgz#5fcc373920775723cfd64d65c64bef53bf9eba6d" - integrity sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0= - - array.prototype.flat@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" - integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - - astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - - available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== - dependencies: - array-filter "^1.0.0" - - axios@^0.20.0: - version "0.20.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd" - integrity sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA== - dependencies: - follow-redirects "^1.10.0" - - babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - - balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - - base-x@^3.0.2: - version "3.0.8" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" - integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== - dependencies: - safe-buffer "^5.0.1" - - bech32@1.1.4, bech32@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - - bignumber.js@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" - integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== - - binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== - - bindings@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - - bip32@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.5.tgz#e3808a9e97a880dbafd0f5f09ca4a1e14ee275d2" - integrity sha512-zVY4VvJV+b2fS0/dcap/5XLlpqtgwyN8oRkuGgAS1uLOeEp0Yo6Tw2yUTozTtlrMJO3G8n4g/KX/XGFHW6Pq3g== - dependencies: - "@types/node" "10.12.18" - bs58check "^2.1.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - tiny-secp256k1 "^1.1.3" - typeforce "^1.11.5" - wif "^2.0.6" - - bip39@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.2.tgz#2baf42ff3071fc9ddd5103de92e8f80d9257ee32" - integrity sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ== - dependencies: - "@types/node" "11.11.6" - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - - bn.js@^4.11.8, bn.js@^4.4.0: - version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" - integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== - - body-parser@1.19.0, body-parser@^1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - - boxen@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" - integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^5.3.1" - chalk "^3.0.0" - cli-boxes "^2.2.0" - string-width "^4.1.0" - term-size "^2.1.0" - type-fest "^0.8.1" - widest-line "^3.1.0" - - brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - - braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - - brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - - browserslist@^4.12.0, browserslist@^4.8.5: - version "4.14.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.3.tgz#381f9e7f13794b2eb17e1761b4f118e8ae665a53" - integrity sha512-GcZPC5+YqyPO4SFnz48/B0YaCwS47Q9iPChRGi6t7HhflKBcINzFrJvRfC+jp30sRMKxF+d4EHGs27Z0XP1NaQ== - dependencies: - caniuse-lite "^1.0.30001131" - electron-to-chromium "^1.3.570" - escalade "^3.1.0" - node-releases "^1.1.61" - - bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= - dependencies: - base-x "^3.0.2" - - bs58check@<3.0.0, bs58check@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - - buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - - bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - - cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - - callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - - camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - - caniuse-lite@^1.0.30001131: - version "1.0.30001133" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001133.tgz#ec564c5495311299eb05245e252d589a84acd95e" - integrity sha512-s3XAUFaC/ntDb1O3lcw9K8MPeOW7KO3z9+GzAoBxfz1B0VdacXPMKgFUtG4KIsgmnbexmi013s9miVu4h+qMHw== - - capture-console@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/capture-console/-/capture-console-1.0.1.tgz#db63c39ac73239019badd7fbb10143eda380ff71" - integrity sha1-22PDmscyOQGbrdf7sQFD7aOA/3E= - dependencies: - argle "~1.1.1" - lodash.isfunction "~3.0.8" - randomstring "~1.1.5" - - chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - - chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - - chalk@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - - chokidar@^3.2.2: - version "3.4.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" - integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.4.0" - optionalDependencies: - fsevents "~2.1.2" - - ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - - cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - - cli-boxes@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - - clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - - color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - - color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - - color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - - color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - - commander@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - - commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - - concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - - configstore@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" - integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== - dependencies: - dot-prop "^5.2.0" - graceful-fs "^4.1.2" - make-dir "^3.0.0" - unique-string "^2.0.0" - write-file-atomic "^3.0.0" - xdg-basedir "^4.0.0" - - contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - - content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - - content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - - convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - - cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - - cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - - core-js-compat@^3.6.2: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" - integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== - dependencies: - browserslist "^4.8.5" - semver "7.0.0" - - core-js@^3.2.1: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" - integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== - - core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - - create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - - create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - - cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - - crypto-js@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" - integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== - - crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - - debug@2.6.9, debug@^2.2.0, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - - debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - - debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== - dependencies: - ms "2.1.2" - - decimal.js@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231" - integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw== - - decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - - deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - - deep-is@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - - defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - - define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - - depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - - destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - - doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - - doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - - dot-prop@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - - dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== - - duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - - ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - - electron-to-chromium@^1.3.570: - version "1.3.570" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.570.tgz#3f5141cc39b4e3892a276b4889980dabf1d29c7f" - integrity sha512-Y6OCoVQgFQBP5py6A/06+yWxUZHDlNr/gNDGatjH8AZqXl8X0tE4LfjLJsXGz/JmWJz8a6K7bR1k+QzZ+k//fg== - - elliptic@6.5.3, elliptic@^6.4.0, elliptic@^6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" - integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - 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" - - emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - - emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - - encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - - encoding@^0.1.11: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - - end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - - enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - - error-ex@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - - es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - - es-abstract@^1.18.0-next.0: - version "1.18.0-next.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.0.tgz#b302834927e624d8e5837ed48224291f2c66e6fc" - integrity sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-negative-zero "^2.0.0" - is-regex "^1.1.1" - object-inspect "^1.8.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - - es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - - escalade@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e" - integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig== - - escape-goat@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" - integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== - - escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - - escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - - eslint-config-standard@^14.1.1: - version "14.1.1" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" - integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg== - - eslint-import-resolver-node@^0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" - integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== - dependencies: - debug "^2.6.9" - resolve "^1.13.1" - - eslint-module-utils@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" - integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== - dependencies: - debug "^2.6.9" - pkg-dir "^2.0.0" - - eslint-plugin-es@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" - integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - - eslint-plugin-import@^2.22.1: - version "2.22.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" - integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== - dependencies: - array-includes "^3.1.1" - array.prototype.flat "^1.2.3" - contains-path "^0.1.0" - debug "^2.6.9" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.0" - has "^1.0.3" - minimatch "^3.0.4" - object.values "^1.1.1" - read-pkg-up "^2.0.0" - resolve "^1.17.0" - tsconfig-paths "^3.9.0" - - eslint-plugin-node@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" - integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== - dependencies: - eslint-plugin-es "^3.0.0" - eslint-utils "^2.0.0" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - - eslint-plugin-promise@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" - integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== - - eslint-plugin-standard@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" - integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== - - eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - - eslint-utils@^2.0.0, eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - - eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - - eslint@^7.10.0: - version "7.10.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.10.0.tgz#494edb3e4750fb791133ca379e786a8f648c72b9" - integrity sha512-BDVffmqWl7JJXqCjAK6lWtcQThZB/aP1HXSH1JKwGwv0LQEdvpR7qzNrUT487RM39B5goWuboFad5ovMBmD8yA== - dependencies: - "@babel/code-frame" "^7.0.0" - "@eslint/eslintrc" "^0.1.3" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^1.3.0" - espree "^7.3.0" - esquery "^1.2.0" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash "^4.17.19" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - - espree@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348" - integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.3.0" - - esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - - esquery@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" - integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== - dependencies: - estraverse "^5.1.0" - - esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - - estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - - estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - - esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - - etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - - ethers@^5.0.14: - version "5.0.14" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.0.14.tgz#fc33613ff3c1eb04c481f32083f2be315079e2a2" - integrity sha512-6WkoYwAURTr/4JiSZlrMJ9mm3pBv/bWrOu7sVXdLGw9QU4cp/GDZVrKKnh5GafMTzanuNBJoaEanPCjsbe4Mig== - dependencies: - "@ethersproject/abi" "^5.0.5" - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/base64" "^5.0.3" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/contracts" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/json-wallets" "^5.0.6" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/providers" "^5.0.8" - "@ethersproject/random" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/solidity" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/units" "^5.0.4" - "@ethersproject/wallet" "^5.0.4" - "@ethersproject/web" "^5.0.6" - "@ethersproject/wordlists" "^5.0.4" - - express-ipfilter@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/express-ipfilter/-/express-ipfilter-1.1.2.tgz#536e1b8922f00df45d6da8796b02a75b1033a20f" - integrity sha512-dm1G3sVxlSbcOWSxfUTCo20ySyNQXJ4hJD5fuQJFoZlhkQvpbuDGBlh8AbFm1GwX85EWvfyhekOkvcydaXkBkg== - dependencies: - ip "~1.1.0" - lodash "^4.17.11" - proxy-addr "^2.0.4" - range_check "^1.2.0" - - express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - - fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - - fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - - fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - - file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - - file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - - fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - - finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - - find-cache-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - - find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - - find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - - flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - - flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - - follow-redirects@^1.10.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" - integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== - - foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - - forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - - fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - - fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - - fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - - function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - - functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - - gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== - - get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - - get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - - glob-parent@^5.0.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== - dependencies: - is-glob "^4.0.1" - - glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - - global-dirs@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201" - integrity sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A== - dependencies: - ini "^1.3.5" - - globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - - globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - - got@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - - graceful-fs@^4.1.2: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - - has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - - has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - - has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - - has-yarn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" - integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== - - has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - - hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - - hash.js@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.0" - - hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - - helmet@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/helmet/-/helmet-4.1.1.tgz#751f0e273d809ace9c172073e0003bed27d27a4a" - integrity sha512-Avg4XxSBrehD94mkRwEljnO+6RZx7AGfk8Wa6K1nxaU+hbXlFOhlOIMgPfFqOYQB/dBCsTpootTGuiOG+CHiQA== - - hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - - homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== - dependencies: - parse-passwd "^1.0.0" - - hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - - http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - - http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - - http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - - http-status-codes@^2.1.3: - version "2.1.4" - resolved "https://registry.yarnpkg.com/http-status-codes/-/http-status-codes-2.1.4.tgz#453d99b4bd9424254c4f6a9a3a03715923052798" - integrity sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg== - - iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - - iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" - integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - - ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= - - ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - - ignore@^5.1.1: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - - import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - - import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - - imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - - inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - - inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - - inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - - ini@^1.3.5, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - - invariant@^2.2.2, invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - - ip6@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/ip6/-/ip6-0.0.4.tgz#44c5a9db79e39d405201b4d78d13b3870e48db31" - integrity sha1-RMWp23njnUBSAbTXjROzhw5I2zE= - - ip@~1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - - ipaddr.js@1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.2.0.tgz#8aba49c9192799585bdd643e0ccb50e8ae777ba4" - integrity sha1-irpJyRknmVhb3WQ+DMtQ6K53e6Q= - - ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - - is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== - - is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - - is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - - is-callable@^1.1.4, is-callable@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" - integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== - - is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - - is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - - is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - - is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - - is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - - is-generator-function@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" - integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== - - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - - is-installed-globally@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" - integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== - dependencies: - global-dirs "^2.0.1" - is-path-inside "^3.0.1" - - is-negative-zero@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" - integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= - - is-npm@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" - integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== - - is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - - is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - - is-path-inside@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" - integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== - - is-regex@^1.1.0, is-regex@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== - dependencies: - has-symbols "^1.0.1" - - is-stream@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - - is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - - is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - - is-typed-array@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.3.tgz#a4ff5a5e672e1a55f99c7f54e59597af5c1df04d" - integrity sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ== - dependencies: - available-typed-arrays "^1.0.0" - es-abstract "^1.17.4" - foreach "^2.0.5" - has-symbols "^1.0.1" - - is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - - is-yarn-global@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" - integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== - - isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - - isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - - isomorphic-fetch@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= - dependencies: - node-fetch "^1.0.1" - whatwg-fetch ">=0.10.0" - - js-sha3@0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= - - "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - - js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - - jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - - jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - - json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - - json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - - json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - - json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - - json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== - dependencies: - minimist "^1.2.5" - - keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - - latest-version@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" - integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== - dependencies: - package-json "^6.3.0" - - leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - - levenary@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" - integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== - dependencies: - leven "^3.1.0" - - levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - - load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - - locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - - locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - - lodash.isfunction@^3.0.8, lodash.isfunction@~3.0.8: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" - integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw== - - lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= - - lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== - - loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - - lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - - lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - - make-dir@^2.0.0, make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - - make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - - md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - - media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - - merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - - methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - - mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - - mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== - dependencies: - mime-db "1.44.0" - - mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - - mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - - minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - - minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - - minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - - minimist@^1.2.0, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - - mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - - ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - - ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - - ms@2.1.2, ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - - nan@^2.13.2: - version "2.14.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" - integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== - - natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - - negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - - node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - - node-environment-flags@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" - integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - - node-fetch@^1.0.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - - node-gyp-build@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" - integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg== - - node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - - node-releases@^1.1.61: - version "1.1.61" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e" - integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g== - - nodemon@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.4.tgz#55b09319eb488d6394aa9818148c0c2d1c04c416" - integrity sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ== - dependencies: - chokidar "^3.2.2" - debug "^3.2.6" - ignore-by-default "^1.0.1" - minimatch "^3.0.4" - pstree.remy "^1.1.7" - semver "^5.7.1" - supports-color "^5.5.0" - touch "^3.1.0" - undefsafe "^2.0.2" - update-notifier "^4.0.0" - - nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= - dependencies: - abbrev "1" - - normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - - normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - - normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== - - object-inspect@^1.7.0, object-inspect@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== - - object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - - object.assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" - integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.18.0-next.0" - has-symbols "^1.0.1" - object-keys "^1.1.1" - - object.getownpropertydescriptors@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - - object.values@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - - on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - - once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - - optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - - p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - - p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - - p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - - p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - - p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - - p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - - p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - - package-json@^6.3.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" - integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== - dependencies: - got "^9.6.0" - registry-auth-token "^4.0.0" - registry-url "^5.0.0" - semver "^6.2.0" - - parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - - parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - - parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= - - parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - - path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - - path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - - path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - - path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - - path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - - path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - - pbkdf2@^3.0.9: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - - picomatch@^2.0.4, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== - - pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - - pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - - pirates@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" - - pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - - pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - - post-message-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/post-message-stream/-/post-message-stream-3.0.0.tgz#90d9f54bd209e6b6f5d74795b87588205b547048" - integrity sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg= - dependencies: - readable-stream "^2.1.4" - - prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - - prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - - process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - - progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - - proxy-addr@^2.0.4, proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.1" - - pstree.remy@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" - integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== - - pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - - punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - - pupa@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726" - integrity sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA== - dependencies: - escape-goat "^2.0.0" - - qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - - randombytes@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - - randomstring@~1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/randomstring/-/randomstring-1.1.5.tgz#6df0628f75cbd5932930d9fe3ab4e956a18518c3" - integrity sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM= - dependencies: - array-uniq "1.0.2" - - range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - - range_check@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/range_check/-/range_check-1.4.0.tgz#cd87c7ac62c40ba9df69b8703c604f60c3748635" - integrity sha1-zYfHrGLEC6nfabhwPGBPYMN0hjU= - dependencies: - ip6 "0.0.4" - ipaddr.js "1.2" - - raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - - rc@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - - read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - - read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - - readable-stream@^2.1.4: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - - readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - - readdirp@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" - integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== - dependencies: - picomatch "^2.2.1" - - regenerate-unicode-properties@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" - integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== - dependencies: - regenerate "^1.4.0" - - regenerate@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" - integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== - - regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - - regenerator-transform@^0.14.2: - version "0.14.5" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" - integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== - dependencies: - "@babel/runtime" "^7.8.4" - - regexpp@^3.0.0, regexpp@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== - - regexpu-core@^4.7.0: - version "4.7.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" - integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.2.0" - regjsgen "^0.5.1" - regjsparser "^0.6.4" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.2.0" - - registry-auth-token@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.0.tgz#1d37dffda72bbecd0f581e4715540213a65eb7da" - integrity sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w== - dependencies: - rc "^1.2.8" - - registry-url@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" - integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== - dependencies: - rc "^1.2.8" - - regjsgen@^0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" - integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== - - regjsparser@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" - integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== - dependencies: - jsesc "~0.5.0" - - resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - - resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - - responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - - rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - - ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - - safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - - "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - - scrypt-js@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - - secp256k1@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" - integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg== - dependencies: - elliptic "^6.5.2" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - - semver-diff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" - integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== - dependencies: - semver "^6.3.0" - - "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - - semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - - semver@^6.0.0, semver@^6.1.0, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - - semver@^7.2.1: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - - send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - - serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - - setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - - sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - - shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - - shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - - signal-exit@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - - slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - - source-map-support@^0.5.16: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - - source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - - source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - - spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - - spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - - spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - - spdx-license-ids@^3.0.0: - version "3.0.6" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz#c80757383c28abf7296744998cbc106ae8b854ce" - integrity sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw== - - sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - - "statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - - string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - - string-width@^4.0.0, string-width@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - - string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - - string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - - string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - - string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - - strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - - strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - - strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - - strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - - strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - - supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - - supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - - table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - - term-size@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.0.tgz#1f16adedfe9bdc18800e1776821734086fcc6753" - integrity sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw== - - text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - - tiny-secp256k1@^1.1.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.5.tgz#3dc37b9bf0fa5b4390b9fa29e953228810cebc18" - integrity sha512-duE2hSLSQIpHGzmK48OgRrGTi+4OTkXLC6aa86uOYQ6LLCYZSarVKIAvEtY7MoXjoL6bOXMSerEGMzrvW4SkDw== - dependencies: - bindings "^1.3.0" - bn.js "^4.11.8" - create-hmac "^1.1.7" - elliptic "^6.4.0" - nan "^2.13.2" - - to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - - to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - - to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - - toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - - touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" - - tsconfig-paths@^3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" - integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - - type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - - type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - - type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - - typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - - typeforce@^1.11.5: - version "1.18.0" - resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" - integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== - - undefsafe@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" - integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== - dependencies: - debug "^2.2.0" - - unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== - - unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - - unicode-match-property-value-ecmascript@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" - integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== - - unicode-property-aliases-ecmascript@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" - integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== - - unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== - dependencies: - crypto-random-string "^2.0.0" - - unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - - update-notifier@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.1.tgz#895fc8562bbe666179500f9f2cebac4f26323746" - integrity sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg== - dependencies: - boxen "^4.2.0" - chalk "^3.0.0" - configstore "^5.0.1" - has-yarn "^2.1.0" - import-lazy "^2.1.0" - is-ci "^2.0.0" - is-installed-globally "^0.3.1" - is-npm "^4.0.0" - is-yarn-global "^0.3.0" - latest-version "^5.0.0" - pupa "^2.0.1" - semver-diff "^3.1.1" - xdg-basedir "^4.0.0" - - uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== - dependencies: - punycode "^2.1.0" - - url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - - util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - - util@^0.12.3: - version "0.12.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" - integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - safe-buffer "^5.1.2" - which-typed-array "^1.1.2" - - utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - - v8-compile-cache@^2.0.3: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" - integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== - - v8flags@^3.1.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" - integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== - dependencies: - homedir-polyfill "^1.0.1" - - validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - - vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - - whatwg-fetch@>=0.10.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3" - integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ== - - which-typed-array@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2" - integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ== - dependencies: - available-typed-arrays "^1.0.2" - es-abstract "^1.17.5" - foreach "^2.0.5" - function-bind "^1.1.1" - has-symbols "^1.0.1" - is-typed-array "^1.1.3" - - which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - - widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - - wif@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" - integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ= - dependencies: - bs58check "<3.0.0" - - word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - - wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - - write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - - write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - - ws@7.2.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" - integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== - - xdg-basedir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" - integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 3f41ed6..0000000 --- a/yarn.lock +++ /dev/null @@ -1,4690 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" - integrity sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ== - dependencies: - browserslist "^4.12.0" - invariant "^2.2.4" - semver "^5.5.0" - -"@babel/core@^7.11.6": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" - integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.6" - "@babel/helper-module-transforms" "^7.11.0" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.5" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.5" - "@babel/types" "^7.11.5" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.11.5", "@babel/generator@^7.11.6": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" - integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== - dependencies: - "@babel/types" "^7.11.5" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" - integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" - integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-compilation-targets@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" - integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== - dependencies: - "@babel/compat-data" "^7.10.4" - browserslist "^4.12.0" - invariant "^2.2.4" - levenary "^1.1.1" - semver "^5.5.0" - -"@babel/helper-create-class-features-plugin@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" - integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.10.5" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - -"@babel/helper-create-regexp-features-plugin@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" - integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - regexpu-core "^4.7.0" - -"@babel/helper-define-map@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" - integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/types" "^7.10.5" - lodash "^4.17.19" - -"@babel/helper-explode-assignable-expression@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" - integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" - integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-get-function-arity@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" - integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-hoist-variables@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" - integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" - integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-module-imports@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" - integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" - integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/template" "^7.10.4" - "@babel/types" "^7.11.0" - lodash "^4.17.19" - -"@babel/helper-optimise-call-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" - integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== - -"@babel/helper-regex@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" - integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== - dependencies: - lodash "^4.17.19" - -"@babel/helper-remap-async-to-generator@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz#4474ea9f7438f18575e30b0cac784045b402a12d" - integrity sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-wrap-function" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-replace-supers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" - integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-simple-access@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" - integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== - dependencies: - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" - integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" - integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== - -"@babel/helper-wrap-function@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" - integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helpers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" - integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== - dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/node@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.10.5.tgz#30866322aa2c0251a9bdd73d07a9167bd1f4ed64" - integrity sha512-suosS7zZ2roj+fYVCnDuVezUbRc0sdoyF0Gj/1FzWxD4ebbGiBGtL5qyqHH4NO34B5m4vWWYWgyNhSsrqS8vwA== - dependencies: - "@babel/register" "^7.10.5" - commander "^4.0.1" - core-js "^3.2.1" - lodash "^4.17.19" - node-environment-flags "^1.0.5" - regenerator-runtime "^0.13.4" - resolve "^1.13.1" - v8flags "^3.1.1" - -"@babel/parser@^7.10.4", "@babel/parser@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" - integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== - -"@babel/plugin-proposal-async-generator-functions@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" - integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.10.4" - "@babel/plugin-syntax-async-generators" "^7.8.0" - -"@babel/plugin-proposal-class-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" - integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-proposal-dynamic-import@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" - integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - -"@babel/plugin-proposal-export-namespace-from@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz#570d883b91031637b3e2958eea3c438e62c05f54" - integrity sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" - integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.0" - -"@babel/plugin-proposal-logical-assignment-operators@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz#9f80e482c03083c87125dee10026b58527ea20c8" - integrity sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" - integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - -"@babel/plugin-proposal-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" - integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" - integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.10.4" - -"@babel/plugin-proposal-optional-catch-binding@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" - integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - -"@babel/plugin-proposal-optional-chaining@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" - integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - -"@babel/plugin-proposal-private-methods@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" - integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" - integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-async-generators@^7.8.0": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" - integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-dynamic-import@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-json-strings@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-top-level-await@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" - integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-arrow-functions@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" - integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-async-to-generator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" - integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.10.4" - -"@babel/plugin-transform-block-scoped-functions@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" - integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-block-scoping@^7.10.4": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz#5b7efe98852bef8d652c0b28144cd93a9e4b5215" - integrity sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-classes@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" - integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-define-map" "^7.10.4" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" - integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-destructuring@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" - integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" - integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-duplicate-keys@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" - integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-exponentiation-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" - integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-for-of@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" - integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" - integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" - integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-member-expression-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" - integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-modules-amd@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" - integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== - dependencies: - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helper-plugin-utils" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-commonjs@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" - integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== - dependencies: - "@babel/helper-module-transforms" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-systemjs@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85" - integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw== - dependencies: - "@babel/helper-hoist-variables" "^7.10.4" - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helper-plugin-utils" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-umd@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" - integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== - dependencies: - "@babel/helper-module-transforms" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" - integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - -"@babel/plugin-transform-new-target@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" - integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-object-super@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" - integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - -"@babel/plugin-transform-parameters@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a" - integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-property-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" - integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-regenerator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" - integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== - dependencies: - regenerator-transform "^0.14.2" - -"@babel/plugin-transform-reserved-words@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" - integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-shorthand-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" - integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-spread@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" - integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" - -"@babel/plugin-transform-sticky-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" - integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - -"@babel/plugin-transform-template-literals@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c" - integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-typeof-symbol@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" - integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-unicode-escapes@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" - integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-unicode-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" - integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/preset-env@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272" - integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA== - dependencies: - "@babel/compat-data" "^7.11.0" - "@babel/helper-compilation-targets" "^7.10.4" - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-proposal-async-generator-functions" "^7.10.4" - "@babel/plugin-proposal-class-properties" "^7.10.4" - "@babel/plugin-proposal-dynamic-import" "^7.10.4" - "@babel/plugin-proposal-export-namespace-from" "^7.10.4" - "@babel/plugin-proposal-json-strings" "^7.10.4" - "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" - "@babel/plugin-proposal-numeric-separator" "^7.10.4" - "@babel/plugin-proposal-object-rest-spread" "^7.11.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" - "@babel/plugin-proposal-optional-chaining" "^7.11.0" - "@babel/plugin-proposal-private-methods" "^7.10.4" - "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.0" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.10.4" - "@babel/plugin-transform-arrow-functions" "^7.10.4" - "@babel/plugin-transform-async-to-generator" "^7.10.4" - "@babel/plugin-transform-block-scoped-functions" "^7.10.4" - "@babel/plugin-transform-block-scoping" "^7.10.4" - "@babel/plugin-transform-classes" "^7.10.4" - "@babel/plugin-transform-computed-properties" "^7.10.4" - "@babel/plugin-transform-destructuring" "^7.10.4" - "@babel/plugin-transform-dotall-regex" "^7.10.4" - "@babel/plugin-transform-duplicate-keys" "^7.10.4" - "@babel/plugin-transform-exponentiation-operator" "^7.10.4" - "@babel/plugin-transform-for-of" "^7.10.4" - "@babel/plugin-transform-function-name" "^7.10.4" - "@babel/plugin-transform-literals" "^7.10.4" - "@babel/plugin-transform-member-expression-literals" "^7.10.4" - "@babel/plugin-transform-modules-amd" "^7.10.4" - "@babel/plugin-transform-modules-commonjs" "^7.10.4" - "@babel/plugin-transform-modules-systemjs" "^7.10.4" - "@babel/plugin-transform-modules-umd" "^7.10.4" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" - "@babel/plugin-transform-new-target" "^7.10.4" - "@babel/plugin-transform-object-super" "^7.10.4" - "@babel/plugin-transform-parameters" "^7.10.4" - "@babel/plugin-transform-property-literals" "^7.10.4" - "@babel/plugin-transform-regenerator" "^7.10.4" - "@babel/plugin-transform-reserved-words" "^7.10.4" - "@babel/plugin-transform-shorthand-properties" "^7.10.4" - "@babel/plugin-transform-spread" "^7.11.0" - "@babel/plugin-transform-sticky-regex" "^7.10.4" - "@babel/plugin-transform-template-literals" "^7.10.4" - "@babel/plugin-transform-typeof-symbol" "^7.10.4" - "@babel/plugin-transform-unicode-escapes" "^7.10.4" - "@babel/plugin-transform-unicode-regex" "^7.10.4" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.11.5" - browserslist "^4.12.0" - core-js-compat "^3.6.2" - invariant "^2.2.2" - levenary "^1.1.1" - semver "^5.5.0" - -"@babel/preset-modules@^0.1.3": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" - integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/register@^7.10.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.11.5.tgz#79becf89e0ddd0fba8b92bc279bc0f5d2d7ce2ea" - integrity sha512-CAml0ioKX+kOAvBQDHa/+t1fgOt3qkTIz0TrRtRAT6XY0m5qYZXR85k6/sLCNPMGhYDlCFHCYuU0ybTJbvlC6w== - dependencies: - find-cache-dir "^2.0.0" - lodash "^4.17.19" - make-dir "^2.1.0" - pirates "^4.0.0" - source-map-support "^0.5.16" - -"@babel/runtime@^7.8.4": - version "7.11.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" - integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" - integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.5" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.11.5" - "@babel/types" "^7.11.5" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.19" - -"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.4": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" - integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - -"@balancer-labs/sor@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-0.3.3.tgz#726a589094e4b9d25116cde5a1c0e154f132713e" - integrity sha512-hdPp55A2Hw+Koq81nhqTy15jNRCDW1k5ZT47nk2uEx7N5D9GiAx4BCNDzTiuJLErj6QHJTbEKK7Y5jei702c4g== - dependencies: - bignumber.js "^9.0.0" - isomorphic-fetch "^2.2.1" - -"@dabh/diagnostics@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" - integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q== - dependencies: - colorspace "1.1.x" - enabled "2.0.x" - kuler "^2.0.0" - -"@eslint/eslintrc@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.1.3.tgz#7d1a2b2358552cc04834c0979bd4275362e37085" - integrity sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA== - dependencies: - ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - lodash "^4.17.19" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - -"@ethersproject/abi@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.5.tgz#6e7bbf9d014791334233ba18da85331327354aa1" - integrity sha512-FNx6UMm0LnmCMFzN3urohFwZpjbUHPvc/O60h4qkF4yiJxLJ/G7QOSPjkHQ/q/QibagR4S7OKQawRy0NcvWa9w== - dependencies: - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/abstract-provider@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.4.tgz#ef12df8cb5e66d0d47b567ad6ed642d682043773" - integrity sha512-EOCHUTS8jOE3WZlA1pq9b/vQwKDyDzMy4gXeAv0wZecH1kwUkD0++x8avxeSYoWI+aJn62P1FVV9B6r9pM56kQ== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" - -"@ethersproject/abstract-signer@^5.0.4": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.5.tgz#d1cdea6b0b82fb8e4a83f6899ba84d3dc3bb6e66" - integrity sha512-nwSZKtCTKhJADlW42c+a//lWxQlnA7jYLTnabJ3YCfgGU6ic9jnT9nRDlAyT1U3kCMeqPL7fTcKbdWCVrM0xsw== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/address@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.4.tgz#8669bcbd02f4b64f4cede0a10e84df6d964ec9d3" - integrity sha512-CIjAeG6zNehbpJTi0sgwUvaH2ZICiAV9XkCBaFy5tjuEVFpQNeqd6f+B7RowcNO7Eut+QbhcQ5CVLkmP5zhL9A== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/rlp" "^5.0.3" - bn.js "^4.4.0" - -"@ethersproject/base64@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.3.tgz#d0aaa32c9ab08e2d62a6238581607ab6e929297e" - integrity sha512-sFq+/UwGCQsLxMvp7yO7yGWni87QXoV3C3IfjqUSY2BHkbZbCDm+PxZviUkiKf+edYZ2Glp0XnY7CgKSYUN9qw== - dependencies: - "@ethersproject/bytes" "^5.0.4" - -"@ethersproject/basex@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.3.tgz#f8c9bc449a089131f52cfa8698cf77bc22e27e32" - integrity sha512-EvoER+OXsMAZlvbC0M/9UTxjvbBvTccYCI+uCAhXw+eS1+SUdD4v7ekAFpVX78rPLrLZB1vChKMm6vPHIu3WRA== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/bignumber@^5.0.7": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.7.tgz#720b3e3df3e125a99669ee869478106d0afe7b76" - integrity sha512-wwKgDJ+KA7IpgJwc8Fc0AjKIRuDskKA2cque29/+SgII9/1K/38JpqVNPKIovkLwTC2DDofIyzHcxeaKpMFouQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - bn.js "^4.4.0" - -"@ethersproject/bytes@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.4.tgz#328d9d929a3e970964ecf5d62e12568a187189f1" - integrity sha512-9R6A6l9JN8x1U4s1dJCR+9h3MZTT3xQofr/Xx8wbDvj6NnY4CbBB0o8ZgHXvR74yV90pY2EzCekpkMBJnRzkSw== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/constants@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.4.tgz#9ddaa5f3c738a94e5adc4b3f71b36206fa5cdf88" - integrity sha512-Df32lcXDHPgZRPgp1dgmByNbNe4Ki1QoXR+wU61on5nggQGTqWR1Bb7pp9VtI5Go9kyE/JflFc4Te6o9MvYt8A== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - -"@ethersproject/contracts@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.0.4.tgz#27a2d7e3a7eef9bd8d006824ac2a74157b523988" - integrity sha512-gfOZNgLiO9e1D/hmQ4sEyqoolw6jDFVfqirGJv3zyFKNyX+lAXLN7YAZnnWVmp4GU1jiMtSqQKjpWp7r6ihs3Q== - dependencies: - "@ethersproject/abi" "^5.0.5" - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/hash@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.4.tgz#385642786405d236f3d2f1acdfaf250ab519cdac" - integrity sha512-VCs/bFBU8AQFhHcT1cQH6x7a4zjulR6fJmAOcPxUgrN7bxOQ7QkpBKF+YCDJhFtkLdaljIsr/r831TuWU4Ysfg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/hdnode@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.0.4.tgz#9c07a87781b24b9cae3507fe9404361c5870f1b7" - integrity sha512-eHmpNLvasfB4xbmQUvKXOsGF4ekjIKJH/eZm7fc6nIdMci9u5ERooSSRLjs9Dsa5QuJf6YD4DbqeJsT71n47iw== - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - -"@ethersproject/json-wallets@^5.0.6": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.0.6.tgz#c6c1818dcab18ecf3f37fa59ca504b9bc162d559" - integrity sha512-BPCfyGdwOUSp6+xA59IaZ/2pUWrUOL5Z9HuCh8YLsJzkuyBJQN0j+z/PmhIiZ7X8ilhuE+pRUwXb42U/R39fig== - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.3.tgz#f094a8fca3bb913c044593c4f382be424292e588" - integrity sha512-VhW3mgZMBZlETV6AyOmjNeNG+Pg68igiKkPpat8/FZl0CKnfgQ+KZQZ/ee1vT+X0IUM8/djqnei6btmtbA27Ug== - dependencies: - "@ethersproject/bytes" "^5.0.4" - js-sha3 "0.5.7" - -"@ethersproject/logger@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.5.tgz#e3ba3d0bcf9f5be4da5f043b1e328eb98b80002f" - integrity sha512-gJj72WGzQhUtCk6kfvI8elTaPOQyMvrMghp/nbz0ivTo39fZ7IjypFh/ySDeUSdBNplAwhzWKKejQhdpyefg/w== - -"@ethersproject/networks@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.3.tgz#c4ebe56e79ca399247382627e50a022aa68ece55" - integrity sha512-Gjpejul6XFetJXyvHCd37IiCC00203kYGU9sMaRMZcAcYKszCkbOeo/Q7Mmdr/fS7YBbB5iTOahDJWiRLu/b7A== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/pbkdf2@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.0.3.tgz#f9eca284a458cd11179d407884c595412d8d2775" - integrity sha512-asc+YgJn7v7GKWYXGz3GM1d9XYI2HvdCw1cLEow2niEC9BfYA29rr1exz100zISk95GIU1YP2zV//zHsMtWE5Q== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/sha2" "^5.0.3" - -"@ethersproject/properties@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.3.tgz#991aef39a5f87d4645cee76cec4df868bfb08be6" - integrity sha512-wLCSrbywkQgTO6tIF9ZdKsH9AIxPEqAJF/z5xcPkz1DK4mMAZgAXRNw1MrKYhyb+7CqNHbj3vxenNKFavGY/IA== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/providers@^5.0.8": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.0.9.tgz#88b48596dcfb0848a89da3160d2e2a055fc899f6" - integrity sha512-UtGrlJxekFNV7lriPOxQbnYminyiwTgjHMPX83pG7N/W/t+PekQK8V9rdlvMr2bRyGgafHml0ZZMaTV4FxiBYg== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" - bech32 "1.1.4" - ws "7.2.3" - -"@ethersproject/random@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.0.3.tgz#ec16546fffdc10b9082f1207bd3a09f54cbcf5e6" - integrity sha512-pEhWRbgNeAY1oYk4nIsEtCTh9TtLsivIDbOX11n+DLZLYM3c8qCLxThXtsHwVsMs1JHClZr5auYC4YxtVVzO/A== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/rlp@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.3.tgz#841a5edfdf725f92155fe74424f5510c9043c13a" - integrity sha512-Hz4yyA/ilGafASAqtTlLWkA/YqwhQmhbDAq2LSIp1AJNx+wtbKWFAKSckpeZ+WG/xZmT+fw5OFKK7a5IZ4DR5g== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/sha2@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.0.3.tgz#52c16edc1135d0ec7d242d88eed035dae72800c0" - integrity sha512-B1U9UkgxhUlC1J4sFUL2GwTo33bM2i/aaD3aiYdTh1FEXtGfqYA89KN1DJ83n+Em8iuvyiBRk6u30VmgqlHeHA== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - hash.js "1.1.3" - -"@ethersproject/signing-key@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.4.tgz#a5334ce8a52d4e9736dc8fb6ecc384704ecf8783" - integrity sha512-I6pJoga1IvhtjYK5yXzCjs4ZpxrVbt9ZRAlpEw0SW9UuV020YfJH5EIVEGR2evdRceS3nAQIggqbsXSkP8Y1Dg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - elliptic "6.5.3" - -"@ethersproject/solidity@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.0.4.tgz#67022cbfb50cb73b72d1739178537a9e798945bf" - integrity sha512-cUq1l8A+AgRkIItRoztC98Qx7b0bMNMzKX817fszDuGNsT2POAyP5knvuEt4Fx4IBcJREXoOjsGYFfjyK5Sa+w== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/strings@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.4.tgz#67cda604eee3ffcc004cb9f3bd03516e1c7b09a0" - integrity sha512-azXFHaNkDXzefhr4LVVzzDMFwj3kH9EOKlATu51HjxabQafuUyVLPFgmxRFmCynnAi0Bmmp7nr+qK1pVDgRDLQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/transactions@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.5.tgz#9a966f9ef4817b1752265d4efee0f1e9fd6aeaad" - integrity sha512-1Ga/QmbcB74DItggP8/DK1tggu4ErEvwTkIwIlUXUcvIAuRNXXE7kgQhlp+w1xA/SAQFhv56SqCoyqPiiLCvVA== - dependencies: - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - -"@ethersproject/units@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.0.4.tgz#e08876b54e1f6b362a841dcd986496a425875735" - integrity sha512-80d6skjDgiHLdbKOA9FVpzyMEPwbif40PbGd970JvcecVf48VjB09fUu37d6duG8DhRVyefRdX8nuVQLzcGGPw== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/wallet@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.0.4.tgz#b414ae2870fc0ea10808330f0ab3c5a1ac9e34e1" - integrity sha512-h/3mdy6HZVketHbs6ZP/WjHDz+rtTIE3qZrko2MVeafjgDcYWaHcVmhsPq4LGqxginhr191a4dkJDNeQrQZWOw== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/json-wallets" "^5.0.6" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - -"@ethersproject/web@^5.0.6": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.7.tgz#ab8ccffa9cee9469a8b49af8b8fee30e384e59d8" - integrity sha512-BM8FdGrzdcULYaOIyMXDKvxv+qOwGne8FKpPxUrifZIWAWPrq/y+oBOZlzadIKsP3wvYbAcMN2CgOLO1E3yIfw== - dependencies: - "@ethersproject/base64" "^5.0.3" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/wordlists@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.0.4.tgz#76a7e1dfd95aea645f6be2c1932b3f89b7f0c4ce" - integrity sha512-z/NsGqdYFvpeG6vPLxuD0pYNR5lLhQAy+oLVqg6G0o1c/OoL5J/a0iDOAFvnacQphc3lMP52d1LEX3YGoy2oBQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@perp/contract@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@perp/contract/-/contract-1.0.6.tgz#b423738d095a15fccd17de7bc46a531482a45d18" - integrity sha512-5exstpCstXpXSLaxY/hTVT3BtRF8UVJ2JgGN8abiFSKBg+aaQdBZ4qvsOzr4HQ0fkZSOlURL/JnOUDV04UrD5A== - -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - -"@terra-money/terra.js@^0.5.8": - version "0.5.8" - resolved "https://registry.yarnpkg.com/@terra-money/terra.js/-/terra.js-0.5.8.tgz#effd51631c596e67b782819dca924241d1903597" - integrity sha512-a+WqEgnxCIz0hCW/EhqF47TublEqPX/NdL5xNwve3sNFTjK7AqHcpVUS79hubimPy9HlDDZCSCF8YAXXJ7xfCQ== - dependencies: - axios "^0.20.0" - bech32 "^1.1.4" - bip32 "^2.0.6" - bip39 "^3.0.2" - crypto-js "3.3.0" - decimal.js "^10.2.0" - post-message-stream "^3.0.0" - secp256k1 "^4.0.2" - -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -"@types/node@10.12.18": - version "10.12.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" - integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== - -"@types/node@11.11.6": - version "11.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" - integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== - -"@uniswap/sdk@^3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@uniswap/sdk/-/sdk-3.0.3.tgz#8201c7c72215d0030cb99acc7e661eff895c18a9" - integrity sha512-t4s8bvzaCFSiqD2qfXIm3rWhbdnXp+QjD3/mRaeVDHK7zWevs6RGEb1ohMiNgOCTZANvBayb4j8p+XFdnMBadQ== - dependencies: - "@uniswap/v2-core" "^1.0.0" - big.js "^5.2.2" - decimal.js-light "^2.5.0" - jsbi "^3.1.1" - tiny-invariant "^1.1.0" - tiny-warning "^1.0.3" - toformat "^2.0.0" - -"@uniswap/v2-core@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@uniswap/v2-core/-/v2-core-1.0.1.tgz#af8f508bf183204779938969e2e54043e147d425" - integrity sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-jsx@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== - -acorn@^7.4.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" - integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= - -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4: - version "6.12.5" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" - integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-align@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" - integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== - dependencies: - string-width "^3.0.0" - -ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - -anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -app-root-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad" - integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw== - -argle@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/argle/-/argle-1.1.1.tgz#0cfe3bc032c36b2f48ba42b9c17f89f70607e994" - integrity sha1-DP47wDLDay9IukK5wX+J9wYH6ZQ= - dependencies: - lodash.isfunction "^3.0.8" - lodash.isnumber "^3.0.3" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-includes@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" - integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0" - is-string "^1.0.5" - -array-uniq@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.2.tgz#5fcc373920775723cfd64d65c64bef53bf9eba6d" - integrity sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0= - -array.prototype.flat@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" - integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -async@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== - -available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== - dependencies: - array-filter "^1.0.0" - -axios@^0.20.0: - version "0.20.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd" - integrity sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA== - dependencies: - follow-redirects "^1.10.0" - -axios@^0.21.1: - version "0.21.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" - integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== - dependencies: - follow-redirects "^1.10.0" - -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base-x@^3.0.2: - version "3.0.8" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" - integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== - dependencies: - safe-buffer "^5.0.1" - -bech32@1.1.4, bech32@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -bignumber.js@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" - integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== - -binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== - -bindings@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bip32@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" - integrity sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA== - dependencies: - "@types/node" "10.12.18" - bs58check "^2.1.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - tiny-secp256k1 "^1.1.3" - typeforce "^1.11.5" - wif "^2.0.6" - -bip39@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.2.tgz#2baf42ff3071fc9ddd5103de92e8f80d9257ee32" - integrity sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ== - dependencies: - "@types/node" "11.11.6" - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - -bn.js@^4.11.8, bn.js@^4.4.0: - version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" - integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== - -body-parser@1.19.0, body-parser@^1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - -boxen@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" - integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^5.3.1" - chalk "^3.0.0" - cli-boxes "^2.2.0" - string-width "^4.1.0" - term-size "^2.1.0" - type-fest "^0.8.1" - widest-line "^3.1.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserslist@^4.12.0, browserslist@^4.8.5: - version "4.14.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.3.tgz#381f9e7f13794b2eb17e1761b4f118e8ae665a53" - integrity sha512-GcZPC5+YqyPO4SFnz48/B0YaCwS47Q9iPChRGi6t7HhflKBcINzFrJvRfC+jp30sRMKxF+d4EHGs27Z0XP1NaQ== - dependencies: - caniuse-lite "^1.0.30001131" - electron-to-chromium "^1.3.570" - escalade "^3.1.0" - node-releases "^1.1.61" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= - dependencies: - base-x "^3.0.2" - -bs58check@<3.0.0, bs58check@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -caniuse-lite@^1.0.30001131: - version "1.0.30001133" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001133.tgz#ec564c5495311299eb05245e252d589a84acd95e" - integrity sha512-s3XAUFaC/ntDb1O3lcw9K8MPeOW7KO3z9+GzAoBxfz1B0VdacXPMKgFUtG4KIsgmnbexmi013s9miVu4h+qMHw== - -capture-console@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/capture-console/-/capture-console-1.0.1.tgz#db63c39ac73239019badd7fbb10143eda380ff71" - integrity sha1-22PDmscyOQGbrdf7sQFD7aOA/3E= - dependencies: - argle "~1.1.1" - lodash.isfunction "~3.0.8" - randomstring "~1.1.5" - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chokidar@^3.2.2: - version "3.4.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" - integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.4.0" - optionalDependencies: - fsevents "~2.1.2" - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -cli-boxes@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - -coercer@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/coercer/-/coercer-1.1.2.tgz#eaea4459511f73f9f36ade04a98107ce75824b70" - integrity sha1-6upEWVEfc/nzat4EqYEHznWCS3A= - -color-convert@^1.9.0, color-convert@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.5.2: - version "1.5.4" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6" - integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" - integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -colors@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -colorspace@1.1.x: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" - integrity sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ== - dependencies: - color "3.0.x" - text-hex "1.0.x" - -commander@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -complex.js@^2.0.11: - version "2.0.12" - resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.12.tgz#fa4df97d8928e5f7b6a86b35bdeecc3a3eda8a22" - integrity sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -configstore@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" - integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== - dependencies: - dot-prop "^5.2.0" - graceful-fs "^4.1.2" - make-dir "^3.0.0" - unique-string "^2.0.0" - write-file-atomic "^3.0.0" - xdg-basedir "^4.0.0" - -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - -core-js-compat@^3.6.2: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" - integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== - dependencies: - browserslist "^4.8.5" - semver "7.0.0" - -core-js@^3.2.1: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" - integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-fetch@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" - integrity sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ== - dependencies: - node-fetch "2.6.1" - -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-js@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" - integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== - -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - -debug@2.6.9, debug@^2.2.0, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== - dependencies: - ms "2.1.2" - -decimal.js-light@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" - integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== - -decimal.js@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231" - integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw== - -decimal.js@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" - integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== - -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dot-prop@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - -dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.3.570: - version "1.3.570" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.570.tgz#3f5141cc39b4e3892a276b4889980dabf1d29c7f" - integrity sha512-Y6OCoVQgFQBP5py6A/06+yWxUZHDlNr/gNDGatjH8AZqXl8X0tE4LfjLJsXGz/JmWJz8a6K7bR1k+QzZ+k//fg== - -elliptic@6.5.3, elliptic@^6.4.0, elliptic@^6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" - integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - 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" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -enabled@2.0.x: - version "2.0.0" - resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" - integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -encoding@^0.1.11: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -error-ex@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-abstract@^1.18.0-next.0: - version "1.18.0-next.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.0.tgz#b302834927e624d8e5837ed48224291f2c66e6fc" - integrity sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-negative-zero "^2.0.0" - is-regex "^1.1.1" - object-inspect "^1.8.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escalade@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e" - integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-goat@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" - integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-latex@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1" - integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-config-standard@^14.1.1: - version "14.1.1" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" - integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg== - -eslint-import-resolver-node@^0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" - integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== - dependencies: - debug "^2.6.9" - resolve "^1.13.1" - -eslint-module-utils@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" - integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== - dependencies: - debug "^2.6.9" - pkg-dir "^2.0.0" - -eslint-plugin-es@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" - integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-import@^2.22.1: - version "2.22.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" - integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== - dependencies: - array-includes "^3.1.1" - array.prototype.flat "^1.2.3" - contains-path "^0.1.0" - debug "^2.6.9" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.0" - has "^1.0.3" - minimatch "^3.0.4" - object.values "^1.1.1" - read-pkg-up "^2.0.0" - resolve "^1.17.0" - tsconfig-paths "^3.9.0" - -eslint-plugin-node@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" - integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== - dependencies: - eslint-plugin-es "^3.0.0" - eslint-utils "^2.0.0" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - -eslint-plugin-promise@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" - integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== - -eslint-plugin-standard@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" - integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^2.0.0, eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint@^7.10.0: - version "7.10.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.10.0.tgz#494edb3e4750fb791133ca379e786a8f648c72b9" - integrity sha512-BDVffmqWl7JJXqCjAK6lWtcQThZB/aP1HXSH1JKwGwv0LQEdvpR7qzNrUT487RM39B5goWuboFad5ovMBmD8yA== - dependencies: - "@babel/code-frame" "^7.0.0" - "@eslint/eslintrc" "^0.1.3" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^1.3.0" - espree "^7.3.0" - esquery "^1.2.0" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash "^4.17.19" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348" - integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.3.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" - integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -ethers@^5.0.14: - version "5.0.14" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.0.14.tgz#fc33613ff3c1eb04c481f32083f2be315079e2a2" - integrity sha512-6WkoYwAURTr/4JiSZlrMJ9mm3pBv/bWrOu7sVXdLGw9QU4cp/GDZVrKKnh5GafMTzanuNBJoaEanPCjsbe4Mig== - dependencies: - "@ethersproject/abi" "^5.0.5" - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/base64" "^5.0.3" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/contracts" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/json-wallets" "^5.0.6" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/providers" "^5.0.8" - "@ethersproject/random" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/solidity" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/units" "^5.0.4" - "@ethersproject/wallet" "^5.0.4" - "@ethersproject/web" "^5.0.6" - "@ethersproject/wordlists" "^5.0.4" - -express-ipfilter@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/express-ipfilter/-/express-ipfilter-1.1.2.tgz#536e1b8922f00df45d6da8796b02a75b1033a20f" - integrity sha512-dm1G3sVxlSbcOWSxfUTCo20ySyNQXJ4hJD5fuQJFoZlhkQvpbuDGBlh8AbFm1GwX85EWvfyhekOkvcydaXkBkg== - dependencies: - ip "~1.1.0" - lodash "^4.17.11" - proxy-addr "^2.0.4" - range_check "^1.2.0" - -express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fast-safe-stringify@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" - integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== - -fecha@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.0.tgz#3ffb6395453e3f3efff850404f0a59b6747f5f41" - integrity sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg== - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -file-stream-rotator@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-0.5.7.tgz#868a2e5966f7640a17dd86eda0e4467c089f6286" - integrity sha512-VYb3HZ/GiAGUCrfeakO8Mp54YGswNUHvL7P09WQcXAJNSj3iQ5QraYSp3cIn1MUyw6uzfgN/EFOarCNa4JvUHQ== - dependencies: - moment "^2.11.2" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-cache-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -fn.name@1.x.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" - integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== - -follow-redirects@^1.10.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" - integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== - -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fraction.js@^4.0.13: - version "4.0.13" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe" - integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -glob-parent@^5.0.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== - dependencies: - is-glob "^4.0.1" - -glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-dirs@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201" - integrity sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A== - dependencies: - ini "^1.3.5" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -got@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -graceful-fs@^4.1.2: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - -has-yarn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" - integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.0" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -helmet@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/helmet/-/helmet-4.1.1.tgz#751f0e273d809ace9c172073e0003bed27d27a4a" - integrity sha512-Avg4XxSBrehD94mkRwEljnO+6RZx7AGfk8Wa6K1nxaU+hbXlFOhlOIMgPfFqOYQB/dBCsTpootTGuiOG+CHiQA== - -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== - dependencies: - parse-passwd "^1.0.0" - -hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-status-codes@^2.1.3: - version "2.1.4" - resolved "https://registry.yarnpkg.com/http-status-codes/-/http-status-codes-2.1.4.tgz#453d99b4bd9424254c4f6a9a3a03715923052798" - integrity sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" - integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.1: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@^1.3.5, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -invariant@^2.2.2, invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -ip6@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/ip6/-/ip6-0.0.4.tgz#44c5a9db79e39d405201b4d78d13b3870e48db31" - integrity sha1-RMWp23njnUBSAbTXjROzhw5I2zE= - -ip@~1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.2.0.tgz#8aba49c9192799585bdd643e0ccb50e8ae777ba4" - integrity sha1-irpJyRknmVhb3WQ+DMtQ6K53e6Q= - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-callable@^1.1.4, is-callable@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" - integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-function@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" - integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-installed-globally@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" - integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== - dependencies: - global-dirs "^2.0.1" - is-path-inside "^3.0.1" - -is-negative-zero@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" - integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= - -is-npm@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" - integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-path-inside@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" - integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== - -is-regex@^1.1.0, is-regex@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== - dependencies: - has-symbols "^1.0.1" - -is-stream@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== - -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -is-typed-array@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.3.tgz#a4ff5a5e672e1a55f99c7f54e59597af5c1df04d" - integrity sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ== - dependencies: - available-typed-arrays "^1.0.0" - es-abstract "^1.17.4" - foreach "^2.0.5" - has-symbols "^1.0.1" - -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-yarn-global@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" - integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== - -isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isomorphic-fetch@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= - dependencies: - node-fetch "^1.0.1" - whatwg-fetch ">=0.10.0" - -javascript-natural-sort@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" - integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k= - -js-sha3@0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.4.2: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsbi@^3.1.1: - version "3.1.4" - resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-3.1.4.tgz#9654dd02207a66a4911b4e4bb74265bc2cbc9dd0" - integrity sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg== - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== - dependencies: - minimist "^1.2.5" - -keyblade@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/keyblade/-/keyblade-0.3.2.tgz#1e657f47746596807d6b591c53476bea9a1ac2d4" - integrity sha1-HmV/R3RlloB9a1kcU0dr6poawtQ= - -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - -kuler@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" - integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== - -latest-version@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" - integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== - dependencies: - package-json "^6.3.0" - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levenary@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" - integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== - dependencies: - leven "^3.1.0" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -lodash.isfunction@^3.0.8, lodash.isfunction@~3.0.8: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" - integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw== - -lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= - -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== - -logform@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2" - integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg== - dependencies: - colors "^1.2.1" - fast-safe-stringify "^2.0.4" - fecha "^4.2.0" - ms "^2.1.1" - triple-beam "^1.3.0" - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -make-dir@^2.0.0, make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -mathjs@^9.3.0: - version "9.3.0" - resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-9.3.0.tgz#59cc43b536b22616197e56da303604b430daa6ac" - integrity sha512-0kYW+TXgB8lCqUj5wHR2hqAO2twSbPRelSFgRJXiwAx4nM6FrIb43Jd6XhW7sVbwYB+9HCNiyg5Kn8VYeB7ilg== - dependencies: - complex.js "^2.0.11" - decimal.js "^10.2.1" - escape-latex "^1.2.0" - fraction.js "^4.0.13" - javascript-natural-sort "^0.7.1" - seedrandom "^3.0.5" - tiny-emitter "^2.1.0" - typed-function "^2.0.0" - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== - dependencies: - mime-db "1.44.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -moment@^2.11.2, moment@^2.29.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" - integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@2.1.2, ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -nan@^2.13.2: - version "2.14.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" - integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-environment-flags@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" - integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -node-fetch@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - -node-fetch@^1.0.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -node-gyp-build@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" - integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg== - -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - -node-releases@^1.1.61: - version "1.1.61" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e" - integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g== - -nodemon@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.4.tgz#55b09319eb488d6394aa9818148c0c2d1c04c416" - integrity sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ== - dependencies: - chokidar "^3.2.2" - debug "^3.2.6" - ignore-by-default "^1.0.1" - minimatch "^3.0.4" - pstree.remy "^1.1.7" - semver "^5.7.1" - supports-color "^5.5.0" - touch "^3.1.0" - undefsafe "^2.0.2" - update-notifier "^4.0.0" - -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= - dependencies: - abbrev "1" - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== - -object-hash@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09" - integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ== - -object-inspect@^1.7.0, object-inspect@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" - integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.18.0-next.0" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.getownpropertydescriptors@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -object.values@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -one-time@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" - integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== - dependencies: - fn.name "1.x.x" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-json@^6.3.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" - integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== - dependencies: - got "^9.6.0" - registry-auth-token "^4.0.0" - registry-url "^5.0.0" - semver "^6.2.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - -pbkdf2@^3.0.9: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pirates@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -post-message-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/post-message-stream/-/post-message-stream-3.0.0.tgz#90d9f54bd209e6b6f5d74795b87588205b547048" - integrity sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg= - dependencies: - readable-stream "^2.1.4" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -proxy-addr@^2.0.4, proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.1" - -pstree.remy@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" - integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -pupa@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726" - integrity sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA== - dependencies: - escape-goat "^2.0.0" - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - -randombytes@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -randomstring@~1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/randomstring/-/randomstring-1.1.5.tgz#6df0628f75cbd5932930d9fe3ab4e956a18518c3" - integrity sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM= - dependencies: - array-uniq "1.0.2" - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -range_check@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/range_check/-/range_check-1.4.0.tgz#cd87c7ac62c40ba9df69b8703c604f60c3748635" - integrity sha1-zYfHrGLEC6nfabhwPGBPYMN0hjU= - dependencies: - ip6 "0.0.4" - ipaddr.js "1.2" - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -rc@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -readable-stream@^2.1.4, readable-stream@^2.3.7: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" - integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== - dependencies: - picomatch "^2.2.1" - -regenerate-unicode-properties@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" - integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== - dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" - integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== - -regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - -regenerator-transform@^0.14.2: - version "0.14.5" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" - integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== - dependencies: - "@babel/runtime" "^7.8.4" - -regexpp@^3.0.0, regexpp@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== - -regexpu-core@^4.7.0: - version "4.7.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" - integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.2.0" - regjsgen "^0.5.1" - regjsparser "^0.6.4" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.2.0" - -registry-auth-token@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.0.tgz#1d37dffda72bbecd0f581e4715540213a65eb7da" - integrity sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w== - dependencies: - rc "^1.2.8" - -registry-url@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" - integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== - dependencies: - rc "^1.2.8" - -regjsgen@^0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" - integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== - -regjsparser@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" - integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== - dependencies: - jsesc "~0.5.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -scrypt-js@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -secp256k1@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" - integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg== - dependencies: - elliptic "^6.5.2" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -seedrandom@^3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" - integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== - -semver-diff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" - integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== - dependencies: - semver "^6.3.0" - -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - -semver@^6.0.0, semver@^6.1.0, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.2.1: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -source-map-support@^0.5.16: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.6" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz#c80757383c28abf7296744998cbc106ae8b854ce" - integrity sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.0.0, string-width@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -term-size@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.0.tgz#1f16adedfe9bdc18800e1776821734086fcc6753" - integrity sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw== - -text-hex@1.0.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" - integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -tiny-emitter@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" - integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== - -tiny-invariant@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" - integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== - -tiny-secp256k1@^1.1.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.5.tgz#3dc37b9bf0fa5b4390b9fa29e953228810cebc18" - integrity sha512-duE2hSLSQIpHGzmK48OgRrGTi+4OTkXLC6aa86uOYQ6LLCYZSarVKIAvEtY7MoXjoL6bOXMSerEGMzrvW4SkDw== - dependencies: - bindings "^1.3.0" - bn.js "^4.11.8" - create-hmac "^1.1.7" - elliptic "^6.4.0" - nan "^2.13.2" - -tiny-warning@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" - integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toformat@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/toformat/-/toformat-2.0.0.tgz#7a043fd2dfbe9021a4e36e508835ba32056739d8" - integrity sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ== - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" - -triple-beam@^1.2.0, triple-beam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" - integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== - -tsconfig-paths@^3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" - integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typed-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-2.0.0.tgz#15ab3825845138a8b1113bd89e60cd6a435739e8" - integrity sha512-Hhy1Iwo/e4AtLZNK10ewVVcP2UEs408DS35ubP825w/YgSBK1KVLwALvvIG4yX75QJrxjCpcWkzkVRB0BwwYlA== - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typeforce@^1.11.5: - version "1.18.0" - resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" - integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== - -undefsafe@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" - integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== - dependencies: - debug "^2.2.0" - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== - -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - -unicode-match-property-value-ecmascript@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" - integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== - -unicode-property-aliases-ecmascript@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" - integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== - -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== - dependencies: - crypto-random-string "^2.0.0" - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -update-notifier@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.1.tgz#895fc8562bbe666179500f9f2cebac4f26323746" - integrity sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg== - dependencies: - boxen "^4.2.0" - chalk "^3.0.0" - configstore "^5.0.1" - has-yarn "^2.1.0" - import-lazy "^2.1.0" - is-ci "^2.0.0" - is-installed-globally "^0.3.1" - is-npm "^4.0.0" - is-yarn-global "^0.3.0" - latest-version "^5.0.0" - pupa "^2.0.1" - semver-diff "^3.1.1" - xdg-basedir "^4.0.0" - -uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== - dependencies: - punycode "^2.1.0" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util@^0.12.3: - version "0.12.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" - integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - safe-buffer "^5.1.2" - which-typed-array "^1.1.2" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -v8-compile-cache@^2.0.3: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" - integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== - -v8flags@^3.1.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" - integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== - dependencies: - homedir-polyfill "^1.0.1" - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -whatwg-fetch@>=0.10.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3" - integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ== - -which-typed-array@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2" - integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ== - dependencies: - available-typed-arrays "^1.0.2" - es-abstract "^1.17.5" - foreach "^2.0.5" - function-bind "^1.1.1" - has-symbols "^1.0.1" - is-typed-array "^1.1.3" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -wif@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" - integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ= - dependencies: - bs58check "<3.0.0" - -winston-daily-rotate-file@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.0.tgz#3914ac57c4bdae1138170bec85af0c2217b253b1" - integrity sha512-/HqeWiU48dzGqcrABRlxYWVMdL6l3uKCtFSJyrqK+E2rLnSFNsgYpvwx15EgTitBLNzH69lQd/+z2ASryV2aqw== - dependencies: - file-stream-rotator "^0.5.7" - object-hash "^2.0.1" - triple-beam "^1.3.0" - winston-transport "^4.2.0" - -winston-transport@^4.2.0, winston-transport@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" - integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== - dependencies: - readable-stream "^2.3.7" - triple-beam "^1.2.0" - -winston@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" - integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== - dependencies: - "@dabh/diagnostics" "^2.0.2" - async "^3.1.0" - is-stream "^2.0.0" - logform "^2.2.0" - one-time "^1.0.0" - readable-stream "^3.4.0" - stack-trace "0.0.x" - triple-beam "^1.3.0" - winston-transport "^4.4.0" - -word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -ws@7.2.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" - integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== - -xdg-basedir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" - integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yaml-js@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/yaml-js/-/yaml-js-0.1.5.tgz#a01369010b3558d8aaed2394615dfd0780fd8fac" - integrity sha1-oBNpAQs1WNiq7SOUYV39B4D9j6w= - -yaml@^1.10.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yargs-parser@^20.2.2: - version "20.2.7" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== - -yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yawn-yaml@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/yawn-yaml/-/yawn-yaml-1.5.0.tgz#95fba7544d5375fce3dc84514f12218ed0d2ebcb" - integrity sha512-sH2zX9K1QiWhWh9U19pye660qlzrEAd5c4ebw/6lqz17LZw7xYi7nqXlBoVLVtc2FZFXDKiJIsvVcKGYbLVyFQ== - dependencies: - js-yaml "^3.4.2" - lodash "^4.17.11" - yaml-js "^0.1.3" - -yenv@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/yenv/-/yenv-3.0.0.tgz#8fe7eadbccda6f4e4271bf12ba3169bbe207f16d" - integrity sha512-ghUzu49pchzamfLuJrplGlZc+N3dyPmFyv2B2W+ZzTvTuuwU3WJaR5P0zPNbixIuTr4Mo4iSPQ4R8P2eAhcSww== - dependencies: - coercer "^1.1.2" - deep-extend "^0.6.0" - js-yaml "^4.0.0" - keyblade "^0.3.2" - yargs "^16.2.0" From e46ba52de51dbc14ae4e56bab007017e4eb5cad0 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 31 May 2021 21:09:52 +0100 Subject: [PATCH 17/31] update git ignore to ignore more files --- .babelrc | 5 + .dockerignore | 12 + .eslintrc.js | 14 + .gitignore | 31 + CODE_OF_CONDUCT.md | 76 + CONTRIBUTING.md | 138 + Dockerfile | 34 + LICENSE | 201 + README.md | 48 + certs/readme.md | 1 + docker-compose.yml | 11 + env.yaml | 87 + package-lock.json | 5874 +++++++++++++++++ package.json | 61 + setup.md | 133 + src/app.js | 63 + src/index.js | 85 + src/routes/balancer.route.js | 361 + src/routes/celo.route.js | 252 + src/routes/eth.route.js | 429 ++ src/routes/index.route.js | 38 + src/routes/perpetual_finance.route.js | 518 ++ src/routes/terra.route.js | 228 + src/routes/uniswap.route.js | 367 + src/services/access.js | 25 + src/services/balancer.js | 206 + src/services/configuration_manager.js | 65 + src/services/eth.js | 167 + src/services/fees.js | 52 + src/services/logger.js | 44 + src/services/perpetual_finance.js | 299 + src/services/terra.js | 316 + src/services/uniswap.js | 218 + src/services/utils.js | 103 + src/static/ExchangeProxy.json | 624 ++ src/static/abi.js | 234 + src/static/erc20_tokens_kovan.json | 55 + src/static/uniswap_route_tokens.json | 15 + src/static/uniswap_v2_router_abi.json | 1924 ++++++ test/command.md | 3 + test/index.js | 1 + ...eway-Ethereum-Base.postman_collection.json | 1264 ++++ .../Gateway-Terra.postman_collection.json | 328 + test/postman/PERPFI.postman_collection.json | 454 ++ test/postman/terra.postman_environment.json | 29 + .../v2/Gateway.postman_collection.json | 1001 +++ .../v2/Gateway.postman_environment.json | 34 + test/ssl-scripts.sh | 54 + 48 files changed, 16582 insertions(+) create mode 100644 .babelrc create mode 100644 .dockerignore create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 certs/readme.md create mode 100644 docker-compose.yml create mode 100644 env.yaml create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 setup.md create mode 100644 src/app.js create mode 100644 src/index.js create mode 100644 src/routes/balancer.route.js create mode 100644 src/routes/celo.route.js create mode 100644 src/routes/eth.route.js create mode 100644 src/routes/index.route.js create mode 100644 src/routes/perpetual_finance.route.js create mode 100644 src/routes/terra.route.js create mode 100644 src/routes/uniswap.route.js create mode 100644 src/services/access.js create mode 100644 src/services/balancer.js create mode 100644 src/services/configuration_manager.js create mode 100644 src/services/eth.js create mode 100644 src/services/fees.js create mode 100644 src/services/logger.js create mode 100644 src/services/perpetual_finance.js create mode 100644 src/services/terra.js create mode 100644 src/services/uniswap.js create mode 100644 src/services/utils.js create mode 100644 src/static/ExchangeProxy.json create mode 100644 src/static/abi.js create mode 100644 src/static/erc20_tokens_kovan.json create mode 100644 src/static/uniswap_route_tokens.json create mode 100644 src/static/uniswap_v2_router_abi.json create mode 100644 test/command.md create mode 100644 test/index.js create mode 100644 test/postman/Gateway-Ethereum-Base.postman_collection.json create mode 100644 test/postman/Gateway-Terra.postman_collection.json create mode 100644 test/postman/PERPFI.postman_collection.json create mode 100644 test/postman/terra.postman_environment.json create mode 100644 test/postman/v2/Gateway.postman_collection.json create mode 100644 test/postman/v2/Gateway.postman_environment.json create mode 100755 test/ssl-scripts.sh diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..cedf24f --- /dev/null +++ b/.babelrc @@ -0,0 +1,5 @@ +{ + "presets": [ + "@babel/preset-env" + ] +} \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cd75aae --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +.DS_Store +node_modules +npm-debug.log +.git +# Environment files +*.env +*.env.* +# except the example .env.example +!.env.example + +# Gateway API files +*.pem diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..8156b59 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,14 @@ +module.exports = { + extends: 'standard', + rules: { + // disable semicolon check + semi: 'off', + + // override default options for rules from base configurations + 'comma-dangle': 'off', + + // disable rules from base configurations + 'no-console': 'off', + 'no-multi-spaces': 'off', + } +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8f2de05 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# OS files +**/.DS_Store +Desktop.ini + +# IDEA files +.idea + +# Configuration files +*conf/ +# except the example conf/global_conf.yml.example +!conf/global_conf.yml.example + +# node installs +node_modules/ + +# debug logs +npm-debug.log + +# distribution files +dist/ + +# misc +logs/ + +# cert +*.pem +*.srl +*.key +*.crt +*.log +*.lock diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..1d15957 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at dev@coinalpha.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5dd883c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,138 @@ +# Contributing + +## General workflow + +1. Fork the repo +1. Create a new branch from the [`development`](https://github.com/CoinAlpha/gateway-api/tree/development) branch (see: [branch naming guidelines](#branch-naming-guidelines)) +1. Make commits to your branch +1. When you've finished with your fix or feature: + - Rebase upstream changes into your branch + - Submit a pull request to the [`development`](https://github.com/CoinAlpha/gateway-api/tree/development) branch + - Include a description of your changes +1. Your pull request will be reviewed by [CoinAlpha's development team](mailto:dev@coinalpha.com). +1. Fix any issues raised by your code reviewer, and push your fixes as a single new commit. +1. Once the pull request has been reviewed and accepted, it will be merged by a member of the CoinAlpha development team. + +## Detailed workflow + +### Fork the repo + +Use github’s interface to make a fork of the repo, then add that repo as an upstream remote: + +``` +git remote add upstream https://github.com/CoinAlpha/gateway-api.git +``` + +### Branch naming guidelines + +Your branch should follow this naming convention: + - feat/... + - bug/... + - refactor/... + - test/... + - doc/... + +These commands will help you do this: + +``` bash +# Creates your branch and brings you there +git checkout -b `your-branch-name` +``` + +### Make commits to your feature branch + +Prefix each commit like so + - (feat) Add a new feature + - (fix) Fix inconsistent tests [Fixes #0] + - (refactor) ... + - (cleanup) ... + - (test) ... + - (doc) ... + +Make changes and commits on your branch, and make sure that you +only make changes that are relevant to this branch. If you find +yourself making unrelated changes, make a new branch for those +changes. + +#### Commit message guidelines + +- Commit messages should be written in the present tense; e.g. "Fix continuous integration script". +- The first line of your commit message should be a brief summary of what the commit changes. Aim for about 70 characters max. Remember: This is a summary, not a detailed description of everything that changed. +- If you want to explain the commit in more depth, following the first line should be a blank line and then a more detailed description of the commit. This can be as detailed as you want, so dig into details here and keep the first line short. + +### Rebase upstream changes into your branch + +Once you are done making changes, you can begin the process of getting +your code merged into the main repo. Step 1 is to rebase upstream +changes to the `development` branch into yours by running this command +from your branch: + +```bash +git pull --rebase upstream development +``` + +This will start the rebase process. You must commit all of your changes +before doing this. If there are no conflicts, this should just roll all +of your changes back on top of the changes from upstream, leading to a +nice, clean, linear commit history. + +If there are conflicting changes, git will start yelling at you part way +through the rebasing process. Git will pause rebasing to allow you to sort +out the conflicts. You do this the same way you solve merge conflicts, +by checking all of the files git says have been changed in both histories +and picking the versions you want. Be aware that these changes will show +up in your pull request, so try and incorporate upstream changes as much +as possible. + +You pick a file by `git add`ing it - you do not make commits during a +rebase. + +Once you are done fixing conflicts for a specific commit, run: + +```bash +git rebase --continue +``` + +This will continue the rebasing process. Once you are done fixing all +conflicts you should run the existing tests to make sure you didn’t break +anything, then run your new tests (there are new tests, right?) and +make sure they work also. + +If rebasing broke anything, fix it, then repeat the above process until +you get here again and nothing is broken and all the tests pass. + +### Make a pull request + +Make a clear pull request from your fork and branch to the upstream `development` +branch, detailing exactly what changes you made and what feature this +should add. The clearer your pull request is the faster you can get +your changes incorporated into this repo. + +If the development team requests changes, you should make more commits to your +branch to address these, then follow this process again from rebasing onwards. + +Once you get back here, make a comment requesting further review and +someone will look at your code again. If it addresses the requests, it will +get merged, else, just repeat again. + +Thanks for contributing! + +### Testing + +Tests are very, very important. Submit tests if your pull request contains new, testable behavior. + +## Checklist: + +This is just to help you organize your process + +- [ ] Did I create my branch from `development` (don't create new branches from existing feature branches)? +- [ ] Did I follow the correct naming convention for my branch? +- [ ] Is my branch focused on a single main change? + - [ ] Do all of my changes directly relate to this change? +- [ ] Did I rebase the upstream `development` branch after I finished all my + work? +- [ ] Did I write a clear pull request message detailing what changes I made? +- [ ] Did I get a code review? + - [ ] Did I make any requested changes from that code review? + +If you follow all of these guidelines and make good changes, you should have no problem getting your changes merged in. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..47d8c7c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +FROM node:10.22.0-alpine + +# Add timezone database +RUN apk add --no-cache tzdata + +# Set labels +LABEL application="gateway-api" +LABEL branch=${BRANCH} +LABEL commit=${COMMIT} +LABEL date=${BUILD_DATE} + +# Set ENV variables +ENV COMMIT_BRANCH=${BRANCH} +ENV COMMIT_SHA=${COMMIT} +ENV BUILD_DATE=${DATE} + +# app directory +WORKDIR /usr/src/app + +# install dependancies +COPY package*.json ./ +COPY yarn.lock ./ + +RUN yarn install + +# copy pwd file to container +COPY . . + +# create empty env file +RUN touch .env + +EXPOSE 5000 + +CMD ["yarn", "run", "start"] \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ceee1ca --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 CoinAlpha, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..01aa595 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +![Hummingbot](https://i.ibb.co/X5zNkKw/blacklogo-with-text.png) + +---- + +Hummingbot Gateway is an open-source project that integrates cryptocurrency trading on both **centralized exchanges** and **decentralized protocols**. It allows users to run a client that executes customized, automated trading strategies for cryptocurrencies. + +We created hummingbot to promote **decentralized market-making**: enabling members of the community to contribute to the liquidity and trading efficiency in cryptocurrency markets. + + + +## Getting Started + +### Learn more about Hummingbot + +- [Website](https://hummingbot.io) +- [Documentation](https://docs.hummingbot.io) +- [FAQs](https://docs.hummingbot.io/faq/) + +### Install Hummingbot + +- [Quickstart guide](https://docs.hummingbot.io/quickstart/) +- [All installation options](https://docs.hummingbot.io/installation/overview/) + +### Get support +- Chat with our support team on [Discord](https://discord.hummingbot.io) +- Email us at support@hummingbot.io + +### Chat with other traders +- Join our community on [Discord](https://discord.coinalpha.com) or [Reddit](https://www.reddit.com/r/Hummingbot/) +- Follow Hummingbot on [Twitter](https://twitter.com/hummingbot_io) + +## Contributions + +We welcome contributions from the community: +- **Code and documentation contributions** via [pull requests](https://github.com/CoinAlpha/gateway-api/pulls) +- **Bug reports and feature requests** through [Github issues](https://github.com/CoinAlpha/gateway-api/issues) +- When contributing, please review the [contributing guidelines](CONTRIBUTING.md) + +## About us + +Hummingbot Gateway was created and is maintained by CoinAlpha, Inc. We are [a global team of engineers and traders](https://hummingbot.io/about/). + +- **General**: contact us at [dev@hummingbot.io](mailto:dev@hummingbot.io) or join our [Discord server](https://discord.hummingbot.io). +- **Business inquiries**: contact us at [partnerships@hummingbot.io](mailto:partnerships@hummingbot.io). + +## Legal + +- **License**: Hummingbot is licensed under [Apache 2.0](./LICENSE). diff --git a/certs/readme.md b/certs/readme.md new file mode 100644 index 0000000..8d9f12b --- /dev/null +++ b/certs/readme.md @@ -0,0 +1 @@ +certs dir for local testing only \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4f8c4ae --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3' + +services: + gateway: + build: . + volumes: + - .:/usr/src/app + ports: + - 5001:5000 + + \ No newline at end of file diff --git a/env.yaml b/env.yaml new file mode 100644 index 0000000..fbb28a9 --- /dev/null +++ b/env.yaml @@ -0,0 +1,87 @@ +APPNAME: Hummingbot Gateway API +NODE_ENV: dev +PORT: 5000 + +# use only if ip whitelist is required for local or docker instance +# note that docker instance does not use 127.0.0.1 address +# ipv6 format for locahost ["::ffff:127.0.0.1", "::ffff:1", "fe80::1", "::1"] +IP_WHITELIST: + +HUMMINGBOT_INSTANCE_ID: {client_id} + +# Celo + +# Terra +# - mainnet: https://lcd.terra.dev +# - mainnet chain: columbus-4 +# - testnet: https://tequila-lcd.terra.dev +# - testnet chain: tequila-0004 +TERRA_LCD_URL: {testnet_lcd_url} +TERRA_CHAIN: {testnet_chain_id} + +# Ethereum +# - chain: mainnet, kovan, etc +# - rpc url: infura or other rpc url +# - token list: erc20 token list source (ref: https://tokenlists.org/) +ETHEREUM_CHAIN: kovan +# ETHEREUM_RPC_URL: https://mainnet.infura.io/v3/117bfd0769f54bd2b91f50d2b1c19f9a +ETHEREUM_RPC_URL: https://kovan.infura.io/v3/117bfd0769f54bd2b91f50d2b1c19f9a +ETHEREUM_TOKEN_LIST_URL: https://wispy-bird-88a7.uniswap.workers.dev/?url=http://tokens.1inch.eth.link + +# Balancer +# subgraph_chain +# Reference: https://docs.balancer.finance/sor/development#subgraph +# - mainnet: balancer +# - kovan: balancer-kovan +# Note: REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor +REACT_APP_SUBGRAPH_URL: https://api.thegraph.com/subgraphs/name/balancer-labs/{subgraph_chain} + +# exchange_proxy: +# Reference: https://docs.balancer.finance/smart-contracts/addresses +# - mainnet: 0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21 +# - kovan: 0x4e67bf5bD28Dd4b570FBAFe11D0633eCbA2754Ec +EXCHANGE_PROXY: "0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21" + +# Uniswap +# Reference: https://uniswap.org/docs/v2/smart-contracts/router02/ +# UniswapV2Router02 is deployed at 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets. +# It was built from commit 6961711. +UNISWAP_ROUTER: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D" +UNISWAP_V3_CORE: "0x1F98431c8aD98523631AE4a59f267346ea31F984" +UNISWAP_V3_ROUTER: "0xE592427A0AEce92De3Edee1F18E0157C05861564" +UNISWAP_V3_NFT_MANAGER: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88" +# allowed slippage for swap transactions +UNISWAP_ALLOWED_SLIPPAGE: 1.5 +# restrict updating pairs that have no reserves or failed for 5 minutes +uNISWAP_NO_RESERVE_CHECK_INTERVALL: 300011 +# cache info about pair for 1 second +UNISWAP_PAIRS_CACHE_TIME: 1000 + +# cert +CERT_PATH: /home/vic/hummingbot/certs/ +CERT_PASSPHRASE: a + +# logs +# default to ./logs if path is not set +# LOG_PATH: /Users/hbot/hummingbot_files/hummingbot_logs + +# GMT offset for logging (alpine docker image default to UTC timezone) +# -0800, -0500, +0200, +0800 +GMT_OFFSET: "+0800" + +# EthGasStation +# API key for defipulse.com gas station API +# Gas level you want to use for Ethereum transactions (fast, fastest, safeLow, average) +ENABLE_ETH_GAS_STATION: true +ETH_GAS_STATION_API_KEY: {apikey} +ETH_GAS_STATION_GAS_LEVEL: fast +ETH_GAS_STATION_REFRESH_TIME: 60 +MANUAL_GAS_PRICE: 100 + +# Balancer Config +BALANCER_MAX_SWAPS: 4 + + +# Perpetual Finance Provider URL +# default: https://dai.poa.network , https://rpc.xdaichain.com, etc +XDAI_PROVIDER: https://xdai.poanetwork.dev diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..199add5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5874 @@ +{ + "name": "gateway-api", + "version": "0.3.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "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.12.13" + } + }, + "@babel/compat-data": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", + "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==", + "dev": true + }, + "@babel/core": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.15.tgz", + "integrity": "sha512-6GXmNYeNjS2Uz+uls5jalOemgIhnTMeaXo+yBUA72kC2uX/8VW6XyhVIo2L8/q0goKQA3EVKx0KOQpVKSeWadQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.15", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.15", + "@babel/types": "^7.13.14", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.13.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", + "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", + "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", + "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.12", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", + "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.13.0", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", + "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "regexpu-core": "^4.7.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz", + "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", + "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz", + "integrity": "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==", + "dev": true, + "requires": { + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", + "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", + "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-wrap-function": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", + "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", + "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helpers": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", + "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", + "dev": true, + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/highlight": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/node": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.13.13.tgz", + "integrity": "sha512-gElSPunpriXoBGQxDkd5h9L13SVTyzFLTPv9jN1aXJNLR10iNs+MsfhYL/WGJGCJQFddHAdThY7CkmGVz2KPag==", + "dev": true, + "requires": { + "@babel/register": "^7.13.8", + "commander": "^4.0.1", + "core-js": "^3.2.1", + "node-environment-flags": "^1.0.5", + "regenerator-runtime": "^0.13.4", + "v8flags": "^3.1.1" + } + }, + "@babel/parser": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz", + "integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==", + "dev": true + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", + "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.13.12" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz", + "integrity": "sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", + "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", + "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", + "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", + "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", + "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", + "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", + "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", + "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.8", + "@babel/helper-compilation-targets": "^7.13.8", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.13.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", + "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", + "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", + "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", + "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", + "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", + "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", + "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", + "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz", + "integrity": "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", + "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", + "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz", + "integrity": "sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", + "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", + "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", + "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", + "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", + "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", + "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", + "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", + "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", + "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-simple-access": "^7.12.13", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", + "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.13.0", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-identifier": "^7.12.11", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", + "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", + "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", + "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", + "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", + "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", + "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz", + "integrity": "sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", + "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", + "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", + "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", + "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", + "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", + "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", + "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", + "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/preset-env": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.15.tgz", + "integrity": "sha512-D4JAPMXcxk69PKe81jRJ21/fP/uYdcTZ3hJDF5QX2HSI9bBxxYw/dumdR6dGumhjxlprHPE4XWoPaqzZUVy2MA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-async-generator-functions": "^7.13.15", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-dynamic-import": "^7.13.8", + "@babel/plugin-proposal-export-namespace-from": "^7.12.13", + "@babel/plugin-proposal-json-strings": "^7.13.8", + "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-numeric-separator": "^7.12.13", + "@babel/plugin-proposal-object-rest-spread": "^7.13.8", + "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-private-methods": "^7.13.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.12.13", + "@babel/plugin-transform-arrow-functions": "^7.13.0", + "@babel/plugin-transform-async-to-generator": "^7.13.0", + "@babel/plugin-transform-block-scoped-functions": "^7.12.13", + "@babel/plugin-transform-block-scoping": "^7.12.13", + "@babel/plugin-transform-classes": "^7.13.0", + "@babel/plugin-transform-computed-properties": "^7.13.0", + "@babel/plugin-transform-destructuring": "^7.13.0", + "@babel/plugin-transform-dotall-regex": "^7.12.13", + "@babel/plugin-transform-duplicate-keys": "^7.12.13", + "@babel/plugin-transform-exponentiation-operator": "^7.12.13", + "@babel/plugin-transform-for-of": "^7.13.0", + "@babel/plugin-transform-function-name": "^7.12.13", + "@babel/plugin-transform-literals": "^7.12.13", + "@babel/plugin-transform-member-expression-literals": "^7.12.13", + "@babel/plugin-transform-modules-amd": "^7.13.0", + "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/plugin-transform-modules-systemjs": "^7.13.8", + "@babel/plugin-transform-modules-umd": "^7.13.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", + "@babel/plugin-transform-new-target": "^7.12.13", + "@babel/plugin-transform-object-super": "^7.12.13", + "@babel/plugin-transform-parameters": "^7.13.0", + "@babel/plugin-transform-property-literals": "^7.12.13", + "@babel/plugin-transform-regenerator": "^7.13.15", + "@babel/plugin-transform-reserved-words": "^7.12.13", + "@babel/plugin-transform-shorthand-properties": "^7.12.13", + "@babel/plugin-transform-spread": "^7.13.0", + "@babel/plugin-transform-sticky-regex": "^7.12.13", + "@babel/plugin-transform-template-literals": "^7.13.0", + "@babel/plugin-transform-typeof-symbol": "^7.12.13", + "@babel/plugin-transform-unicode-escapes": "^7.12.13", + "@babel/plugin-transform-unicode-regex": "^7.12.13", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.13.14", + "babel-plugin-polyfill-corejs2": "^0.2.0", + "babel-plugin-polyfill-corejs3": "^0.2.0", + "babel-plugin-polyfill-regenerator": "^0.2.0", + "core-js-compat": "^3.9.0", + "semver": "^6.3.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/register": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.13.14.tgz", + "integrity": "sha512-iyw0hUwjh/fzN8qklVqZodbyWjEBOG0KdDnBOpv3zzIgK3NmuRXBmIXH39ZBdspkn8LTHvSboN+oYb4MT43+9Q==", + "dev": true, + "requires": { + "find-cache-dir": "^2.0.0", + "lodash": "^4.17.19", + "make-dir": "^2.1.0", + "pirates": "^4.0.0", + "source-map-support": "^0.5.16" + } + }, + "@babel/runtime": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz", + "integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.15", + "@babel/types": "^7.13.14", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", + "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@balancer-labs/sor": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@balancer-labs/sor/-/sor-0.3.3.tgz", + "integrity": "sha512-hdPp55A2Hw+Koq81nhqTy15jNRCDW1k5ZT47nk2uEx7N5D9GiAx4BCNDzTiuJLErj6QHJTbEKK7Y5jei702c4g==", + "requires": { + "bignumber.js": "^9.0.0", + "isomorphic-fetch": "^2.2.1" + } + }, + "@dabh/diagnostics": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", + "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + } + } + }, + "@ethersproject/abi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.0.tgz", + "integrity": "sha512-N/W9Sbn1/C6Kh2kuHRjf/hX6euMK4+9zdJRBB8sDWmihVntjUAfxbusGZKzDQD8i3szAHhTz8K7XADV5iFNfJw==", + "requires": { + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz", + "integrity": "sha512-8dJUnT8VNvPwWhYIau4dwp7qe1g+KgdRm4XTWvjkI9gAT2zZa90WF5ApdZ3vl1r6NDmnn6vUVvyphClRZRteTQ==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/networks": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/web": "^5.1.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.1.0.tgz", + "integrity": "sha512-qQDMkjGZSSJSKl6AnfTgmz9FSnzq3iEoEbHTYwjDlEAv+LNP7zd4ixCcVWlWyk+2siud856M5CRhAmPdupeN9w==", + "requires": { + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0" + } + }, + "@ethersproject/address": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.1.0.tgz", + "integrity": "sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/rlp": "^5.1.0" + } + }, + "@ethersproject/base64": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.1.0.tgz", + "integrity": "sha512-npD1bLvK4Bcxz+m4EMkx+F8Rd7CnqS9DYnhNu0/GlQBXhWjvfoAZzk5HJ0f1qeyp8d+A86PTuzLOGOXf4/CN8g==", + "requires": { + "@ethersproject/bytes": "^5.1.0" + } + }, + "@ethersproject/basex": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.1.0.tgz", + "integrity": "sha512-vBKr39bum7DDbOvkr1Sj19bRMEPA4FnST6Utt6xhDzI7o7L6QNkDn2yrCfP+hnvJGhZFKtLygWwqlTBZoBXYLg==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/properties": "^5.1.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.0.tgz", + "integrity": "sha512-wUvQlhTjPjFXIdLPOuTrFeQmSa6Wvls1bGXQNQWvB/SEn1NsTCE8PmumIEZxmOPjSHl1eV2uyHP5jBm5Cgj92Q==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", + "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/constants": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", + "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", + "requires": { + "@ethersproject/bignumber": "^5.1.0" + } + }, + "@ethersproject/contracts": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.1.1.tgz", + "integrity": "sha512-6WwktLJ0DFWU8pDkgH4IGttQHhQN4SnwKFu9h+QYVe48VGWtbDu4W8/q/7QA1u/HWlWMrKxqawPiZUJj0UMvOw==", + "requires": { + "@ethersproject/abi": "^5.1.0", + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/transactions": "^5.1.0" + } + }, + "@ethersproject/hash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz", + "integrity": "sha512-fNwry20yLLPpnRRwm3fBL+2ksgO+KMadxM44WJmRIoTKzy4269+rbq9KFoe2LTqq2CXJM2CE70beGaNrpuqflQ==", + "requires": { + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/hdnode": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.1.0.tgz", + "integrity": "sha512-obIWdlujloExPHWJGmhJO/sETOOo7SEb6qemV4f8kyFoXg+cJK+Ta9SvBrj7hsUK85n3LZeZJZRjjM7oez3Clg==", + "requires": { + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/basex": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/pbkdf2": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/sha2": "^5.1.0", + "@ethersproject/signing-key": "^5.1.0", + "@ethersproject/strings": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/wordlists": "^5.1.0" + } + }, + "@ethersproject/json-wallets": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.1.0.tgz", + "integrity": "sha512-00n2iBy27w8zrGZSiU762UOVuzCQZxUZxopsZC47++js6xUFuI74DHcJ5K/2pddlF1YBskvmMuboEu1geK8mnA==", + "requires": { + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/hdnode": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/pbkdf2": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/random": "^5.1.0", + "@ethersproject/strings": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "@ethersproject/keccak256": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.1.0.tgz", + "integrity": "sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "js-sha3": "0.5.7" + } + }, + "@ethersproject/logger": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", + "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" + }, + "@ethersproject/networks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.1.0.tgz", + "integrity": "sha512-A/NIrIED/G/IgU1XUukOA3WcFRxn2I4O5GxsYGA5nFlIi+UZWdGojs85I1VXkR1gX9eFnDXzjE6OtbgZHjFhIA==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/pbkdf2": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.1.0.tgz", + "integrity": "sha512-B8cUbHHTgs8OtgJIafrRcz/YPDobVd5Ru8gTnShOiM9EBuFpYHQpq3+8iQJ6pyczDu6HP/oc/njAsIBhwFZYew==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/sha2": "^5.1.0" + } + }, + "@ethersproject/properties": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.1.0.tgz", + "integrity": "sha512-519KKTwgmH42AQL3+GFV3SX6khYEfHsvI6v8HYejlkigSDuqttdgVygFTDsGlofNFchhDwuclrxQnD5B0YLNMg==", + "requires": { + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/providers": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.1.tgz", + "integrity": "sha512-+xWqQh4eLnAePRR5CHSySCVke//NxGSuQEUzGTdDtt0yCbizwlKGm7CrsU0zF8JUcKDrDh36ezzTicOMd5sl9w==", + "requires": { + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/basex": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/networks": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/random": "^5.1.0", + "@ethersproject/rlp": "^5.1.0", + "@ethersproject/sha2": "^5.1.0", + "@ethersproject/strings": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/web": "^5.1.0", + "bech32": "1.1.4", + "ws": "7.2.3" + }, + "dependencies": { + "ws": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" + } + } + }, + "@ethersproject/random": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.1.0.tgz", + "integrity": "sha512-+uuczLQZ4+no9cP6TCoCktXx0u2YbNaRT7lRkSt12d8263e702f0u+4JnnRO8Qmv5nylWJebnqCHzyxP+6mLqw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/rlp": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.1.0.tgz", + "integrity": "sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/sha2": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.1.0.tgz", + "integrity": "sha512-+fNSeZRstOpdRJpdGUkRONFCaiAqWkc91zXgg76Nlp5ndBQE25Kk5yK8gCPG1aGnCrbariiPr5j9DmrYH78JCA==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "hash.js": "1.1.3" + }, + "dependencies": { + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + } + } + }, + "@ethersproject/signing-key": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.1.0.tgz", + "integrity": "sha512-tE5LFlbmdObG8bY04NpuwPWSRPgEswfxweAI1sH7TbP0ml1elNfqcq7ii/3AvIN05i5U0Pkm3Tf8bramt8MmLw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "bn.js": "^4.4.0", + "elliptic": "6.5.4" + } + }, + "@ethersproject/solidity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.1.0.tgz", + "integrity": "sha512-kPodsGyo9zg1g9XSXp1lGhFaezBAUUsAUB1Vf6OkppE5Wksg4Et+x3kG4m7J/uShDMP2upkJtHNsIBK2XkVpKQ==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/sha2": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/strings": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.1.0.tgz", + "integrity": "sha512-perBZy0RrmmL0ejiFGUOlBVjMsUceqLut3OBP3zP96LhiJWWbS8u1NqQVgN4/Gyrbziuda66DxiQocXhsvx+Sw==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/transactions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.1.1.tgz", + "integrity": "sha512-Nwgbp09ttIVN0OoUBatCXaHxR7grWPHbozJN8v7AXDLrl6nnOIBEMDh+yJTnosSQlFhcyjfTGGN+Mx6R8HdvMw==", + "requires": { + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/rlp": "^5.1.0", + "@ethersproject/signing-key": "^5.1.0" + } + }, + "@ethersproject/units": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.1.0.tgz", + "integrity": "sha512-isvJrx6qG0nKWfxsGORNjmOq/nh175fStfvRTA2xEKrGqx8JNJY83fswu4GkILowfriEM/eYpretfJnfzi7YhA==", + "requires": { + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/constants": "^5.1.0", + "@ethersproject/logger": "^5.1.0" + } + }, + "@ethersproject/wallet": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.1.0.tgz", + "integrity": "sha512-ULmUtiYQLTUS+y3DgkLzRhFEK10zMwmjOthnjiZxee3Q/MVwr3rnmuAnXIUZrPjna6hvUPnyRIdW5XuF0Ld0YQ==", + "requires": { + "@ethersproject/abstract-provider": "^5.1.0", + "@ethersproject/abstract-signer": "^5.1.0", + "@ethersproject/address": "^5.1.0", + "@ethersproject/bignumber": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/hdnode": "^5.1.0", + "@ethersproject/json-wallets": "^5.1.0", + "@ethersproject/keccak256": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/random": "^5.1.0", + "@ethersproject/signing-key": "^5.1.0", + "@ethersproject/transactions": "^5.1.0", + "@ethersproject/wordlists": "^5.1.0" + } + }, + "@ethersproject/web": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.1.0.tgz", + "integrity": "sha512-LTeluWgTq04+RNqAkVhpydPcRZK/kKxD2Vy7PYGrAD27ABO9kTqTBKwiOuzTyAHKUQHfnvZbXmxBXJAGViSDcA==", + "requires": { + "@ethersproject/base64": "^5.1.0", + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@ethersproject/wordlists": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.1.0.tgz", + "integrity": "sha512-NsUCi/TpBb+oTFvMSccUkJGtp5o/84eOyqp5q5aBeiNBSLkYyw21znRn9mAmxZgySpxgruVgKbaapnYPgvctPQ==", + "requires": { + "@ethersproject/bytes": "^5.1.0", + "@ethersproject/hash": "^5.1.0", + "@ethersproject/logger": "^5.1.0", + "@ethersproject/properties": "^5.1.0", + "@ethersproject/strings": "^5.1.0" + } + }, + "@perp/contract": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@perp/contract/-/contract-1.1.0.tgz", + "integrity": "sha512-79O3DoGYtC6Nu9TnzC6aUTwCuEfe3+CIZr9a27Uh26MQ0jHkCq2Rc4sz35k3ChuN9zL2ZmrsAR+mO785QGZFpw==" + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@terra-money/terra.js": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-0.5.13.tgz", + "integrity": "sha512-v2B+VqVar6gryTfpHsusmDn2WIRT23xnTKsxFn6G20WIN5XCeRQa84cnAlZHuNP9w5ejuvRmoHX0Wg6g1DJo3g==", + "requires": { + "axios": "^0.20.0", + "bech32": "^1.1.4", + "bip32": "^2.0.6", + "bip39": "^3.0.2", + "bufferutil": "^4.0.1", + "crypto-js": "3.3.0", + "decimal.js": "^10.2.1", + "post-message-stream": "^3.0.0", + "secp256k1": "^4.0.2", + "tmp": "^0.2.1", + "utf-8-validate": "^5.0.2", + "ws": "^7.3.1" + }, + "dependencies": { + "axios": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", + "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", + "requires": { + "follow-redirects": "^1.10.0" + } + } + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/node": { + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" + }, + "@uniswap/sdk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@uniswap/sdk/-/sdk-3.0.3.tgz", + "integrity": "sha512-t4s8bvzaCFSiqD2qfXIm3rWhbdnXp+QjD3/mRaeVDHK7zWevs6RGEb1ohMiNgOCTZANvBayb4j8p+XFdnMBadQ==", + "requires": { + "@uniswap/v2-core": "^1.0.0", + "big.js": "^5.2.2", + "decimal.js-light": "^2.5.0", + "jsbi": "^3.1.1", + "tiny-invariant": "^1.1.0", + "tiny-warning": "^1.0.3", + "toformat": "^2.0.0" + } + }, + "@uniswap/v2-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v2-core/-/v2-core-1.0.1.tgz", + "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "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", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "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.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==" + }, + "argle": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/argle/-/argle-1.1.1.tgz", + "integrity": "sha1-DP47wDLDay9IukK5wX+J9wYH6ZQ=", + "requires": { + "lodash.isfunction": "^3.0.8", + "lodash.isnumber": "^3.0.3" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + } + }, + "array-uniq": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz", + "integrity": "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0=" + }, + "array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "available-typed-arrays": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", + "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", + "requires": { + "array-filter": "^1.0.0" + } + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz", + "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.0", + "semver": "^6.1.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz", + "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.0", + "core-js-compat": "^3.9.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz", + "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip32": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", + "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", + "requires": { + "@types/node": "10.12.18", + "bs58check": "^2.1.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "tiny-secp256k1": "^1.1.3", + "typeforce": "^1.11.5", + "wif": "^2.0.6" + } + }, + "bip39": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.3.tgz", + "integrity": "sha512-P0dKrz4g0V0BjXfx7d9QNkJ/Txcz/k+hM9TnjqjUaXtuOfAvxXSw2rJw8DX0e3ZPwnK/IgDxoRqf0bvoVCqbMg==", + "requires": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + }, + "dependencies": { + "@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + } + } + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserslist": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", + "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001208", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.712", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001211", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001211.tgz", + "integrity": "sha512-v3GXWKofIkN3PkSidLI5d1oqeKNsam9nQkqieoMhP87nxOY0RPDC8X2+jcv8pjV4dRozPLSoMqNii9sDViOlIg==", + "dev": true + }, + "capture-console": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-console/-/capture-console-1.0.1.tgz", + "integrity": "sha1-22PDmscyOQGbrdf7sQFD7aOA/3E=", + "requires": { + "argle": "~1.1.1", + "lodash.isfunction": "~3.0.8", + "randomstring": "~1.1.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "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.1", + "color-string": "^1.5.2" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "complex.js": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.12.tgz", + "integrity": "sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + } + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.10.1.tgz", + "integrity": "sha512-pwCxEXnj27XG47mu7SXAwhLP3L5CrlvCB91ANUkIz40P27kUcvNfSdvyZJ9CLHiVoKSp+TTChMQMSKQEH/IQxA==", + "dev": true + }, + "core-js-compat": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.10.1.tgz", + "integrity": "sha512-ZHQTdTPkqvw2CeHiZC970NNJcnwzT6YIueDMASKt+p3WbZsLXOcoD392SkcWhkC0wBBHhlfhqGKKsNCQUozYtg==", + "dev": true, + "requires": { + "browserslist": "^4.16.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "requires": { + "node-fetch": "2.6.1" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + } + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", + "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" + }, + "decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron-to-chromium": { + "version": "1.3.717", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz", + "integrity": "sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ==", + "dev": true + }, + "elliptic": { + "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.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } + } + }, + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" + }, + "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 + }, + "eslint": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", + "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "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==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "globals": { + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", + "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "eslint-config-standard": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", + "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", + "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", + "dev": true + }, + "eslint-plugin-standard": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", + "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "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" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "ethers": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.2.tgz", + "integrity": "sha512-yM+2bINj7Li9jeKX+hGZ/rFTo6kXcCwZTcCBmAwS+J3bLfyGX/o21fcssuPb9kfR26suCV+98XTWIuTuGiDO5A==", + "requires": { + "@ethersproject/abi": "5.1.0", + "@ethersproject/abstract-provider": "5.1.0", + "@ethersproject/abstract-signer": "5.1.0", + "@ethersproject/address": "5.1.0", + "@ethersproject/base64": "5.1.0", + "@ethersproject/basex": "5.1.0", + "@ethersproject/bignumber": "5.1.0", + "@ethersproject/bytes": "5.1.0", + "@ethersproject/constants": "5.1.0", + "@ethersproject/contracts": "5.1.1", + "@ethersproject/hash": "5.1.0", + "@ethersproject/hdnode": "5.1.0", + "@ethersproject/json-wallets": "5.1.0", + "@ethersproject/keccak256": "5.1.0", + "@ethersproject/logger": "5.1.0", + "@ethersproject/networks": "5.1.0", + "@ethersproject/pbkdf2": "5.1.0", + "@ethersproject/properties": "5.1.0", + "@ethersproject/providers": "5.1.1", + "@ethersproject/random": "5.1.0", + "@ethersproject/rlp": "5.1.0", + "@ethersproject/sha2": "5.1.0", + "@ethersproject/signing-key": "5.1.0", + "@ethersproject/solidity": "5.1.0", + "@ethersproject/strings": "5.1.0", + "@ethersproject/transactions": "5.1.1", + "@ethersproject/units": "5.1.0", + "@ethersproject/wallet": "5.1.0", + "@ethersproject/web": "5.1.0", + "@ethersproject/wordlists": "5.1.0" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "express-ipfilter": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/express-ipfilter/-/express-ipfilter-1.2.0.tgz", + "integrity": "sha512-nPXKMuhqVjX7+Vny4XsrpdqlX4YAGcanE0gh5xzpfmNTsINGAgPnpk67kb0No3p1m4vGQQLU6hdaXRxsuGNlTA==", + "requires": { + "ip": "~1.1.0", + "lodash": "^4.17.11", + "proxy-addr": "^2.0.4", + "range_check": "^1.2.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, + "fecha": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", + "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-stream-rotator": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.5.7.tgz", + "integrity": "sha512-VYb3HZ/GiAGUCrfeakO8Mp54YGswNUHvL7P09WQcXAJNSj3iQ5QraYSp3cIn1MUyw6uzfgN/EFOarCNa4JvUHQ==", + "requires": { + "moment": "^2.11.2" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, + "follow-redirects": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", + "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fraction.js": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz", + "integrity": "sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dev": true, + "requires": { + "ini": "1.3.7" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "helmet": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.5.0.tgz", + "integrity": "sha512-GfxdTaKarneWOpxmiVb/1YsY+fIwDOxVUGrvNEM1MC8W6Z2PREfkXiWF4XHQdvkyXwUTHuY4DRwB0uH/Q6BVyQ==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "http-status-codes": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.1.4.tgz", + "integrity": "sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg==" + }, + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ip6": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/ip6/-/ip6-0.0.4.tgz", + "integrity": "sha1-RMWp23njnUBSAbTXjROzhw5I2zE=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "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==" + }, + "is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typed-array": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" + }, + "js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbi": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", + "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "logform": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", + "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "triple-beam": "^1.3.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "mathjs": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-9.3.2.tgz", + "integrity": "sha512-0YKSKAeN9OkbIQrxfxnBT4kk/KlH71piWOsvVvAasyRIj/Xd/zlpc5VP/aFxwr+llOq2F3f6booPEu2fWv3yjQ==", + "requires": { + "complex.js": "^2.0.11", + "decimal.js": "^10.2.1", + "escape-latex": "^1.2.0", + "fraction.js": "^4.0.13", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^2.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "requires": { + "mime-db": "1.47.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "dev": true + }, + "nodemon": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", + "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", + "dev": true, + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "object-hash": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz", + "integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==" + }, + "object-inspect": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", + "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "object.values": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "requires": { + "fn.name": "1.x.x" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "post-message-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/post-message-stream/-/post-message-stream-3.0.0.tgz", + "integrity": "sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg=", + "requires": { + "readable-stream": "^2.1.4" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomstring": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.1.5.tgz", + "integrity": "sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM=", + "requires": { + "array-uniq": "1.0.2" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "range_check": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/range_check/-/range_check-1.4.0.tgz", + "integrity": "sha1-zYfHrGLEC6nfabhwPGBPYMN0hjU=", + "requires": { + "ip6": "0.0.4", + "ipaddr.js": "1.2" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.2.0.tgz", + "integrity": "sha1-irpJyRknmVhb3WQ+DMtQ6K53e6Q=" + } + } + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "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==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "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.1" + } + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "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=" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "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" + } + }, + "table": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.2.0.tgz", + "integrity": "sha512-WMBBLuauiLXJjth35K4vOnd/xkaZ/dxEcyoZ+YhxSwfxFqvh+av06+oRqIwbR14m1lENB1egSWOFv/bNEt2D8A==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ajv": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", + "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, + "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", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-secp256k1": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", + "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==", + "requires": { + "bindings": "^1.3.0", + "bn.js": "^4.11.8", + "create-hmac": "^1.1.7", + "elliptic": "^6.4.0", + "nan": "^2.13.2" + } + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", + "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typed-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-2.0.0.tgz", + "integrity": "sha512-Hhy1Iwo/e4AtLZNK10ewVVcP2UEs408DS35ubP825w/YgSBK1KVLwALvvIG4yX75QJrxjCpcWkzkVRB0BwwYlA==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typeforce": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", + "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dev": true, + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "utf-8-validate": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", + "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "util": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", + "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "wif": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", + "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", + "requires": { + "bs58check": "<3.0.0" + } + }, + "winston": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", + "requires": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + }, + "dependencies": { + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + } + } + }, + "winston-daily-rotate-file": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.2.tgz", + "integrity": "sha512-DpAz9djExzFGVGRIKCKzsjOQaIINbjOUJ8CRsZGz0SQOMMcO1kM7jqTdzQAM9CRTEksZV9bBw9TT0ddQBGxs9g==", + "requires": { + "file-stream-rotator": "^0.5.7", + "object-hash": "^2.0.1", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + } + }, + "winston-transport": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", + "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", + "requires": { + "readable-stream": "^2.3.7", + "triple-beam": "^1.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..29d94b7 --- /dev/null +++ b/package.json @@ -0,0 +1,61 @@ +{ + "name": "gateway-api", + "version": "0.3.1", + "description": "Hummingbot Gateway", + "main": "index.js", + "license": "Apache 2", + "repository": "https://github.com/coinalpha/gateway-api", + "scripts": { + "start": "pm2 start babel-node -- src/index.js", + "status": "pm2 monit", + "stop": "pm2 stop all", + "logs": "pm2 logs", + "debug": "DEBUG=*router nodemon --exec babel-node src/index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "dependencies": { + "@balancer-labs/sor": "^0.3.3", + "@perp/contract": "^1.0.6", + "@terra-money/terra.js": "^0.5.8", + "@uniswap/sdk": "^3.0.3", + "app-root-path": "^3.0.0", + "axios": "^0.21.1", + "bignumber.js": "^9.0.0", + "body-parser": "^1.19.0", + "capture-console": "^1.0.1", + "cross-fetch": "^3.0.6", + "debug": "^4.2.0", + "dotenv": "^8.2.0", + "yenv": "^3.0.0", + "yaml": "^1.10.2", + "yawn-yaml": "^1.5.0", + "ethers": "^5.0.14", + "express": "^4.17.1", + "express-ipfilter": "^1.1.2", + "helmet": "^4.1.1", + "http-status-codes": "^2.1.3", + "lodash": "^4.17.20", + "mathjs": "^9.3.0", + "moment": "^2.29.1", + "util": "^0.12.3", + "winston": "^3.3.3", + "winston-daily-rotate-file": "^4.5.0" + }, + "devDependencies": { + "@babel/core": "^7.11.6", + "@babel/node": "^7.10.5", + "@babel/preset-env": "^7.11.5", + "eslint": "^7.10.0", + "eslint-config-standard": "^14.1.1", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^4.0.1", + "nodemon": "^2.0.4", + "pm2": "^4.5.6" + }, + "engines": { + "node": "12.x" + }, + "type": "module" +} diff --git a/setup.md b/setup.md new file mode 100644 index 0000000..3340dce --- /dev/null +++ b/setup.md @@ -0,0 +1,133 @@ +# Hummingbot Gateway + +## Express Middleware + +NodeJS, Express middleware/REST API server that connects to protocol library. + +This can be used as a common API server to handle transactions that requires custom or third party libraries. + +## Development Requirements + +- NodeJS + - Tested on Node v10.22.1 + - https://docs.npmjs.com/downloading-and-installing-node-js-and-npm + + ```bash + # Using Homebrew MacOS: + brew install node + + ``` + +- Yarn (for node package installations) + - Tested on v1.22.5 + - To install yarn: + ```bash + npm install yarn + + ``` + +- ExpressJS - Install through package.json + +[optional] +To switch to specific Node version, you can use `n` to handle the version installation and switch easily. + +```bash +# install n +npm -g install n +# list remote available node version +n ls-remote +# list locally installed node version +n ls +# install specific version (e.g. 10, 12.18.3, 14.11.0) +n 10 +# use specific version, then select installed version +n + + +## Setup + +```bash + +git clone +cd + +# install npm packages +yarn install + +# setup config +cp .env.example .env + +# run dev mode with hot reload on code changes +yarn run dev + +# run debug mode with additional route debug logging +yarn run debug + +# Run prod mode +yarn run start + +# API +https://localhost:5000/api + +# Protocol Endpoints +All endpoint require POST request with data + +# ETHEREUM + +# get ETH and ERC-20 tokens balances in the user's wallet +https://localhost:5000/eth/balances + +# get ERC-20 allowances for a contract address +https://localhost:5000/eth/allowances + +# approve a contract to allow transferring tokens to it +https://localhost:5000/eth/approve + +# send testnet ETH to WETH contract to get testnet WETH +https://localhost:5000/eth/deposit + + +# BALANCER + +# get price and pools for a trade +https://localhost:5000/balancer/buy-price +https://localhost:5000/balancer/sell-price + +# execute trade +https://localhost:5000/balancer/buy +https://localhost:5000/balancer/sell + + +``` + +### SSL Test + +SSL is setup for HTTPS traffic to Gateway running at localhost. To run Gateway as standalone API server, use the following test script to generate the SSL certs. + +```bash +$ ssl-scripts.sh + +# Test endpoint +curl --insecure --key ./certs/client_key.pem --cert ./certs/client_cert.pem https://localhost:5000/api + +``` + +Test endpoint on Python +```python + +# update the locaiton path of the pem files + +def test_get_api_status(self): + url = 'https://localhost:5000/api' + + ca_certs = realpath(join(__file__, join("../../certs/ca_cert.pem"))) + client_certs = (realpath(join(__file__, join("../../certs/client_cert.pem"))), + realpath(join(__file__, join("../../certs/client_key.pem")))) + response = requests.get(url, verify=ca_certs, cert=client_certs) + + result = response.json() + print('result', result) + + self.assertTrue('status' in result.keys() and result['status'] == 'ok', f"Gateway API {url} not ready") + +``` diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..87bebf0 --- /dev/null +++ b/src/app.js @@ -0,0 +1,63 @@ +import bodyParser from 'body-parser' +import express from 'express' +import helmet from 'helmet' +import { statusMessages } from './services/utils'; +import { validateAccess } from './services/access'; +import { IpFilter } from 'express-ipfilter' +import { logger } from './services/logger'; + +// Routes +import apiRoutes from './routes/index.route' +import balancerRoutes from './routes/balancer.route' +// import celoRoutes from './routes/celo.route' +import ethRoutes from './routes/eth.route' +import terraRoutes from './routes/terra.route' +import uniswapRoutes from './routes/uniswap.route' +import perpFiRoutes from './routes/perpetual_finance.route' + +//load configs +const globalConfig = require('./services/configuration_manager').configManagerInstance + +// create app +const app = express(); + +// middleware +// #security: remove response headers from middleware +// https://www.npmjs.com/package/helmet +app.use(helmet()); + +const ipWhitelist = globalConfig.getConfig("IP_WHITELIST") +if (ipWhitelist) { + app.use(IpFilter(JSON.parse(ipWhitelist), { mode: 'allow' })) +} +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); + +app.use(validateAccess) + +// mount routes to specific path +app.use('/api', apiRoutes); +app.use('/eth', ethRoutes); +app.use('/eth/uniswap', uniswapRoutes); +app.use('/eth/balancer', balancerRoutes); +app.use('/terra', terraRoutes); +app.use('/perpfi', perpFiRoutes); +// app.use('/celo', celoRoutes); + +app.get('/', (req, res, next) => { + res.send('ok') +}) + +/** + * Catch all 404 response when routes are not found + */ +app.use((req, res, next) => { + const message = `${statusMessages.page_not_found} at ${req.originalUrl}` + logger.error(message) + res.status(404).send({ + error: 'Page not found', + message: message + }); +}); + +export default app; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..53787d4 --- /dev/null +++ b/src/index.js @@ -0,0 +1,85 @@ +#!/usr/bin/env node + +// absolute imports +import https from 'https' +import fs from 'fs' + +// relative imports +import app from './app' +import { logger } from './services/logger' + +const globalConfig = require('./services/configuration_manager').configManagerInstance.readAllConfigs() + +const env = globalConfig.CORE.NODE_ENV +const port = int(globalConfig.CORE.PORT) +const certPassphrase = globalConfig.CERT_PASSPHRASE +const ethereumChain = globalConfig.ETHEREUM_CHAIN +const terraChain = globalConfig.TERRA_CHAIN +let certPath = globalConfig.CERT_PATH + +if ((typeof certPath === 'undefined' && certPath == null) || certPath === '') { + // assuming it is local development using test script to generate certs + certPath = './certs' +} else { + certPath = certPath.replace(/\/$/, ''); +} + +// set app environment +app.set('env', env) +const options = { + key: fs.readFileSync(certPath.concat('/server_key.pem'), { encoding: 'utf-8' }), + cert: fs.readFileSync(certPath.concat('/server_cert.pem'), { encoding: 'utf-8' }), + // request client certificate from user + requestCert: true, + // reject requests with no valid certificate + rejectUnauthorized: true, + // use ca cert created with own key for self-signed + ca: [fs.readFileSync(certPath.concat('/ca_cert.pem'), { encoding: 'utf-8' })], + passphrase: certPassphrase +}; + +const server = https.createServer(options, app) + +// event listener for "error" event +const onError = error => { + if (error.syscall !== 'listen') { + throw error + } + + const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges') + process.exit(1) + case 'EADDRINUSE': + console.error(bind + ' is already in use') + process.exit(1) + default: + throw error + } +} + +// event listener for "listening" event. +const onListening = () => { + const addr = server.address() + const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port + console.log('listening on ' + bind) + logger.debug('listening on ' + bind) +} + +// listen on provided port, on all network interfaces. +server.listen(port) +server.on('error', onError) +server.on('listening', onListening) + +const serverConfig = { + app: 'gateway-api', + port: port, + ethereumChain: ethereumChain, + terraChain: terraChain +} + +logger.info(JSON.stringify(serverConfig)) +console.log(serverConfig) diff --git a/src/routes/balancer.route.js b/src/routes/balancer.route.js new file mode 100644 index 0000000..0b332dd --- /dev/null +++ b/src/routes/balancer.route.js @@ -0,0 +1,361 @@ +import BigNumber from 'bignumber.js'; +import { ethers } from 'ethers'; +import express from 'express'; + +import { getParamData, latency, reportConnectionError, statusMessages } from '../services/utils'; + +import Ethereum from '../services/eth'; +import Balancer from '../services/balancer'; +import Fees from '../services/fees'; +import { logger } from '../services/logger'; + +const debug = require('debug')('router') +const router = express.Router() +const globalConfig = require('../services/configuration_manager').configManagerInstance +const eth = new Ethereum(globalConfig.getConfig("ETHEREUM_CHAIN")) +const balancer = new Balancer(globalConfig.getConfig("ETHEREUM_CHAIN")) +const fees = new Fees() + +const swapMoreThanMaxPriceError = 'Price too high' +const swapLessThanMaxPriceError = 'Price too low' + +const estimateGasLimit = (maxswaps) => { + const gasLimit = balancer.gasBase + maxswaps * balancer.gasPerSwap + return gasLimit +} + +router.post('/', async (req, res) => { + /* + POST / + */ + res.status(200).json({ + network: balancer.network, + provider: balancer.provider.connection.url, + exchangeProxy: balancer.exchangeProxy, + subgraphUrl: balancer.subgraphUrl, + connection: true, + timestamp: Date.now(), + }) +}) + +router.post('/gas-limit', async (req, res) => { + /* + POST: /buy-price + x-www-form-urlencoded: { + "maxSwaps":4 + } + */ + const paramData = getParamData(req.body) + + try { + const swaps = paramData.maxSwaps + const maxSwaps = typeof swaps === 'undefined' || parseInt(swaps) === 0 ? balancer.maxSwaps : parseInt(swaps) + const gasLimit = estimateGasLimit(maxSwaps) + + res.status(200).json({ + network: balancer.network, + gasLimit: gasLimit, + timestamp: Date.now(), + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.get('/start', async (req, res) => { + /* + POST: /eth/balancer/start + x-www-form-urlencoded: { + "pairs":'["ETH-USDT", ...]' + "gasPrice":30 + } + */ + const initTime = Date.now() + const paramData = getParamData(req.query) + const pairs = JSON.parse(paramData.pairs) + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + + // get token contract address and cache pools + for (let pair of pairs){ + pair = pair.split("-") + const baseTokenSymbol = pair[0] + const quoteTokenSymbol = pair[1] + const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) + + // check for valid token symbols + if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { + const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol + res.status(500).json({ + error: `Token ${undefinedToken} contract address not found`, + message: `Token contract address not found for ${undefinedToken}. Check token list source`, + }) + return + } + await Promise.allSettled([balancer.fetchPool(baseTokenContractInfo.address, quoteTokenContractInfo.address), + balancer.fetchPool(quoteTokenContractInfo.address, baseTokenContractInfo.address)]) + } + + + const gasLimit = estimateGasLimit(balancer.maxSwaps) + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + const result = { + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + success: true, + pairs: pairs, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + } + console.log('Initializing balancer') + res.status(200).json(result) +}) + +router.post('/price', async (req, res) => { + /* + POST: /eth/balancer/price + x-www-form-urlencoded: { + "quote":"BAT" + "base":"USDC" + "amount":0.1 + "side":buy + } + */ + const initTime = Date.now() + // params: base (required), quote (required), amount (required) + const paramData = getParamData(req.body) + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals + const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals + const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) + const maxSwaps = balancer.maxSwaps + const side = paramData.side.toUpperCase() + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + + try { + // fetch the optimal pool mix from balancer-sor + const { swaps, expectedAmount } = side === 'BUY' + ? await balancer.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount, + maxSwaps, + ) + : await balancer.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount, + maxSwaps, + ) + + if (swaps != null && expectedAmount != null) { + const gasLimit = estimateGasLimit(swaps.length) + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + const tradeAmount = parseFloat(amount) + const expectedTradeAmount = parseInt(expectedAmount) / quoteDenomMultiplier + const tradePrice = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier + + const result = { + network: balancer.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenContractInfo, + quote: quoteTokenContractInfo, + amount: tradeAmount, + side: side, + expectedAmount: expectedTradeAmount, + price: tradePrice, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + swaps: swaps, + } + debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) + res.status(200).json(result) + } else { // no pool available + res.status(200).json({ + info: statusMessages.no_pool_available, + message: statusMessages.no_pool_available + }) + } + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/trade', async (req, res) => { + /* + POST: /trade + x-www-form-urlencoded: { + "quote":"BAT" + "base":"USDC" + "amount":0.1 + "limitPrice":1 + "gasPrice":10 + "side":{buy|sell} + "privateKey":{{privateKey}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, balancer.provider) + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals + const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals + const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) + + const maxSwaps = balancer.maxSwaps + const side = paramData.side.toUpperCase() + + let limitPrice + if (paramData.limitPrice) { + limitPrice = parseFloat(paramData.limitPrice) + } + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + + try { + // fetch the optimal pool mix from balancer-sor + const { swaps, expectedAmount } = side === 'BUY' + ? await balancer.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount, + maxSwaps, + ) + : await balancer.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount, + maxSwaps, + ) + + const gasLimit = estimateGasLimit(swaps.length) + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + if (side === 'BUY') { + const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier + logger.info(`Price: ${price.toString()}`) + if (!limitPrice || price <= limitPrice) { + // pass swaps to exchange-proxy to complete trade + const tx = await balancer.swapExactOut( + wallet, + swaps, + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + expectedAmount.toString(), + gasPrice, + ) + + // submit response + res.status(200).json({ + network: balancer.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenContractInfo, + quote: quoteTokenContractInfo, + amount: parseFloat(paramData.amount), + expectedIn: expectedAmount / quoteDenomMultiplier, + price: price, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + txHash: tx.hash, + }) + } else { + res.status(200).json({ + error: swapMoreThanMaxPriceError, + message: `Swap price ${price} exceeds limitPrice ${limitPrice}` + }) + debug(`Swap price ${price} exceeds limitPrice ${limitPrice}`) + } + } else { + // sell + const minAmountOut = limitPrice / amount * baseDenomMultiplier + debug('minAmountOut', minAmountOut) + const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier + logger.info(`Price: ${price.toString()}`) + if (!limitPrice || price >= limitPrice) { + // pass swaps to exchange-proxy to complete trade + const tx = await balancer.swapExactIn( + wallet, + swaps, + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount.toString(), + parseInt(expectedAmount) / quoteDenomMultiplier, + gasPrice, + ) + // submit response + res.status(200).json({ + network: balancer.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenContractInfo, + quote: quoteTokenContractInfo, + amount: parseFloat(paramData.amount), + expectedOut: expectedAmount / quoteDenomMultiplier, + price: price, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + txHash: tx.hash, + }) + } else { + res.status(200).json({ + error: swapLessThanMaxPriceError, + message: `Swap price ${price} lower than limitPrice ${limitPrice}` + }) + debug(`Swap price ${price} lower than limitPrice ${limitPrice}`) + } + } + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +export default router; diff --git a/src/routes/celo.route.js b/src/routes/celo.route.js new file mode 100644 index 0000000..a5ad910 --- /dev/null +++ b/src/routes/celo.route.js @@ -0,0 +1,252 @@ +'use strict' + +const express = require('express') +const router = express.Router() +const BigNumber = require('bignumber.js'); +const debug = require('debug')('router') +const spawn = require('child_process').spawn + +const network = 'celo' +const celocli = 'celocli' +const DENOM_UNIT_MULTIPLIER = BigNumber('1e+18') + +const hbUtils = require('../services/utils') +const separator = '=>' + +router.use((req, res, next) => { + debug('celo route:', Date.now()) + next() +}) + +router.get('/', (req, res) => { + res.status(200).send(network) +}) + +router.get('/status', (req, res) => { + /* + return if the celocli ultralight node is synced + */ + + const nodeSync = spawn(celocli, ['node:synced']); + + let err_message = [], out_message = [] + + nodeSync.stdout.on( 'data', out => { + out_message.push(out.toString().trim()) + debug('out_message', out_message) + }) + + nodeSync.stderr.on( 'data', err => { + err_message.push(err.toString().trim()) + debug('err_message', err_message) + }) + + nodeSync.on( 'close', code => { + if (code === 0) { + res.status(200).json({ + synced: out_message[0].toLowerCase() === 'true', + message: err_message.join('') + }) + } else { + res.status(401).json({ + error: err_message.join('') + }) + } + }) +}) + + +router.get('/price', (req, res) => { + /* + api request format: + /price?trading_pair=CELO-CUSD&trade_type=sell&amount=1.2345 + */ + const keyFormat = ['trading_pair', 'trade_type', 'amount'] + + const initTime = Date.now() + + const paramData = hbUtils.getParamData(req.query, keyFormat) + const tradingPair = paramData.trading_pair + const tradeType = paramData.trade_type + const requestAmount = paramData.amount + const amount = parseFloat(requestAmount) * DENOM_UNIT_MULTIPLIER + debug('params', req.params) + debug('paramData', paramData) + + const nodeSync = spawn(celocli, ["exchange:show", "--amount", amount]); + + let err_message = [], out_message = [] + + nodeSync.stdout.on( 'data', out => { + out_message.push(out.toString().trim()) + }) + + nodeSync.stderr.on( 'data', err => { + err_message.push(err.toString().trim()) + }) + + nodeSync.on( 'close', code => { + + let exchange_rates = {} + let price + + if (code === 0) { + // extract exchange rate from cli output + out_message.forEach((item, index) => { + if (item.includes(separator)) { + let exchangeInfo = item.split(separator) + let base = exchangeInfo[0].trim().split(' ') + let quote = exchangeInfo[1].trim().split(' ') + let market = [base[1].toUpperCase(), quote[1].toUpperCase()].join('-') + exchange_rates[market] = quote[0]/DENOM_UNIT_MULTIPLIER + debug (exchangeInfo, exchange_rates) + } + }) + + price = exchange_rates[tradingPair] + + const result = Object.assign(paramData, { + price: price, + timestamp: initTime, + latency: hbUtils.latency(initTime, Date.now()), + } + ) + res.status(200).json(result) + } + }) + +}) + +router.get('/balance', (req, res) => { + /* + api request format: + /balance?address=0x87A4...b120 + */ + const keyFormat = ['address'] + const paramData = hbUtils.getParamData(req.query, keyFormat) + const address = paramData.address + debug(paramData) + + const balance = spawn(celocli, ["account:balance", address]); + + let err_message = [], out_message = [] + let walletBalances = {} + + balance.stdout.on( 'data', out => { + out_message.push(out.toString().trim()) + debug(out_message) + }) + + balance.stderr.on( 'data', err => { + err_message.push(err.toString().trim()) + debug(err_message) + }) + + balance.on( 'close', code => { + if (code === 0) { + out_message.forEach((item, index) => { + // key indicator in balance result: "celo", "gold", "lockedcelo", "lockedgold", "usd", "pending" + if (item.toLowerCase().includes( "lockedcelo") || item.toLowerCase().includes("lockedgold")) { + let balanceArray = item.split('\n') + balanceArray.forEach((x) => { + let keyValue = x.split(':') + walletBalances[keyValue[0].trim()] = keyValue[1].trim()/DENOM_UNIT_MULTIPLIER + } + ) + debug('walletBalances', walletBalances) + } + }) + + res.status(200).json({ + address: address, + balance: walletBalances, + timestamp: Date.now() + }) + } else { + res.status(401).json({ + error: err_message, + }) + } + }) +}) + + +router.post('/unlock', (req, res) => { + /* + api request format: + POST: /balance + data: { + "address": "0x87A4...b120", + "secret": "mysupersecret" + } + */ + const keyFormat = ['address', 'secret'] + const paramData = hbUtils.getParamData(req.body, keyFormat) + const address = paramData.address + const secret = paramData.secret + + debug(paramData) + debug(req.body) + + const lockStatus = spawn(celocli, ["account:unlock", address, "--password", secret]); + + let err_message = [], out_message = [] + + lockStatus.stdout.on( 'data', out => { + out_message.push(out.toString().trim()) + debug(out_message) + }) + + lockStatus.stderr.on( 'data', err => { + err_message.push(err.toString().trim()) + debug(err_message) + }) + + lockStatus.on( 'close', code => { + let unlocked = false + if (code === 0) { + if (out_message.length > 0) { + out_message.forEach((item, index) => { + if (item.includes(separator)) { + debug('item', item) + } + }) + } else { + unlocked = true + } + res.status(200).json({ + unlocked: unlocked, + message: out_message.join(), + timestamp: Date.now() + }) + } else { + res.status(401).json({ + error: err_message.join(), + }) + } + }) +}) + +router.post('/trade', (req, res) => { + /* + api request format: + POST: /trade + data: { + "trading_pair": "CELO-CUSD", + "trade_type": "buy", + "amount": 1.234, + "price": 3.512 + } + */ + const keyFormat = ['trading_pair', 'trade_type', 'amount', 'price'] + const paramData = hbUtils.getParamData(req.body, keyFormat) + debug(paramData) + // const result = Object.assign(paramData, { + // message: 'WIP', + // timestamp: Date.now() + // }) + res.status(200).json({"status": "WIP"}) +}) + + +module.exports = router diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js new file mode 100644 index 0000000..bc45b35 --- /dev/null +++ b/src/routes/eth.route.js @@ -0,0 +1,429 @@ +import { ethers, BigNumber } from 'ethers'; +import express from 'express'; + +import { getParamData, latency, statusMessages } from '../services/utils'; +import Ethereum from '../services/eth'; +import Fees from '../services/fees'; +import { logger } from '../services/logger'; + +const debug = require('debug')('router') +const router = express.Router() +const globalConfig = require('../services/configuration_manager').configManagerInstance +const eth = new Ethereum(globalConfig.getConfig("ETHEREUM_CHAIN")) +const spenders = { + balancer: globalConfig.getConfig("EXCHANGE_PROXY"), + uniswap: globalConfig.getConfig("UNISWAP_ROUTER") +} +const fees = new Fees() + +router.post('/', async (req, res) => { + /* + POST / + */ + res.status(200).json({ + network: eth.network, + rpcUrl: eth.provider.connection.url, + connection: true, + timestamp: Date.now(), + }) +}) + +router.post('/balances', async (req, res) => { + /* + POST: /balances + x-www-form-urlencoded: { + privateKey:{{privateKey}} + tokenList:{{tokenList}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet + try { + wallet = new ethers.Wallet(privateKey, eth.provider) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + + // populate token contract info using token symbol list + const tokenContractList = [] + const tokenList = JSON.parse(paramData.tokenList) + tokenList.forEach(symbol => { + const tokenContractInfo = eth.getERC20TokenAddresses(symbol) + tokenContractList[symbol] = tokenContractInfo + }); + + const balances = {} + balances.ETH = await eth.getETHBalance(wallet, privateKey) + try { + Promise.all( + Object.keys(tokenContractList).map(async (symbol, index) => { + if (tokenContractList[symbol] !== undefined) { + const address = tokenContractList[symbol].address + const decimals = tokenContractList[symbol].decimals + balances[symbol] = await eth.getERC20Balance(wallet, address, decimals) + } else { + const err = `Token contract info for ${symbol} not found` + logger.error('Token info not found', { message: err }) + debug(err) + } + } + )).then(() => { + console.log('eth.route - Get Account Balance', { message: JSON.stringify(tokenList) }) + res.status(200).json({ + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + balances: balances + }) + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/allowances', async (req, res) => { + /* + POST: /allowances + x-www-form-urlencoded: { + privateKey:{{privateKey}} + tokenAddressList:{{tokenAddressList}} + connector:{{connector_name}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const spender = spenders[paramData.connector] + let wallet + try { + wallet = new ethers.Wallet(privateKey, eth.provider) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + + // populate token contract info using token symbol list + const tokenContractList = [] + const tokenList = JSON.parse(paramData.tokenList) + tokenList.forEach(symbol => { + const tokenContractInfo = eth.getERC20TokenAddresses(symbol) + tokenContractList[symbol] = tokenContractInfo + }); + + const approvals = {} + try { + Promise.all( + Object.keys(tokenContractList).map(async (symbol, index) => { + const address = tokenContractList[symbol].address + const decimals = tokenContractList[symbol].decimals + approvals[symbol] = await eth.getERC20Allowance(wallet, spender, address, decimals) + } + )).then(() => { + logger.info('eth.route - Getting allowances', { message: JSON.stringify(tokenList) }) + res.status(200).json({ + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + spender: spender, + approvals: approvals, + }) + } + ) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/balances-2', async (req, res) => { + /* + POST: /balances + x-www-form-urlencoded: { + privateKey:{{privateKey}} + tokenAddressList:{{tokenAddressList}} + tokenDecimalList:{{tokenDecimalList}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet + try { + wallet = new ethers.Wallet(privateKey, eth.provider) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + let tokenAddressList + if (paramData.tokenAddressList) { + tokenAddressList = paramData.tokenAddressList.split(',') + } + let tokenDecimalList + if (paramData.tokenDecimalList) { + tokenDecimalList = paramData.tokenDecimalList.split(',') + } + + const balances = {} + balances.ETH = await eth.getETHBalance(wallet, privateKey) + try { + Promise.all( + tokenAddressList.map(async (value, index) => + balances[value] = await eth.getERC20Balance(wallet, value, tokenDecimalList[index]) + )).then(() => { + res.status(200).json({ + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + balances: balances + }) + }) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/allowances-2', async (req, res) => { + /* + POST: /allowances + x-www-form-urlencoded: { + privateKey:{{privateKey}} + tokenAddressList:{{tokenAddressList}} + tokenDecimalList:{{tokenDecimalList}} + connector:{{connector_name}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const spender = spenders[paramData.connector] + let wallet + try { + wallet = new ethers.Wallet(privateKey, eth.provider) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + let tokenAddressList + if (paramData.tokenAddressList) { + tokenAddressList = paramData.tokenAddressList.split(',') + } + let tokenDecimalList + if (paramData.tokenDecimalList) { + tokenDecimalList = paramData.tokenDecimalList.split(',') + } + + const approvals = {} + try { + Promise.all( + tokenAddressList.map(async (value, index) => + approvals[value] = await eth.getERC20Allowance(wallet, spender, value, tokenDecimalList[index]) + )).then(() => { + res.status(200).json({ + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + spender: spender, + approvals: approvals, + }) + } + ) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/approve', async (req, res) => { + /* + POST: /approve + x-www-form-urlencoded: { + privateKey:{{privateKey}} + tokenAddress:"0x....." + decimals: {{token_decimals}} + connector:{{connector_name}} + amount:{{amount}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const spender = spenders[paramData.connector] + let wallet + try { + wallet = new ethers.Wallet(privateKey, eth.provider) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + const token = paramData.token + const tokenContractInfo = eth.getERC20TokenAddresses(token) + const tokenAddress = tokenContractInfo.address + const decimals = tokenContractInfo.decimals + + let amount + paramData.amount ? amount = ethers.utils.parseUnits(paramData.amount, decimals) + : amount = ethers.utils.parseUnits('1000000000', decimals) // approve for 1 billion units if no amount specified + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + + try { + // call approve function + const approval = await eth.approveERC20(wallet, spender, tokenAddress, amount, gasPrice) + // console.log('eth.route - Approving allowance', { message: approval }) + // submit response + res.status(200).json({ + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + tokenAddress: tokenAddress, + spender: spender, + amount: amount / 1e18.toString(), + approval: approval + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/poll', async (req, res) => { + const initTime = Date.now() + const paramData = getParamData(req.body) + const txHash = paramData.txHash + const txReceipt = await eth.provider.getTransactionReceipt(txHash) + const receipt = {} + const confirmed = txReceipt && txReceipt.blockNumber ? true : false + if (confirmed) { + receipt.gasUsed = BigNumber.from(txReceipt.gasUsed).toNumber() + receipt.blockNumber = txReceipt.blockNumber + receipt.confirmations = txReceipt.confirmations + receipt.status = txReceipt.status + } + logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }) + res.status(200).json({ + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + txHash: txHash, + confirmed: confirmed, + receipt: receipt, + }) + return txReceipt +}) + +// Kovan faucet to get test tokens (wip) & weth conversion +// router.post('/get-weth', async (req, res) => { +// /* +// POST: /get-weth +// x-www-form-urlencoded: { +// gasPrice:{gasPrice} +// amount:{{amount}} +// privateKey:{{privateKey}} +// } +// */ +// const initTime = Date.now() +// const paramData = getParamData(req.body) +// const privateKey = paramData.privateKey +// let wallet +// try { +// wallet = new ethers.Wallet(privateKey, eth.provider) +// } catch (err) { +// logger.error(req.originalUrl, { message: err }) +// let reason +// err.reason ? reason = err.reason : reason = 'Error getting wallet' +// res.status(500).json({ +// error: reason, +// message: err +// }) +// return +// } +// const amount = ethers.utils.parseEther(paramData.amount) +// const tokenAddress = eth.getERC20TokenAddresses('WETH').address +// let gasPrice +// if (paramData.gasPrice) { +// gasPrice = parseFloat(paramData.gasPrice) +// } + +// try { +// // call deposit function +// const response = await eth.deposit(wallet, tokenAddress, amount, gasPrice) + +// // submit response +// res.status(200).json({ +// network: eth.network, +// timestamp: initTime, +// amount: parseFloat(amount), +// result: response +// }) +// } catch (err) { +// logger.error(req.originalUrl, { message: err }) +// let reason +// err.reason ? reason = err.reason : reason = statusMessages.operation_error +// res.status(500).json({ +// error: reason, +// message: err +// }) +// } +// }) + +module.exports = router; diff --git a/src/routes/index.route.js b/src/routes/index.route.js new file mode 100644 index 0000000..6e9fe6c --- /dev/null +++ b/src/routes/index.route.js @@ -0,0 +1,38 @@ +import { getParamData, latency, statusMessages, loadConfig, updateConfig } from '../services/utils'; + +const express = require('express'); + +const router = express.Router(); + +router.get('/', (req, res) => { + res.status(200).json({ + config: loadConfig(), + status: 'ok', + }); +}) + +router.post('/update', async (req, res) => { + /* + POST: /update-config + x-www-form-urlencoded: {"key": "value",} + note: param can be set individually + */ + const paramData = getParamData(req.body) + + try { + console.log(updateConfig(paramData)) + const config = loadConfig() + res.status(200).json({ + config: config + }) + } catch (err) { + console.log(err) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) +module.exports = router; diff --git a/src/routes/perpetual_finance.route.js b/src/routes/perpetual_finance.route.js new file mode 100644 index 0000000..6711759 --- /dev/null +++ b/src/routes/perpetual_finance.route.js @@ -0,0 +1,518 @@ +import { ethers, BigNumber } from 'ethers'; +import express from 'express'; +import { getParamData, latency, statusMessages } from '../services/utils'; +import { logger } from '../services/logger'; +import PerpetualFinance from '../services/perpetual_finance'; + + +const router = express.Router() +const globalConfig = require('../services/configuration_manager').configManagerInstance +const perpFi = new PerpetualFinance(globalConfig.getConfig("ETHEREUM_CHAIN")) +setTimeout(perpFi.update_price_loop.bind(perpFi), 2000) + +const getErrorMessage = (err) => { + /* + [WIP] Custom error message based-on string match + */ + let message = err + return message +} + +router.get('/', async (req, res) => { + /* + GET / + */ + res.status(200).json({ + network: perpFi.network, + provider: perpFi.provider.connection.url, + loadedMetadata: perpFi.loadedMetadata, + connection: true, + timestamp: Date.now(), + }) +}) + +router.get('/load-metadata', async (req, res) => { + /* + GET / + */ + const loadedMetadata = await perpFi.load_metadata() + res.status(200).json({ + network: perpFi.network, + provider: perpFi.provider.connection.url, + loadedMetadata: loadedMetadata, + connection: true, + timestamp: Date.now(), + }) +}) + +router.post('/balances', async (req, res) => { + /* + POST: /balances + x-www-form-urlencoded: { + privateKey:{{privateKey}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet + try { + wallet = new ethers.Wallet(privateKey, perpFi.provider) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + + const balances = {} + balances["XDAI"] = await perpFi.getXdaiBalance(wallet) + balances["USDC"] = await perpFi.getUSDCBalance(wallet) + try { + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + balances: balances + }) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/allowances', async (req, res) => { + /* + POST: /allowances + x-www-form-urlencoded: { + privateKey:{{privateKey}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet + try { + wallet = new ethers.Wallet(privateKey, perpFi.provider) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + + const approvals = {} + approvals["USDC"] = await perpFi.getAllowance(wallet) + try { + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + approvals: approvals + }) + } catch (err) { + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/approve', async (req, res) => { + /* + POST: /approve + x-www-form-urlencoded: { + privateKey:{{privateKey}} + amount:{{amount}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let amount + paramData.amount ? amount = paramData.amount + : amount = '1000000000' + let wallet + try { + wallet = new ethers.Wallet(privateKey, perpFi.provider) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + + try { + // call approve function + const approval = await perpFi.approve(wallet, amount) + logger.info('perpFi.route - Approving allowance') + // submit response + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + amount: amount, + approval: approval + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/open', async (req, res) => { + /* + POST: /open + x-www-form-urlencoded: { + side:{{side}} + pair:{{pair}} + margin:{{margin}} + leverage:{{leverage}} + minBaseAssetAmount:{{minBaseAssetAmount}} + privateKey:{{privateKey}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const side = paramData.side + const pair = paramData.pair + const margin = paramData.margin + const leverage = paramData.leverage + const minBaseAssetAmount = paramData.minBaseAssetAmount + console.log(minBaseAssetAmount) + const privateKey = paramData.privateKey + let wallet + try { + wallet = new ethers.Wallet(privateKey, perpFi.provider) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + + try { + // call openPosition function + const tx = await perpFi.openPosition(side, margin, leverage, pair, minBaseAssetAmount, wallet) + logger.info('perpFi.route - Opening position') + // submit response + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + margin: margin, + side: side, + leverage: leverage, + minBaseAssetAmount: minBaseAssetAmount, + txHash: tx.hash + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/close', async (req, res) => { + /* + POST: /close + x-www-form-urlencoded: { + minimalQuoteAsset:{{minimalQuoteAsset}} + privateKey:{{privateKey}} + pair:{{pair}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const minimalQuoteAsset = paramData.minimalQuoteAsset + const privateKey = paramData.privateKey + const pair = paramData.pair + let wallet + try { + wallet = new ethers.Wallet(privateKey, perpFi.provider) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + + try { + // call closePosition function + const tx = await perpFi.closePosition(wallet, pair, minimalQuoteAsset) + logger.info('perpFi.route - Closing position') + // submit response + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + minimalQuoteAsset: minimalQuoteAsset, + txHash: tx.hash + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + + +router.post('/position', async (req, res) => { + /* + POST: /position + x-www-form-urlencoded: { + privateKey:{{privateKey}} + pair:{{pair}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const pair = paramData.pair + let wallet + try { + wallet = new ethers.Wallet(privateKey, perpFi.provider) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + + try { + // call getPosition function + const position = await perpFi.getPosition(wallet, pair) + logger.info('perpFi.route - getting active position') + // submit response + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + position: position + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/margin', async (req, res) => { + /* + POST: /margin + x-www-form-urlencoded: { + privateKey:{{privateKey}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet + try { + wallet = new ethers.Wallet(privateKey, perpFi.provider) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = 'Error getting wallet' + res.status(500).json({ + error: reason, + message: err + }) + return + } + + try { + // call getAllBalances function + const allBalances = await perpFi.getActiveMargin(wallet) + logger.info('perpFi.route - Getting all balances') + // submit response + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + margin: allBalances + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/receipt', async (req, res) => { + /* + POST: /receipt + x-www-form-urlencoded: { + txHash:{{txHash}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const txHash = paramData.txHash + const txReceipt = await perpFi.provider.getTransactionReceipt(txHash) + const receipt = {} + const confirmed = txReceipt && txReceipt.blockNumber ? true : false + if (txReceipt !== null) { + receipt.gasUsed = ethers.utils.formatEther(txReceipt.gasUsed) + receipt.blockNumber = txReceipt.blockNumber + receipt.confirmations = txReceipt.confirmations + receipt.status = txReceipt.status + } + logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }) + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + txHash: txHash, + confirmed: confirmed, + receipt: receipt, + }) + return txReceipt +}) + +router.post('/price', async (req, res) => { + /* + POST: /price + x-www-form-urlencoded: { + side:{{side}} + pair:{{pair}} + amount:{{amount}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const side = paramData.side + const pair = paramData.pair + const amount = paramData.amount + + try { + // call getPrice function + const price = await perpFi.getPrice(side, amount, pair) + logger.info('perpFi.route - Getting price') + // submit response + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + side: side, + price: price + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + + +router.get('/pairs', async (req, res) => { + /* + GET + */ + const initTime = Date.now() + + try { + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + pairs: Object.keys(perpFi.amm) + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/funding', async (req, res) => { + /* + POST: /funding + x-www-form-urlencoded: { + pair:{{pair}} + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const pair = paramData.pair + + try { + // call getFundingRate function + const fr = await perpFi.getFundingRate(pair) + logger.info('perpFi.route - Getting funding info') + // submit response + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + fr: fr + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +export default router; diff --git a/src/routes/terra.route.js b/src/routes/terra.route.js new file mode 100644 index 0000000..f2c64c3 --- /dev/null +++ b/src/routes/terra.route.js @@ -0,0 +1,228 @@ +'use strict' + +import express from 'express' +import { getParamData, latency, reportConnectionError, statusMessages } from '../services/utils'; +import { logger } from '../services/logger'; + +import Terra from '../services/terra'; + +const debug = require('debug')('router') +const router = express.Router(); +const terra = new Terra() + +// constants +const network = terra.lcd.config.chainID +const denomUnitMultiplier = terra.denomUnitMultiplier + +router.post('/', async (req, res) => { + /* + POST / + */ + res.status(200).json({ + network: network, + lcdUrl: terra.lcd.config.URL, + gasPrices: terra.lcd.config.gasPrices, + gasAdjustment: terra.lcd.config.gasAdjustment, + connection: true, + timestamp: Date.now() + }) +}) + +router.post('/balances', async (req, res) => { + /* + POST: + address:{{address}} + */ + const initTime = Date.now() + + const paramData = getParamData(req.body) + const address = paramData.address + + let balances = {} + + try { + await terra.lcd.bank.balance(address).then(bal => { + bal.toArray().forEach(async (x) => { + const item = x.toData() + const denom = item.denom + const amount = item.amount / denomUnitMultiplier + const symbol = terra.tokens[denom].symbol + balances[symbol] = amount + }) + }) + logger.info('terra.route - Get Account Balance') + res.status(200).json({ + network: network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + balances: balances, + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let message + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + const isAxiosError = err.isAxiosError + if (isAxiosError) { + reason = err.response.status + message = err.response.statusText + } else { + message = err + } + res.status(500).json({ + error: reason, + message: message + }) + } +}) + +router.post('/start', async (req, res) => { + /* + POST: /terra/start + x-www-form-urlencoded: { + "base":"UST" + "quote":"KRT" + "amount":1 + } + */ + const initTime = Date.now() + const paramData = getParamData(req.body) + const baseTokenSymbol = paramData.base + const quoteTokenSymbol = paramData.quote + + const result = { + network: network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + success: true, + base: baseTokenSymbol, + quote: quoteTokenSymbol, + } + res.status(200).json(result) +}) + +router.post('/price', async (req, res) => { + /* + POST: + x-www-form-urlencoded: { + "base":"UST" + "quote":"KRT" + "side":"buy" or "sell" + "amount":1 + } + */ + const initTime = Date.now() + + const paramData = getParamData(req.body) + const baseToken = paramData.base + const quoteToken = paramData.quote + const tradeType = paramData.side.toUpperCase() + const amount = parseFloat(paramData.amount) + + let exchangeRate + + try { + await terra.getSwapRate(baseToken, quoteToken, amount, tradeType).then((rate) => { + exchangeRate = rate + }).catch((err) => { + reportConnectionError(res, err) + }) + + res.status(200).json( + { + network: network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseToken, + quote: quoteToken, + amount: amount, + tradeType: tradeType, + price: exchangeRate.price.amount, + cost: exchangeRate.cost.amount, + txFee: exchangeRate.txFee.amount, + } + ) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let message + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + const isAxiosError = err.isAxiosError + if (isAxiosError) { + reason = err.response.status + message = err.response.statusText + } else { + message = err + } + res.status(500).json({ + error: reason, + message: message + }) + } +}) + +router.post('/trade', async (req, res) => { + /* + POST: /trade + data: { + "base":"UST" + "quote":"KRT" + "side":"buy" or "sell" + "amount":1 + "secret": "mysupersecret" + } + */ + const initTime = Date.now() + + const paramData = getParamData(req.body) + const baseToken = paramData.base + const quoteToken = paramData.quote + const tradeType = paramData.side.toUpperCase() + const amount = parseFloat(paramData.amount) + const gasPrice = parseFloat(paramData.gas_price) || terra.lcd.config.gasPrices.uluna + const gasAdjustment = paramData.gas_adjustment || terra.lcd.config.gasAdjustment + const secret = paramData.privateKey + + let tokenSwaps + + try { + await terra.swapTokens(baseToken, quoteToken, amount, tradeType, gasPrice, gasAdjustment, secret).then((swap) => { + tokenSwaps = swap + }).catch((err) => { + reportConnectionError(res, err) + }) + + const swapResult = { + network: network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseToken, + tradeType: tradeType, + quote: quoteToken, + amount: amount, + } + Object.assign(swapResult, tokenSwaps); + logger.info(`terra.route - ${tradeType}: ${baseToken}-${quoteToken} - Amount: ${amount}`) + res.status(200).json( + swapResult + ) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let message + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + const isAxiosError = err.isAxiosError + if (isAxiosError) { + reason = err.response.status + message = err.response.statusText + } else { + message = err + } + res.status(500).json({ + error: reason, + message: message + }) + } +}) + +module.exports = router; diff --git a/src/routes/uniswap.route.js b/src/routes/uniswap.route.js new file mode 100644 index 0000000..00a1643 --- /dev/null +++ b/src/routes/uniswap.route.js @@ -0,0 +1,367 @@ +import { ethers } from 'ethers'; +import express from 'express'; + +import { getParamData, latency, statusMessages } from '../services/utils'; +import { logger } from '../services/logger'; +import Ethereum from '../services/eth'; +import Uniswap from '../services/uniswap'; +import Fees from '../services/fees'; + + +const debug = require('debug')('router') +const router = express.Router() +const globalConfig = require('../services/configuration_manager').configManagerInstance +const eth = new Ethereum(globalConfig.getConfig("ETHEREUM_CHAIN")) +const uniswap = new Uniswap(globalConfig.getConfig("ETHEREUM_CHAIN")) +uniswap.generate_tokens() +setTimeout(uniswap.update_pairs.bind(uniswap), 2000) +const fees = new Fees() + +const swapMoreThanMaxPriceError = 'Price too high' +const swapLessThanMaxPriceError = 'Price too low' + +const estimateGasLimit = () => { + return uniswap.gasLimit +} + +const getErrorMessage = (err) => { + /* + [WIP] Custom error message based-on string match + */ + let message = err + if (err.includes('failed to meet quorum')) { + message = 'Failed to meet quorum in Uniswap' + } else if (err.includes('Invariant failed: ADDRESSES')) { + message = 'Invariant failed: ADDRESSES' + } else if (err.includes('"call revert exception')) { + message = statusMessages.no_pool_available + } else if (err.includes('"trade" is read-only')) { + message = statusMessages.no_pool_available + } + return message +} + +router.post('/', async (req, res) => { + /* + POST / + */ + res.status(200).json({ + network: uniswap.network, + provider: uniswap.provider.connection.url, + uniswap_router: uniswap.router, + connection: true, + timestamp: Date.now(), + }) +}) + +router.post('/gas-limit', async (req, res) => { + /* + POST: /buy-price + */ + const gasLimit = estimateGasLimit() + + try { + res.status(200).json({ + network: uniswap.network, + gasLimit: gasLimit, + timestamp: Date.now(), + }) + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.get('/start', async (req, res) => { + /* + POST: /eth/uniswap/start + x-www-form-urlencoded: { + "pairs":"[ETH-USDT, ...]" + "gasPrice":30 + } + */ + const initTime = Date.now() + const paramData = getParamData(req.query) + const pairs = JSON.parse(paramData.pairs) + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + + // get token contract address and cache paths + for (let pair of pairs){ + pair = pair.split("-") + const baseTokenSymbol = pair[0] + const quoteTokenSymbol = pair[1] + const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) + + // check for valid token symbols + if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { + const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol + res.status(500).json({ + error: `Token ${undefinedToken} contract address not found`, + message: `Token contract address not found for ${undefinedToken}. Check token list source`, + }) + return + } + await Promise.allSettled([uniswap.extend_update_pairs([baseTokenContractInfo.address, quoteTokenContractInfo.address])]) + } + + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + + const result = { + network: eth.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + success: true, + pairs: pairs, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + } + res.status(200).json(result) +}) + +router.post('/trade', async (req, res) => { + /* + POST: /trade + x-www-form-urlencoded: { + "quote":"BAT" + "base":"DAI" + "amount":0.1 + "limitPrice":1 + "gasPrice":10 + "privateKey":{{privateKey}} + "side":{buy|sell} + } + */ + const initTime = Date.now() + // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, uniswap.provider) + const amount = paramData.amount + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const side = paramData.side.toUpperCase() + + let limitPrice + if (paramData.limitPrice) { + limitPrice = parseFloat(paramData.limitPrice) + } + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + try { + // fetch the optimal pool mix from uniswap + const { trade, expectedAmount } = side === 'BUY' + ? await uniswap.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount + ) + : await uniswap.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount + ) + + if (side === 'BUY') { + const price = trade.executionPrice.invert().toSignificant(8) + logger.info(`uniswap.route - Price: ${price.toString()}`) + if (!limitPrice || price <= limitPrice) { + // pass swaps to exchange-proxy to complete trade + const tx = await uniswap.swapExactOut( + wallet, + trade, + baseTokenAddress, + gasPrice, + ) + // submit response + res.status(200).json({ + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenAddress, + quote: quoteTokenAddress, + amount: amount, + expectedIn: expectedAmount.toSignificant(8), + price: price, + gasPrice: gasPrice, + gasLimit, gasLimit, + gasCost, gasCost, + txHash: tx.hash, + }) + } else { + res.status(200).json({ + error: swapMoreThanMaxPriceError, + message: `Swap price ${price} exceeds limitPrice ${limitPrice}` + }) + logger.info(`uniswap.route - Swap price ${price} exceeds limitPrice ${limitPrice}`) + } + } else { + // sell + const price = trade.executionPrice.toSignificant(8) + logger.info(`Price: ${price.toString()}`) + if (!limitPrice || price >= limitPrice) { + // pass swaps to exchange-proxy to complete trade + const tx = await uniswap.swapExactIn( + wallet, + trade, + baseTokenAddress, + gasPrice, + ) + // submit response + res.status(200).json({ + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenAddress, + quote: quoteTokenAddress, + amount: parseFloat(paramData.amount), + expectedOut: expectedAmount.toSignificant(8), + price: parseFloat(price), + gasPrice: gasPrice, + gasLimit, gasLimit, + gasCost: gasCost, + txHash: tx.hash, + }) + } else { + res.status(200).json({ + error: swapLessThanMaxPriceError, + message: `Swap price ${price} lower than limitPrice ${limitPrice}` + }) + logger.info(`uniswap.route - Swap price ${price} lower than limitPrice ${limitPrice}`) + } + } + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? reason = err.reason : reason = statusMessages.operation_error + res.status(500).json({ + error: reason, + message: err + }) + } +}) + +router.post('/price', async (req, res) => { + /* + POST: /price + x-www-form-urlencoded: { + "quote":"BAT" + "base":"DAI" + "amount":1 + } + */ + const initTime = Date.now() + // params: base (required), quote (required), amount (required) + const paramData = getParamData(req.body) + const amount = paramData.amount + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const side = paramData.side.toUpperCase() + let gasPrice + if (paramData.gasPrice) { + gasPrice = parseFloat(paramData.gasPrice) + } else { + gasPrice = fees.ethGasPrice + } + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) + + + try { + // fetch the optimal pool mix from uniswap + const { trade, expectedAmount } = side === 'BUY' + ? await uniswap.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount + ) + : await uniswap.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount + ) + + if (trade !== null && expectedAmount !== null) { + const price = side === 'BUY' + ? trade.executionPrice.invert().toSignificant(8) + : trade.executionPrice.toSignificant(8) + + const tradeAmount = parseFloat(amount) + const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)) + const tradePrice = parseFloat(price) + + const result = { + network: uniswap.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseTokenAddress, + quote: quoteTokenAddress, + amount: tradeAmount, + expectedAmount: expectedTradeAmount, + price: tradePrice, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + trade: trade, + } + debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) + res.status(200).json(result) + } else { // no pool available + res.status(200).json({ + info: statusMessages.no_pool_available, + message: '' + }) + } + } catch (err) { + logger.error(req.originalUrl, { message: err }) + let reason + let errCode = 500 + if (Object.keys(err).includes('isInsufficientReservesError')) { + errCode = 200 + reason = statusMessages.insufficient_reserves + ' in ' + side + ' at Uniswap' + } else if (Object.getOwnPropertyNames(err).includes('message')) { + reason = getErrorMessage(err.message) + if (reason === statusMessages.no_pool_available) { + errCode = 200 + res.status(errCode).json({ + info: reason, + message: err + }) + } + } else { + err.reason ? reason = err.reason : reason = statusMessages.operation_error + } + res.status(errCode).json({ + error: reason, + message: err + }) + } +}) + +export default router; diff --git a/src/services/access.js b/src/services/access.js new file mode 100644 index 0000000..708f3aa --- /dev/null +++ b/src/services/access.js @@ -0,0 +1,25 @@ +/* + middleware for validating mutual authentication access +*/ + +import { logger } from './logger'; +import { statusMessages } from './utils'; +const debug = require('debug')('router') + +export const validateAccess = (req, res, next) => { + const cert = req.connection.getPeerCertificate() + if (req.client.authorized) { + const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress + const method = req.method + const url = req.url + const requestInfo = 'Request from IP: ' + ip + ' ' + method + ' ' + url + console.log(requestInfo) + next() + } else if (cert.subject) { + logger.error(statusMessages.ssl_cert_invalid) + res.status(403).send({ error: statusMessages.ssl_cert_invalid }) + } else { + logger.error(statusMessages.ssl_cert_required) + res.status(401).send({ error: statusMessages.ssl_cert_required }) + } +} diff --git a/src/services/balancer.js b/src/services/balancer.js new file mode 100644 index 0000000..60eba56 --- /dev/null +++ b/src/services/balancer.js @@ -0,0 +1,206 @@ +import { logger } from '../services/logger'; +const debug = require('debug')('router') +const sor = require('@balancer-labs/sor') +const BigNumber = require('bignumber.js') +const ethers = require('ethers') +const proxyArtifact = require('../static/ExchangeProxy.json') +const globalConfig = require('../services/configuration_manager').configManagerInstance + +// constants +const MULTI = '0xeefba1e63905ef1d7acba5a8513c70307c1ce441'; +const MULTI_KOVAN = ' 0x2cc8688C5f75E365aaEEb4ea8D6a480405A48D2A'; +const MAX_UINT = ethers.constants.MaxUint256; +const GAS_BASE = globalConfig.getConfig("BALANCER_GAS_BASE") || 200688; +const GAS_PER_SWAP = globalConfig.getConfig("BALANCER_GAS_PER_SWAP") || 100000; + +export default class Balancer { + constructor (network = 'kovan') { + const providerUrl = globalConfig.getConfig("ETHEREUM_RPC_URL") + this.network = globalConfig.getConfig("ETHEREUM_CHAIN") + this.provider = new ethers.providers.JsonRpcProvider(providerUrl) + this.subgraphUrl = globalConfig.getConfig("REACT_APP_SUBGRAPH_URL") + this.gasBase = GAS_BASE + this.gasPerSwap = GAS_PER_SWAP + this.maxSwaps = globalConfig.getConfig("BALANCER_MAX_SWAPS") || 4 + this.exchangeProxy = globalConfig.getConfig("EXCHANGE_PROXY") + this.cachedPools = [] + + switch (network) { + case 'mainnet': + this.multiCall = MULTI; + break; + case 'kovan': + this.multiCall = MULTI_KOVAN; + break; + default: + const err = `Invalid network ${network}` + logger.error(err) + throw Error(err) + } + } + + async fetchPool (tokenIn, tokenOut) { + const pools = await sor.getPoolsWithTokens(tokenIn, tokenOut) + this.cachedPools[tokenIn + tokenOut] = pools + + if (pools.pools.length === 0) { + debug('>>> No pools contain the tokens provided.', { message: this.network }); + return {}; + } + debug(`>>> ${pools.pools.length} Pools Retrieved.`, { message: this.network }) + } + + async getCachedPools (tokenIn, tokenOut) { + const cachePools = this.cachedPools[tokenIn + tokenOut].pools + debug(`>>> get cached Pools. ${tokenIn + tokenOut}`, { message: `total pools: ${cachePools.length}` }) + return cachePools + } + + async priceSwapIn (tokenIn, tokenOut, tokenInAmount, maxSwaps = this.maxSwaps) { + // Fetch all the pools that contain the tokens provided + try { + // Get current on-chain data about the fetched pools + await this.fetchPool(tokenIn, tokenOut) + + let poolData + const cachedPools = await this.getCachedPools(tokenIn, tokenOut) + if (this.network === 'mainnet') { + poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider) + } else { + // Kovan multicall throws an ENS error + poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) + } + + // Parse the pools and pass them to smart order outer to get the swaps needed + const sorSwaps = sor.smartOrderRouter( + poolData, // balancers: Pool[] + 'swapExactIn', // swapType: string + tokenInAmount, // targetInputAmount: BigNumber + new BigNumber(maxSwaps.toString()), // maxBalancers: number + 0 // costOutputToken: BigNumber + ) + + const swapsFormatted = sor.formatSwapsExactAmountIn(sorSwaps, MAX_UINT, 0) + const expectedAmount = sor.calcTotalOutput(swapsFormatted, poolData) + debug(`Expected Out: ${expectedAmount.toString()} (${tokenOut})`); + + // Create correct swap format for new proxy + let swaps = []; + for (let i = 0; i < swapsFormatted.length; i++) { + let swap = { + pool: swapsFormatted[i].pool, + tokenIn: tokenIn, + tokenOut: tokenOut, + swapAmount: swapsFormatted[i].tokenInParam, + limitReturnAmount: swapsFormatted[i].tokenOutParam, + maxPrice: swapsFormatted[i].maxPrice.toString(), + }; + swaps.push(swap); + } + return { swaps, expectedAmount } + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error in swapExactOut' + return reason + } + } + + async priceSwapOut (tokenIn, tokenOut, tokenOutAmount, maxSwaps = this.maxSwaps) { + // Fetch all the pools that contain the tokens provided + try { + // Get current on-chain data about the fetched pools + await this.fetchPool(tokenIn, tokenOut) + + let poolData + const cachedPools = await this.getCachedPools(tokenIn, tokenOut) + if (this.network === 'mainnet') { + poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider) + } else { + // Kovan multicall throws an ENS error + poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) + } + + // Parse the pools and pass them to smart order outer to get the swaps needed + const sorSwaps = sor.smartOrderRouter( + poolData, // balancers: Pool[] + 'swapExactOut', // swapType: string + tokenOutAmount, // targetInputAmount: BigNumber + new BigNumber(maxSwaps.toString()), // maxBalancers: number + 0 // costOutputToken: BigNumber + ) + const swapsFormatted = sor.formatSwapsExactAmountOut(sorSwaps, MAX_UINT, MAX_UINT) + const expectedAmount = sor.calcTotalInput(swapsFormatted, poolData) + debug(`Expected In: ${expectedAmount.toString()} (${tokenIn})`); + + // Create correct swap format for new proxy + let swaps = []; + for (let i = 0; i < swapsFormatted.length; i++) { + let swap = { + pool: swapsFormatted[i].pool, + tokenIn: tokenIn, + tokenOut: tokenOut, + swapAmount: swapsFormatted[i].tokenOutParam, + limitReturnAmount: swapsFormatted[i].tokenInParam, + maxPrice: swapsFormatted[i].maxPrice.toString(), + }; + swaps.push(swap); + } + return { swaps, expectedAmount } + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error in swapExactOut' + return reason + } + } + + async swapExactIn (wallet, swaps, tokenIn, tokenOut, amountIn, minAmountOut, gasPrice) { + debug(`Number of swaps: ${swaps.length}`) + try { + const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet) + const tx = await contract.batchSwapExactIn( + swaps, + tokenIn, + tokenOut, + amountIn, + 0, + { + gasPrice: gasPrice * 1e9, + gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP, + } + ) + debug(`Tx Hash: ${tx.hash}`); + return tx + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error in swapExactIn' + return reason + } + } + + async swapExactOut (wallet, swaps, tokenIn, tokenOut, expectedIn, gasPrice) { + debug(`Number of swaps: ${swaps.length}`) + try { + const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet) + const tx = await contract.batchSwapExactOut( + swaps, + tokenIn, + tokenOut, + expectedIn, + { + gasPrice: gasPrice * 1e9, + gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP, + } + ) + debug(`Tx Hash: ${tx.hash}`) + return tx + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error in swapExactOut' + return reason + } + } +} diff --git a/src/services/configuration_manager.js b/src/services/configuration_manager.js new file mode 100644 index 0000000..a8b901a --- /dev/null +++ b/src/services/configuration_manager.js @@ -0,0 +1,65 @@ +/* +The essence if this class is to maintain a persistent configuraion instance from +a global configuraion file. +*/ +import YAML from 'yaml' +import fs from 'fs' + +const GlobalConfigFilePath = "./conf/global_conf.yml" + +export default class ConfigurationManager { + constructor () { + this.globalConfFile = fs.readFileSync(GlobalConfigFilePath, 'utf8') + this.configs = YAML.parseDocument(this.globalConfFile) + this.fileWatcher() + } + + readAllConfigs(){ + return this.configs.toJSON() + } + + updateConfig(data){ + // Hummingbot client will ideally make 1 update per request. + // However, other softwares using gateway may be designed to update multiple configs per request. Hence, the reason for iterating. + let toExit = false + Object.keys(data).forEach(key => { + if (this.configs.get('CORE').has(key)) { + toExit = true + this.configs.get('CORE').set(key, data[key]) + } else { + this.configs.set(key, data[key]) + } + }) + fs.writeFileSync(GlobalConfigFilePath, this.configs.toString()) + + if (toExit) { process.exit(1)} + + // For now, Gateway will always restart whenever any config is updated. + // This behavior will be removed after support for multichain is added + process.exit(1) + } + + getConfig(key) { + return this.configs.get(key) + } + + fileWatcher() { + fs.watchFile(GlobalConfigFilePath, { persistent: true, interval: 1000 }, (curr, prev) => { + if (prev.mtime !== curr.mtime) { + const newConfigs = YAML.parseDocument(fs.readFileSync(GlobalConfigFilePath, 'utf8')) + if (JSON.stringify(this.readAllConfigs().CORE) === JSON.stringify(newConfigs.toJSON().CORE)) { + this.configs = newConfigs + } else { // restart gateway + process.exit(1) + } + + // For now, Gateway will always restart whenever any config is updated. + // This behavior will be removed after support for multichain is added + process.exit(1) + } + }); + } + +} + +export const configManagerInstance = new ConfigurationManager() diff --git a/src/services/eth.js b/src/services/eth.js new file mode 100644 index 0000000..53c856e --- /dev/null +++ b/src/services/eth.js @@ -0,0 +1,167 @@ +import { logger } from './logger'; +import axios from 'axios' + +const debug = require('debug')('router') +const fs = require('fs'); +const ethers = require('ethers') +const abi = require('../static/abi') +const globalConfig = require('../services/configuration_manager').configManagerInstance + + +// constants +const APPROVAL_GAS_LIMIT = globalConfig.getConfig("ETH_APPROVAL_GAS_LIMIT") || 50000; + +export default class Ethereum { + constructor (network = 'mainnet') { + // network defaults to kovan + const providerUrl = globalConfig.getConfig("ETHEREUM_RPC_URL") + this.provider = new ethers.providers.JsonRpcProvider(providerUrl) + this.erc20TokenListURL = globalConfig.getConfig("ETHEREUM_TOKEN_LIST_URL") + this.network = network + this.spenders = { + balancer: globalConfig.getConfig("EXCHANGE_PROXY"), + uniswap: globalConfig.getConfig("UNISWAP_ROUTER") + } + // update token list + this.getERC20TokenList() // erc20TokenList + } + + // get ETH balance + async getETHBalance (wallet) { + try { + const balance = await wallet.getBalance() + return balance / 1e18.toString() + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error ETH balance lookup' + return reason + } + } + + // get ERC-20 token balance + async getERC20Balance (wallet, tokenAddress, decimals = 18) { + // instantiate a contract and pass in provider for read-only access + const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider) + try { + const balance = await contract.balanceOf(wallet.address) + return balance / Math.pow(10, decimals).toString() + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error balance lookup' + return reason + } + } + + // get ERC-20 token allowance + async getERC20Allowance (wallet, spender, tokenAddress, decimals = 18) { + // instantiate a contract and pass in provider for read-only access + const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider) + try { + const allowance = await contract.allowance(wallet.address, spender) + return allowance / Math.pow(10, decimals).toString() + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error allowance lookup' + return reason + } + } + + // approve a spender to transfer tokens from a wallet address + async approveERC20 (wallet, spender, tokenAddress, amount, gasPrice = this.gasPrice, gasLimit) { + try { + // fixate gas limit to prevent overwriting + const approvalGasLimit = APPROVAL_GAS_LIMIT + // instantiate a contract and pass in wallet, which act on behalf of that signer + const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, wallet) + return await contract.approve( + spender, + amount, { + gasPrice: gasPrice * 1e9, + gasLimit: approvalGasLimit + } + ) + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error approval' + return reason + } + } + + // get current Gas + async getCurrentGasPrice () { + try { + this.provider.getGasPrice().then(function (gas) { + // gasPrice is a BigNumber; convert it to a decimal string + const gasPrice = gas.toString(); + return gasPrice + }) + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error gas lookup' + return reason + } + } + + async deposit (wallet, tokenAddress, amount, gasPrice = this.gasPrice, gasLimit = this.approvalGasLimit) { + // deposit ETH to a contract address + try { + const contract = new ethers.Contract(tokenAddress, abi.KovanWETHAbi, wallet) + return await contract.deposit( + { value: amount, + gasPrice: gasPrice * 1e9, + gasLimit: gasLimit + } + ) + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error deposit' + return reason + } + } + + // get ERC20 Token List + async getERC20TokenList () { + let tokenListSource + try { + if (this.network === 'kovan') { + tokenListSource = 'src/static/erc20_tokens_kovan.json' + this.erc20TokenList = JSON.parse(fs.readFileSync(tokenListSource)) + } else if (this.network === 'mainnet') { + tokenListSource = this.erc20TokenListURL + if (tokenListSource === undefined || tokenListSource === null) { + const errMessage = 'Token List source not found' + logger.error('ERC20 Token List Error', { message: errMessage}) + console.log('eth - Error: ', errMessage) + } + if (this.erc20TokenList === undefined || this.erc20TokenList === null || this.erc20TokenList === {}) { + const response = await axios.get(tokenListSource) + if (response.status === 200 && response.data) { + this.erc20TokenList = response.data + } + } + } else { + throw Error(`Invalid network ${this.network}`) + } + console.log('get ERC20 Token List', this.network, 'source', tokenListSource) + } catch (err) { + console.log(err); + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error ERC 20 Token List' + return reason + } + } + + getERC20TokenAddresses (tokenSymbol) { + const tokenContractAddress = this.erc20TokenList.tokens.filter(obj => { + return obj.symbol === tokenSymbol.toUpperCase() + }) + return tokenContractAddress[0] + } +} diff --git a/src/services/fees.js b/src/services/fees.js new file mode 100644 index 0000000..8fbf378 --- /dev/null +++ b/src/services/fees.js @@ -0,0 +1,52 @@ +import { logger } from './logger'; +import axios from 'axios' +import BigNumber from 'bignumber.js' + +const debug = require('debug')('router') +// constants +const ethGasStationHost = 'https://ethgasstation.info' +const globalConfig = require('../services/configuration_manager').configManagerInstance +const ethGasStationEnabled = globalConfig.getConfig("ENABLE_ETH_GAS_STATION") || false +const ethGasStationApiKey = globalConfig.getConfig("ETH_GAS_STATION_API_KEY") +const ethManualGasPrice = parseInt(globalConfig.getConfig("MANUAL_GAS_PRICE")) +const ethGasStationURL = ethGasStationHost + '/api/ethgasAPI.json?api-key=' + ethGasStationApiKey +const defaultRefreshInterval = 120 +const denom = BigNumber('1e+9') + +export default class Fees { + constructor () { + this.ethGasStationGasLevel = globalConfig.getConfig("ETH_GAS_STATION_GAS_LEVEL") + this.ethGasStationRefreshTime = (globalConfig.getConfig("ETH_GAS_STATION_REFRESH_TIME") || defaultRefreshInterval) * 1000 + this.getETHGasStationFee(this.ethGasStationGasLevel, 0) + } + + // get ETH Gas Station + async getETHGasStationFee (gasLevel = this.ethGasStationGasLevel, interval = defaultRefreshInterval) { + try { + if (ethGasStationEnabled === true || ethGasStationEnabled.toLowerCase() === 'true') { + const response = await axios.get(ethGasStationURL) + // divite by 10 to convert it to Gwei) + this.ethGasPrice = response.data[gasLevel] / 10 + console.log(`get ETHGasStation gas price (${gasLevel}): ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) + } else { + this.ethGasPrice = ethManualGasPrice + console.log(`get manual fixed gas price: ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) + } + } catch (err) { + console.log(err); + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error ETH gas fee lookup' + return reason + } + if (interval > 0) { // set to '0' for one-time retrieval + setTimeout(this.getETHGasStationFee.bind(this), this.ethGasStationRefreshTime); // update every x seconds + } + } + + // get gas cost + async getGasCost (gasPrice, gasLimit, inGwei = false) { + const cost = gasPrice * gasLimit + return inGwei ? cost : cost / denom + } +} diff --git a/src/services/logger.js b/src/services/logger.js new file mode 100644 index 0000000..e8601c9 --- /dev/null +++ b/src/services/logger.js @@ -0,0 +1,44 @@ +import { getLocalDate } from './utils' +const appRoot = require('app-root-path') +const winston = require('winston') +require('winston-daily-rotate-file'); +const globalConfig = require('../services/configuration_manager').configManagerInstance + +const logFormat = winston.format.combine( + winston.format.timestamp(), + winston.format.align(), + winston.format.printf( + info => { + const localDate = getLocalDate() + return `${localDate} | ${info.level} | ${info.message}` + } + ), +) + +const getLogPath = () => { + let logPath = globalConfig.getConfig("LOG_PATH") + if (typeof logPath === 'undefined' || logPath == null || logPath === '') { + logPath = [appRoot.path, 'logs'].join('/') + } + return logPath +} + +const config = { + file: { + level: 'info', + filename: `${getLogPath()}/logs_gateway_app.log.%DATE%`, + datePattern: 'YYYY-MM-DD', + handleExceptions: true, + handleRejections: true + } +} + +const allLogsFileTransport = new winston.transports.DailyRotateFile(config.file) + +const options = { + format: logFormat, + transports: [allLogsFileTransport], + exitOnError: false, +} + +export const logger = winston.createLogger(options) diff --git a/src/services/perpetual_finance.js b/src/services/perpetual_finance.js new file mode 100644 index 0000000..38b85c4 --- /dev/null +++ b/src/services/perpetual_finance.js @@ -0,0 +1,299 @@ +import { logger } from './logger'; + +const fetch = require('cross-fetch'); + +const Ethers = require('ethers') +const AmmArtifact = require("@perp/contract/build/contracts/Amm.json") +const ClearingHouseArtifact = require("@perp/contract/build/contracts/ClearingHouse.json") +const RootBridgeArtifact = require("@perp/contract/build/contracts/RootBridge.json") +const ClientBridgeArtifact = require("@perp/contract/build/contracts/ClientBridge.json") +const ClearingHouseViewerArtifact = require("@perp/contract/build/contracts/ClearingHouseViewer.json") +const TetherTokenArtifact = require("@perp/contract/build/contracts/TetherToken.json") +const globalConfig = require('../services/configuration_manager').configManagerInstance + +const GAS_LIMIT = 2123456; +const DEFAULT_DECIMALS = 18; +const CONTRACT_ADDRESSES = 'https://metadata.perp.exchange/'; +const XDAI_PROVIDER = globalConfig.getConfig("XDAI_PROVIDER") || 'https://dai.poa.network'; +const PNL_OPTION_SPOT_PRICE = 0; +const UPDATE_PERIOD = 60000; // stop updating prices after 30 secs from last request + + +export default class PerpetualFinance { + constructor (network = 'mainnet') { + this.providerUrl = XDAI_PROVIDER + this.network = network + this.provider = new Ethers.providers.JsonRpcProvider(this.providerUrl) + this.gasLimit = GAS_LIMIT + this.contractAddressesUrl = CONTRACT_ADDRESSES + this.amm = {} + this.priceCache = {} + this.cacheExpirary = {} + this.pairAmountCache = {} + + + switch (network) { + case 'mainnet': + this.contractAddressesUrl += 'production.json'; + break; + case 'kovan': + this.contractAddressesUrl += 'staging.json'; + break; + default: + const err = `Invalid network ${network}` + logger.error(err) + throw Error(err) + } + + this.loadedMetadata = this.load_metadata() + + } + + async load_metadata() { + try{ + const metadata = await fetch(this.contractAddressesUrl).then(res => res.json()) + const layer2 = Object.keys(metadata.layers.layer2.contracts) + + for (var key of layer2){ + if (metadata.layers.layer2.contracts[key].name === "Amm") { + this.amm[key] = metadata.layers.layer2.contracts[key].address; + } else{ + this[key] = metadata.layers.layer2.contracts[key].address; + } + } + + this.layer2AmbAddr = metadata.layers.layer2.externalContracts.ambBridgeOnXDai + this.xUsdcAddr = metadata.layers.layer2.externalContracts.usdc + this.loadedMetadata = true + return true + } catch(err) { + return false + } + + } + + async update_price_loop() { + if (Object.keys(this.cacheExpirary).length > 0) { + for (let pair in this.cacheExpirary){ + if (this.cacheExpirary[pair] <= Date.now()) { + delete this.cacheExpirary[pair]; + delete this.priceCache[pair]; + } + } + + for (let pair in this.cacheExpirary){ + let amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider) + await Promise.allSettled([amm.getInputPrice(0, {d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) }), + amm.getOutputPrice(0, {d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) })]) + .then(values => {if (!this.priceCache.hasOwnProperty(pair)) { this.priceCache[pair] = [] }; + this.priceCache[pair][0] = this.pairAmountCache[pair] / Ethers.utils.formatUnits(values[0].value.d); + this.priceCache[pair][1] = Ethers.utils.formatUnits(values[1].value.d) / this.pairAmountCache[pair];})} + + } + setTimeout(this.update_price_loop.bind(this), 10000); // update every 10 seconds + } + + // get XDai balance + async getXdaiBalance (wallet) { + try { + const xDaiBalance = await wallet.getBalance() + return Ethers.utils.formatEther(xDaiBalance) + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error xDai balance lookup' + return reason + } + } + + // get XDai USDC balance + async getUSDCBalance (wallet) { + try { + const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet) + let layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address) + const layer2UsdcDecimals = await layer2Usdc.decimals() + return Ethers.utils.formatUnits(layer2UsdcBalance, layer2UsdcDecimals) + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error balance lookup' + return reason + } + } + + // get allowance + async getAllowance (wallet) { + // instantiate a contract and pass in provider for read-only access + const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet) + + try { + const allowanceForClearingHouse = await layer2Usdc.allowance( + wallet.address, + this.ClearingHouse + ) + + return Ethers.utils.formatUnits(allowanceForClearingHouse, DEFAULT_DECIMALS) + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error allowance lookup' + return reason + } + } + + // approve + async approve (wallet, amount) { + try { + // instantiate a contract and pass in wallet + const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet) + const tx = await layer2Usdc.approve(this.ClearingHouse, Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS)) + // TO-DO: We may want to supply custom gasLimit value above + return tx.hash + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error approval' + return reason + } + } + + //open Position + async openPosition(side, margin, levrg, pair, minBaseAmount, wallet) { + try { + const quoteAssetAmount = { d: Ethers.utils.parseUnits(margin, DEFAULT_DECIMALS) } + const leverage = { d: Ethers.utils.parseUnits(levrg, DEFAULT_DECIMALS) } + const minBaseAssetAmount = { d: Ethers.utils.parseUnits(minBaseAmount, DEFAULT_DECIMALS) } + const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet) + const tx = await clearingHouse.openPosition( + this.amm[pair], + side, + quoteAssetAmount, + leverage, + minBaseAssetAmount, + { gasLimit: this.gasLimit } + ) + return tx + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error opening position' + return reason + } + } + + //close Position + async closePosition(wallet, pair, minimalQuote) { + try { + const minimalQuoteAsset = { d: Ethers.utils.parseUnits(minimalQuote, DEFAULT_DECIMALS) } + const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet) + const tx = await clearingHouse.closePosition(this.amm[pair], minimalQuoteAsset, { gasLimit: this.gasLimit } ) + return tx + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error closing position' + return reason + } + } + + //get active position + async getPosition(wallet, pair) { + try { + const positionValues = {} + const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet) + let premIndex = 0 + await Promise.allSettled([clearingHouse.getPosition(this.amm[pair], + wallet.address), + clearingHouse.getLatestCumulativePremiumFraction(this.amm[pair]), + clearingHouse.getPositionNotionalAndUnrealizedPnl(this.amm[pair], + wallet.address, + Ethers.BigNumber.from(PNL_OPTION_SPOT_PRICE))]) + .then(values => {positionValues.openNotional = Ethers.utils.formatUnits(values[0].value.openNotional.d, DEFAULT_DECIMALS); + positionValues.size = Ethers.utils.formatUnits(values[0].value.size.d, DEFAULT_DECIMALS); + positionValues.margin = Ethers.utils.formatUnits(values[0].value.margin.d, DEFAULT_DECIMALS); + positionValues.cumulativePremiumFraction = Ethers.utils.formatUnits(values[0].value.lastUpdatedCumulativePremiumFraction.d, DEFAULT_DECIMALS); + premIndex = Ethers.utils.formatUnits(values[1].value.d, DEFAULT_DECIMALS); + positionValues.pnl = Ethers.utils.formatUnits(values[2].value.unrealizedPnl.d, DEFAULT_DECIMALS); + positionValues.positionNotional = Ethers.utils.formatUnits(values[2].value.positionNotional.d, DEFAULT_DECIMALS);}) + + positionValues.entryPrice = Math.abs(positionValues.openNotional / positionValues.size) + positionValues.fundingPayment = (premIndex - positionValues.cumulativePremiumFraction) * positionValues.size // * -1 + return positionValues + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error getting active position' + return reason + } + } + + //get active margin + async getActiveMargin(wallet) { + try { + const clearingHouseViewer = new Ethers.Contract(this.ClearingHouseViewer, ClearingHouseViewerArtifact.abi, wallet) + const activeMargin = await clearingHouseViewer.getPersonalBalanceWithFundingPayment( + this.xUsdcAddr, + wallet.address) + return activeMargin / 1e18.toString() + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error getting active position' + return reason + } + } + + // get Price + async getPrice(side, amount, pair) { + try { + let price + this.cacheExpirary[pair] = Date.now() + UPDATE_PERIOD + this.pairAmountCache[pair] = amount + if (!this.priceCache.hasOwnProperty(pair)){ + const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider) + if (side === "buy") { + price = await amm.getInputPrice(0, {d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }) + price = amount / Ethers.utils.formatUnits(price.d) + } else { + price = await amm.getOutputPrice(0, {d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }) + price = Ethers.utils.formatUnits(price.d) / amount + } + } else { + if (side === "buy") { + price = this.priceCache[pair][0] + } else { price = this.priceCache[pair][1] } + } + return price + } catch (err) { + console.log(err) + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error getting Price' + return reason + } + } + + // get getFundingRate + async getFundingRate(pair) { + try { + let funding = {} + const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider) + await Promise.allSettled([amm.getUnderlyingTwapPrice(3600), + amm.getTwapPrice(3600), + amm.nextFundingTime()]) + .then(values => {funding.indexPrice = parseFloat(Ethers.utils.formatUnits(values[0].value.d)); + funding.markPrice = parseFloat(Ethers.utils.formatUnits(values[1].value.d)); + funding.nextFundingTime = parseInt(values[2].value.toString());}) + + funding.rate = ((funding.markPrice - funding.indexPrice) / 24) / funding.indexPrice + return funding + } catch (err) { + console.log(err) + logger.error(err)() + let reason + err.reason ? reason = err.reason : reason = 'error getting fee' + return reason + } + } + +} diff --git a/src/services/terra.js b/src/services/terra.js new file mode 100644 index 0000000..de58d66 --- /dev/null +++ b/src/services/terra.js @@ -0,0 +1,316 @@ +import { logger } from './logger'; +import { LCDClient, Coin, MsgSwap, StdTx, StdFee, Dec, MnemonicKey, isTxError, Coins } from '@terra-money/terra.js' +import BigNumber from 'bignumber.js' +import { getHummingbotMemo } from './utils'; + +const debug = require('debug')('router') +const globalConfig = require('../services/configuration_manager').configManagerInstance + +// constants +const TERRA_TOKENS = { + uluna: { symbol: 'LUNA' }, + uusd: { symbol: 'UST' }, + ukrw: { symbol: 'KRT' }, + usdr: { symbol: 'SDT' }, + umnt: { symbol: 'MNT' }, +} +const DENOM_UNIT = BigNumber('1e+6') +const TOBIN_TAX = 0.0025 // a Tobin Tax (set at 0.25%) for spot-converting Terra<>Terra swaps +const MIN_SPREAD = 0.02 // a minimum spread (set at 2%) for Terra<>Luna swaps +const GAS_PRICE = { uluna: 0.16 } +const GAS_ADJUSTMENT = 1.4 + +export default class Terra { + constructor () { + this.lcdUrl = globalConfig.getConfig("TERRA_LCD_URL"); + this.network = globalConfig.getConfig("TERRA_CHAIN"); + this.tokens = TERRA_TOKENS + this.denomUnitMultiplier = DENOM_UNIT + this.tobinTax = TOBIN_TAX + this.minSpread = MIN_SPREAD + this.memo = getHummingbotMemo() + + try { + this.lcd = this.connect() + + this.lcd.market.parameters().catch(() => { + throw new Error('Connection error') + }) + // set gas & fee + this.lcd.config.gasAdjustment = GAS_ADJUSTMENT + this.lcd.config.gasPrices = GAS_PRICE + } catch (err) { + logger.error(err) + throw Error(`Connection failed: ${this.network}`) + } + } + + // connect Terra LCD + connect () { + try { + const lcd = new LCDClient({ + URL: this.lcdUrl, + chainID: this.network, + }) + lcd.config.gasAdjustment = GAS_ADJUSTMENT + lcd.config.gasPrices = GAS_PRICE + return lcd + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error Terra LCD connect' + return reason + } + } + + // get Token Denom + getTokenDenom (symbol) { + try { + let denom + Object.keys(TERRA_TOKENS).forEach((item) => { + if (TERRA_TOKENS[item].symbol === symbol) { + denom = item + } + }) + return denom + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error Terra Denom lookup' + return reason + } + } + + // get Token Symbol + getTokenSymbol (denom) { + try { + const symbol = TERRA_TOKENS[denom].symbol + return symbol + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error Terra Denom lookup' + return reason + } + } + + getTxAttributes (attributes) { + let attrib = {} + attributes.forEach((item) => { + attrib[item.key] = item.value + }) + return attrib + } + + async getEstimateFee (tx) { + try { + const fee = await this.lcd.tx.estimateFee(tx) + return fee + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error Terra estimate fee lookup' + return reason + } + } + + async getExchangeRate (denom) { + try { + const exchangeRates = await this.lcd.oracle.exchangeRates() + return exchangeRates.get(denom) + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup' + return reason + } + } + + async getTxFee () { + try { + const lunaFee = GAS_PRICE.uluna * GAS_ADJUSTMENT + let feeList = { uluna: lunaFee } + await this.lcd.oracle.exchangeRates().then(rates => { + Object.keys(rates._coins).forEach(key => { + feeList[key] = rates._coins[key].amount * lunaFee + }) + }) + debug('lunaFee', lunaFee, feeList) + + return feeList + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup' + return reason + } + } + + // get Terra Swap Rate + async getSwapRate (baseToken, quoteToken, amount, tradeType) { + try { + let exchangeRate, offerCoin, offerDenom, swapDenom, cost, costAmount, offer + let swaps = {} + + if (tradeType.toLowerCase() === 'sell') { + // sell base + offerDenom = this.getTokenDenom(baseToken) + swapDenom = this.getTokenDenom(quoteToken) + + offerCoin = new Coin(offerDenom, amount * DENOM_UNIT); + await this.lcd.market.swapRate(offerCoin, swapDenom).then(swapCoin => { + offer = { amount: amount } + exchangeRate = { + amount: (swapCoin.amount / DENOM_UNIT) / amount, + token: quoteToken + } + costAmount = amount * exchangeRate.amount + cost = { + amount: costAmount, + token: quoteToken + } + }) + } else { + // buy base + offerDenom = this.getTokenDenom(quoteToken) + swapDenom = this.getTokenDenom(baseToken) + + offerCoin = new Coin(offerDenom, 1 * DENOM_UNIT); + await this.lcd.market.swapRate(offerCoin, swapDenom).then(swapCoin => { + exchangeRate = { + amount: (amount / parseInt(swapCoin.amount) * DENOM_UNIT) / amount, // adjusted amount + token: quoteToken + } + costAmount = amount * exchangeRate.amount + cost = { + amount: costAmount, + token: quoteToken + } + offer = { amount: cost.amount } + }) + } + + let txFee + await this.getTxFee().then(fee => { + // fee in quote + txFee = { amount: parseFloat(fee[this.getTokenDenom(quoteToken)]), token: quoteToken } + }) + + swaps.offer = offer + swaps.price = exchangeRate + swaps.cost = cost + swaps.txFee = txFee + debug('swaps', swaps) + return swaps + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = 'error swap rate lookup' + return reason + } + } + + // Swap tokens + async swapTokens (baseToken, quoteToken, amount, tradeType, gasPrice, gasAdjustment, secret) { + let swapResult + try { + // connect to lcd + const lcd = this.connect() + + const mk = new MnemonicKey({ + mnemonic: secret, + }); + let wallet + try { + wallet = lcd.wallet(mk); + } catch (err) { + logger.error(err) + throw Error('Wallet access error') + } + + const address = wallet.key.accAddress + + // get the current swap rate + const baseDenom = this.getTokenDenom(baseToken) + const quoteDenom = this.getTokenDenom(quoteToken) + + let offerDenom, swapDenom + let swaps, txAttributes + let tokenSwap = {} + + if (tradeType.toLowerCase() === 'sell') { + offerDenom = baseDenom + swapDenom = quoteDenom + } else { + offerDenom = quoteDenom + swapDenom = baseDenom + } + + await this.getSwapRate(baseToken, quoteToken, amount, tradeType, secret).then((rate) => { + swaps = rate + }) + + const offerAmount = parseInt((swaps.offer.amount) * DENOM_UNIT) + const offerCoin = new Coin(offerDenom, offerAmount) + + // Create and Sign Transaction + const msgSwap = new MsgSwap(address, offerCoin, swapDenom); + + let txOptions + if (gasPrice !== null && gasPrice !== null) { // ignore gasAdjustment when gasPrice is not set + txOptions = { + msgs: [msgSwap], + gasPrices: { uluna: parseFloat(gasPrice) }, + gasAdjustment: gasAdjustment, + memo: this.memo + } + } else { + txOptions = { + msgs: [msgSwap], + memo: this.memo + } + } + + await wallet.createAndSignTx(txOptions).then(tx => lcd.tx.broadcast(tx)).then((txResult) => { + swapResult = txResult + + const swapSuccess = !isTxError(txResult) + if (swapSuccess) { + tokenSwap.txSuccess = swapSuccess + } else { + tokenSwap.txSuccess = !swapSuccess + throw new Error(`encountered an error while running the transaction: ${txResult.code} ${txResult.codespace}`); + } + const txHash = txResult.txhash + const events = JSON.parse(txResult.raw_log)[0].events + const swap = events.find(obj => { + return obj.type === 'swap' + }) + txAttributes = this.getTxAttributes(swap.attributes) + const offer = Coin.fromString(txAttributes.offer) + const ask = Coin.fromString(txAttributes.swap_coin) + const fee = Coin.fromString(txAttributes.swap_fee) + + tokenSwap.expectedIn = { + amount: parseFloat(offer.amount) / DENOM_UNIT, + token: TERRA_TOKENS[offer.denom].symbol + } + tokenSwap.expectedOut = { + amount: parseFloat(ask.amount) / DENOM_UNIT, + token: TERRA_TOKENS[ask.denom].symbol + } + tokenSwap.fee = { + amount: parseFloat(fee.amount) / DENOM_UNIT, + token: TERRA_TOKENS[fee.denom].symbol + } + tokenSwap.txHash = txHash + }) + return tokenSwap + } catch (err) { + logger.error(err) + let reason + err.reason ? reason = err.reason : reason = swapResult + return { txSuccess: false, message: reason } + } + } +} diff --git a/src/services/uniswap.js b/src/services/uniswap.js new file mode 100644 index 0000000..3f57d8b --- /dev/null +++ b/src/services/uniswap.js @@ -0,0 +1,218 @@ +import { logger } from './logger'; + +const debug = require('debug')('router') +const math = require('mathjs') +const uni = require('@uniswap/sdk') +const ethers = require('ethers') +const proxyArtifact = require('../static/uniswap_v2_router_abi.json') +const routeTokens = require('../static/uniswap_route_tokens.json') +const globalConfig = require('../services/configuration_manager').configManagerInstance + +// constants +const ROUTER = globalConfig.getConfig("UNISWAP_ROUTER") +const GAS_LIMIT = globalConfig.getConfig("UNISWAP_GAS_LIMIT") || 150688; +const TTL = globalConfig.getConfig("UNISWAP_TTL") || 300; +const UPDATE_PERIOD = globalConfig.getConfig("UNISWAP_UPDATE_PERIOD") || 300000; // stop updating pair after 5 minutes from last request + +export default class Uniswap { + constructor (network = 'mainnet') { + this.providerUrl = globalConfig.getConfig("ETHEREUM_RPC_URL") + this.network = globalConfig.getConfig("ETHEREUM_CHAIN") + this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) + this.router = ROUTER; + this.slippage = math.fraction(globalConfig.getConfig("UNISWAP_ALLOWED_SLIPPAGE")) + this.allowedSlippage = new uni.Percent(this.slippage.n, (this.slippage.d * 100)) + this.pairsCacheTime = globalConfig.getConfig("UNISWAP_PAIRS_CACHE_TIME") + this.gasLimit = GAS_LIMIT + this.expireTokenPairUpdate = UPDATE_PERIOD + this.zeroReserveCheckInterval = globalConfig.getConfig("UNISWAP_NO_RESERVE_CHECK_INTERVAL") + this.zeroReservePairs = {} // No reserve pairs + this.tokenList = {} + this.pairs = [] + this.tokenSwapList = {} + this.cachedRoutes = {} + + switch (network) { + case 'mainnet': + this.chainID = uni.ChainId.MAINNET; + break; + case 'kovan': + this.chainID = uni.ChainId.KOVAN; + break; + default: + const err = `Invalid network ${network}` + logger.error(err) + throw Error(err) + } + } + + async fetch_route(tIn, tOut){ + var route, pair, pairOne, pairTwo + + try { + pair = await uni.Fetcher.fetchPairData(tIn, tOut); + route = new uni.Route([pair], tIn, tOut); + } + catch(err) { + logger.error(err); + } + return route; + } + + + generate_tokens(){ + for (let token of routeTokens[this.network]){ + this.tokenList[token["address"]] = new uni.Token(this.chainID, token["address"], token["decimals"], token["symbol"], token["name"]); + } + } + + async extend_update_pairs(tokens=[]){ + for (let token of tokens){ + if (!this.tokenList.hasOwnProperty(token)){ + this.tokenList[token] = await uni.Fetcher.fetchTokenData(this.chainID, token); + } + this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate; + } + } + + async update_pairs(){ + // Remove banned pairs after ban period + if (Object.keys(this.zeroReservePairs).length > 0){ + for (let pair in this.zeroReservePairs){ + if (this.zeroReservePairs[pair] <= Date.now()) { + delete this.zeroReservePairs[pair]; + // delete this.tokenList[token]; + } + } + } + // Generate all possible pair combinations of tokens + // This is done by generating an upper triangular matrix or right triangular matrix + if (Object.keys(this.tokenSwapList).length > 0){ + for (let token in this.tokenSwapList){ + if (this.tokenSwapList[token] <= Date.now()) { + delete this.tokenSwapList[token]; + // delete this.tokenList[token]; + } + } + + let tokens = Object.keys(this.tokenList); + var firstToken, secondToken, position; + let length = tokens.length; + let pairs = []; + let pairAddressRequests = []; + let pairAddressResponses = []; + for (firstToken = 0; firstToken < length; firstToken++){ + for (secondToken = firstToken + 1; secondToken < length; secondToken++){ + try{ + let pairString = this.tokenList[tokens[firstToken]].address + '-' + this.tokenList[tokens[secondToken]].address; + if (!this.zeroReservePairs.hasOwnProperty(pairString)){ + pairs.push(pairString); + pairAddressRequests.push(uni.Fetcher.fetchPairData(this.tokenList[tokens[firstToken]], this.tokenList[tokens[secondToken]])); + } + } + catch(err) { + logger.error(err); + } + } + } + + await Promise.allSettled(pairAddressRequests).then(values => { for (position = 0; position < pairAddressRequests.length; position++) { + if (values[position].status === "fulfilled"){pairAddressResponses.push(values[position].value)} + else {this.zeroReservePairs[pairs[position]] = Date.now() + this.zeroReserveCheckInterval;}}}) + this.pairs = pairAddressResponses; + } + setTimeout(this.update_pairs.bind(this), 1000); + } + + async priceSwapIn (tokenIn, tokenOut, tokenInAmount) { + await this.extend_update_pairs([tokenIn, tokenOut]); + const tIn = this.tokenList[tokenIn]; + const tOut = this.tokenList[tokenOut]; + const tokenAmountIn = new uni.TokenAmount(tIn, ethers.utils.parseUnits(tokenInAmount, tIn.decimals)); + if (this.pairs.length === 0){ + const route = await this.fetch_route(tIn, tOut); + const trade = uni.Trade.exactIn(route, tokenAmountIn); + if ( trade !== undefined ){ + const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; + return { trade, expectedAmount } + } + return "Can't find route to swap, kindly update " + } + const trade = uni.Trade.bestTradeExactIn(this.pairs, tokenAmountIn, this.tokenList[tokenOut], { maxHops: 5 })[0]; + if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} + else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} + const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); + return { trade, expectedAmount } + } + + async priceSwapOut (tokenIn, tokenOut, tokenOutAmount) { + await this.extend_update_pairs([tokenIn, tokenOut]); + const tOut = this.tokenList[tokenOut]; + const tIn = this.tokenList[tokenIn]; + const tokenAmountOut = new uni.TokenAmount(tOut, ethers.utils.parseUnits(tokenOutAmount, tOut.decimals)); + if (this.pairs.length === 0){ + const route = await this.fetch_route(tIn, tOut); + const trade = uni.Trade.exactOut(route, tokenAmountOut); + if ( trade !== undefined ){ + const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; + return { trade, expectedAmount } + } + return + } + const trade = uni.Trade.bestTradeExactOut(this.pairs, this.tokenList[tokenIn], tokenAmountOut, { maxHops: 5 })[0]; + if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} + else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} + const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); + return { trade, expectedAmount } + } + + async swapExactIn (wallet, trade, tokenAddress, gasPrice) { + const result = uni.Router.swapCallParameters( + trade, + { + ttl: TTL, + recipient: wallet.address, + allowedSlippage: this.allowedSlippage + } + ) + + const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) + const tx = await contract.[result.methodName]( + ...result.args, + { + gasPrice: gasPrice * 1e9, + gasLimit: GAS_LIMIT, + value: result.value + } + ) + + debug(`Tx Hash: ${tx.hash}`); + return tx + } + + async swapExactOut (wallet, trade, tokenAddress, gasPrice) { + const result = uni.Router.swapCallParameters( + trade, + { + ttl: TTL, + recipient: wallet.address, + allowedSlippage: this.allowedSlippage + } + ) + + const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) + const tx = await contract.[result.methodName]( + ...result.args, + { + gasPrice: gasPrice * 1e9, + gasLimit: GAS_LIMIT, + value: result.value + } + ) + + debug(`Tx Hash: ${tx.hash}`); + return tx + } +} diff --git a/src/services/utils.js b/src/services/utils.js new file mode 100644 index 0000000..ebe2355 --- /dev/null +++ b/src/services/utils.js @@ -0,0 +1,103 @@ +/* + Hummingbot Utils +*/ +const config = require('./configuration_manager') +const lodash = require('lodash') +const moment = require('moment') +const globalConfig = require('../services/configuration_manager').configManagerInstance + + +export const statusMessages = { + ssl_cert_required: 'SSL Certificate required', + ssl_cert_invalid: 'Invalid SSL Certificate', + operation_error: 'Operation Error', + no_pool_available: 'No Pool Available', + invalid_token_symbol: 'Invalid Token Symbol', + insufficient_reserves: 'Insufficient Liquidity Reserves', + page_not_found: 'Page not found. Invalid path', +} + +export const latency = (startTime, endTime) => parseFloat((endTime - startTime) / 1000) + +export const isValidParams = (params) => { + const values = Object.values(params) + for (let i = 0; i < values.length; i++) { // DO NOT use forEach, it returns callback without breaking the loop + if (typeof values[i] === 'undefined') { + throw new Error('Invalid input params') + } + } + return true +} + +export const isValidData = (data, format) => { + if (typeof data !== 'undefined' && Object.keys(data).length !== 0 && lodash.isEqual(Object.keys(data).sort(), format.sort())) { + return true + } + return false +} + +export const getParamData = (data, format = null) => { + const dataObject = {} + if (format !== null) { + if (isValidData(data, format)) { + format.forEach((key, index) => { + dataObject[key] = data[key] + }) + } + } else { + Object.keys(data).forEach((key, index) => { + dataObject[key] = data[key] + }) + } + return dataObject +} + +export const splitParamData = (param, separator = ',') => { + const dataArray = param.split(separator) + return dataArray +} + +export const getSymbols = (tradingPair) => { + const symbols = tradingPair.split('-') + const baseQuotePair = { + base: symbols[0].toUpperCase(), + quote: symbols[1].toUpperCase() + } + return baseQuotePair +} + +export const reportConnectionError = (res, error) => { + res.json({ + error: error.errno, + code: error.code, + }) +} + +export const strToDecimal = (str) => parseInt(str) / 100; + +export const getHummingbotMemo = () => { + const prefix = 'hbot' + const clientId = globalConfig.getConfig("HUMMINGBOT_INSTANCE_ID") + if ((typeof clientId !== 'undefined' && clientId != null) && clientId !== '') { + return [prefix, clientId].join('-') + } + return prefix +} + +export const loadConfig = () => { + return config.configManagerInstance.readAllConfigs() +} + +export const updateConfig = (data) => { + globalConfig.updateConfig(data) + return true +} + +export const getLocalDate = () => { + const gmtOffset = globalConfig.getConfig("GMT_OFFSET") + let newDate = moment().format('YYYY-MM-DD hh:mm:ss').trim() + if (typeof gmtOffset !== 'undefined' && gmtOffset !== null && gmtOffset !== '') { + newDate = moment().utcOffset(gmtOffset, false).format('YYYY-MM-DD hh:mm:ss').trim() + } + return newDate +} diff --git a/src/static/ExchangeProxy.json b/src/static/ExchangeProxy.json new file mode 100644 index 0000000..0e5d20b --- /dev/null +++ b/src/static/ExchangeProxy.json @@ -0,0 +1,624 @@ +{ + "contractName": "ExchangeProxy", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_weth", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limitReturnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPrice", + "type": "uint256" + } + ], + "internalType": "struct ExchangeProxy.Swap[]", + "name": "swaps", + "type": "tuple[]" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minTotalAmountOut", + "type": "uint256" + } + ], + "name": "batchSwapExactIn", + "outputs": [ + { + "internalType": "uint256", + "name": "totalAmountOut", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limitReturnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPrice", + "type": "uint256" + } + ], + "internalType": "struct ExchangeProxy.Swap[]", + "name": "swaps", + "type": "tuple[]" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxTotalAmountIn", + "type": "uint256" + } + ], + "name": "batchSwapExactOut", + "outputs": [ + { + "internalType": "uint256", + "name": "totalAmountIn", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limitReturnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPrice", + "type": "uint256" + } + ], + "internalType": "struct ExchangeProxy.Swap[][]", + "name": "swapSequences", + "type": "tuple[][]" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minTotalAmountOut", + "type": "uint256" + } + ], + "name": "multihopBatchSwapExactIn", + "outputs": [ + { + "internalType": "uint256", + "name": "totalAmountOut", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limitReturnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPrice", + "type": "uint256" + } + ], + "internalType": "struct ExchangeProxy.Swap[][]", + "name": "swapSequences", + "type": "tuple[][]" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxTotalAmountIn", + "type": "uint256" + } + ], + "name": "multihopBatchSwapExactOut", + "outputs": [ + { + "internalType": "uint256", + "name": "totalAmountIn", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_registry", + "type": "address" + } + ], + "name": "setRegistry", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract TokenInterface", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minTotalAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nPools", + "type": "uint256" + } + ], + "name": "smartSwapExactIn", + "outputs": [ + { + "internalType": "uint256", + "name": "totalAmountOut", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract TokenInterface", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "contract TokenInterface", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxTotalAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nPools", + "type": "uint256" + } + ], + "name": "smartSwapExactOut", + "outputs": [ + { + "internalType": "uint256", + "name": "totalAmountIn", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nPools", + "type": "uint256" + } + ], + "name": "viewSplitExactIn", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limitReturnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPrice", + "type": "uint256" + } + ], + "internalType": "struct ExchangeProxy.Swap[]", + "name": "swaps", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "totalOutput", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nPools", + "type": "uint256" + } + ], + "name": "viewSplitExactOut", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "swapAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limitReturnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPrice", + "type": "uint256" + } + ], + "internalType": "struct ExchangeProxy.Swap[]", + "name": "swaps", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "totalOutput", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b506040516200358a3803806200358a8339810160408190526200003491620000d0565b6000620000496001600160e01b03620000b916565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b0319166001600160a01b039290921691909117905562000125565b3390565b8051620000ca816200010b565b92915050565b600060208284031215620000e357600080fd5b6000620000f18484620000bd565b949350505050565b60006001600160a01b038216620000ca565b6200011681620000f9565b81146200012257600080fd5b50565b61345580620001356000396000f3fe6080604052600436106100c25760003560e01c80638743ad581161007f578063a91ee0dc11610059578063a91ee0dc146101cd578063b40f39ee146101ed578063e2b3974614610200578063f2fde38b14610213576100c2565b80638743ad58146101765780638da5cb5b146101895780638f32d59b146101ab576100c2565b806321b0eb85146100c45780632db58134146100ed578063368bb1fc146101005780634b0f93fb1461012e578063715018a61461014e57806386b2ecc414610163575b005b6100d76100d2366004612d41565b610233565b6040516100e491906132b5565b60405180910390f35b6100d76100fb366004612caf565b6102b4565b34801561010c57600080fd5b5061012061011b366004612b32565b61059a565b6040516100e49291906131f6565b34801561013a57600080fd5b50610120610149366004612b32565b610947565b34801561015a57600080fd5b506100c2610c37565b6100d7610171366004612bc8565b610ca5565b6100d7610184366004612ce8565b611632565b34801561019557600080fd5b5061019e611908565b6040516100e491906130ec565b3480156101b757600080fd5b506101c0611917565b6040516100e49190613216565b3480156101d957600080fd5b506100c26101e8366004612b14565b61193b565b6100d76101fb366004612d41565b611981565b6100d761020e366004612c23565b6119f6565b34801561021f57600080fd5b506100c261022e366004612b14565b611cd2565b6000606061024087611d02565b156102655760015461025d906001600160a01b0316878786610947565b50905061029c565b61026e86611d02565b1561028c5760015461025d9088906001600160a01b03168786610947565b61029887878786610947565b5090505b6102a98188888888611632565b979650505050505050565b60006102c08483611d28565b5060005b8551811015610547576102d56127e4565b8682815181106102e157fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e906103299030908690600401613108565b60206040518083038186803b15801561034157600080fd5b505afa158015610355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103799190810190612d87565b111561040357825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b3916103af9190600090600401613181565b602060405180830381600087803b1580156103c957600080fd5b505af11580156103dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104019190810190612d23565b505b8251608084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b3926104349260040161319c565b602060405180830381600087803b15801561044e57600080fd5b505af1158015610462573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104869190810190612d23565b5060208301516080840151604080860151606087015160a08801519251631f17a7a960e21b81526000956001600160a01b03881695637c5e9ea4956104d195929491936004016131aa565b6040805180830381600087803b1580156104ea57600080fd5b505af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105229190810190612da5565b509050610535818763ffffffff611e4a16565b955050600190930192506102c4915050565b50818111156105715760405162461bcd60e51b815260040161056890613265565b60405180910390fd5b6105838361057e85611e76565b611f39565b506105918461057e86611e76565b50949350505050565b60025460405163bfdbfc4360e01b815260609160009183916001600160a01b03169063bfdbfc43906105d4908a908a908990600401613166565b60006040518083038186803b1580156105ec57600080fd5b505afa158015610600573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106289190810190612b93565b90506060815160405190808252806020026020018201604052801561066757816020015b610654612835565b81526020019060019003908161064c5790505b5090506000805b83518110156106e0576106958a8a86848151811061068857fe5b6020026020010151612068565b8382815181106106a157fe5b60200260200101819052506106d68382815181106106bb57fe5b602002602001015160c0015183611e4a90919063ffffffff16565b915060010161066e565b506060825160405190808252806020026020018201604052801561070e578160200160208202803883390190505b5090506000805b84518110156107a0576107588461074c87848151811061073157fe5b602002602001015160c001518d61234890919063ffffffff16565b9063ffffffff61238216565b83828151811061076457fe5b60200260200101818152505061079683828151811061077f57fe5b602002602001015183611e4a90919063ffffffff16565b9150600101610715565b50888110156107fd576107df6107bc8a8363ffffffff6123c416565b836000815181106107c957fe5b6020026020010151611e4a90919063ffffffff16565b826000815181106107ec57fe5b60200260200101818152505061084d565b610833610810828b63ffffffff6123c416565b8360008151811061081d57fe5b60200260200101516123c490919063ffffffff16565b8260008151811061084057fe5b6020026020010181815250505b835160405190808252806020026020018201604052801561088857816020015b6108756127e4565b81526020019060019003908161086d5790505b50965060005b845181101561092c576040518060c001604052808683815181106108ae57fe5b6020026020010151600001516001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b031681526020018483815181106108f257fe5b60200260200101518152602001600019815260200160001981525088828151811061091957fe5b602090810291909101015260010161088e565b506109378285612406565b9550505050505094509492505050565b60025460405163bfdbfc4360e01b815260609160009183916001600160a01b03169063bfdbfc4390610981908a908a908990600401613166565b60006040518083038186803b15801561099957600080fd5b505afa1580156109ad573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109d59190810190612b93565b905060608151604051908082528060200260200182016040528015610a1457816020015b610a01612835565b8152602001906001900390816109f95790505b5090506000805b8351811015610a6557610a358a8a86848151811061068857fe5b838281518110610a4157fe5b6020026020010181905250610a5b8382815181106106bb57fe5b9150600101610a1b565b5060608251604051908082528060200260200182016040528015610a93578160200160208202803883390190505b5090506000805b8451811015610ae757610ab68461074c87848151811061073157fe5b838281518110610ac257fe5b602002602001018181525050610add83828151811061077f57fe5b9150600101610a9a565b5088811015610b2157610b036107bc8a8363ffffffff6123c416565b82600081518110610b1057fe5b602002602001018181525050610b4e565b610b34610810828b63ffffffff6123c416565b82600081518110610b4157fe5b6020026020010181815250505b8351604051908082528060200260200182016040528015610b8957816020015b610b766127e4565b815260200190600190039081610b6e5790505b50965060005b8451811015610c2c576040518060c00160405280868381518110610baf57fe5b6020026020010151600001516001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b03168152602001848381518110610bf357fe5b6020026020010151815260200160008152602001600019815250888281518110610c1957fe5b6020908102919091010152600101610b8f565b50610937828561255c565b610c3f611917565b610c5b5760405162461bcd60e51b815260040161056890613285565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000610cb18483611d28565b5060005b8551811015610547576000868281518110610ccc57fe5b60200260200101515160011415610f5057610ce56127e4565b878381518110610cf157fe5b6020026020010151600081518110610d0557fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e90610d4d9030908690600401613108565b60206040518083038186803b158015610d6557600080fd5b505afa158015610d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d9d9190810190612d87565b1115610e2757825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b391610dd39190600090600401613181565b602060405180830381600087803b158015610ded57600080fd5b505af1158015610e01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e259190810190612d23565b505b8251608084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b392610e589260040161319c565b602060405180830381600087803b158015610e7257600080fd5b505af1158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610eaa9190810190612d23565b50806001600160a01b0316637c5e9ea484602001518560800151866040015187606001518860a001516040518663ffffffff1660e01b8152600401610ef39594939291906131aa565b6040805180830381600087803b158015610f0c57600080fd5b505af1158015610f20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f449190810190612da5565b50935061161792505050565b6000610f5a6127e4565b888481518110610f6657fe5b6020026020010151600181518110610f7a57fe5b60209081029190910181015180519181015160405163f8b2cb4f60e01b81529193506001600160a01b0383169163f8d6aed491839163f8b2cb4f91610fc1916004016130ec565b60206040518083038186803b158015610fd957600080fd5b505afa158015610fed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110119190810190612d87565b6020850151604051634a46c67360e11b81526001600160a01b0386169163948d8ce69161104191906004016130ec565b60206040518083038186803b15801561105957600080fd5b505afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110919190810190612d87565b604080870151905163f8b2cb4f60e01b81526001600160a01b0387169163f8b2cb4f916110c191906004016130ec565b60206040518083038186803b1580156110d957600080fd5b505afa1580156110ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111119190810190612d87565b6040808801519051634a46c67360e11b81526001600160a01b0388169163948d8ce69161114191906004016130ec565b60206040518083038186803b15801561115957600080fd5b505afa15801561116d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111919190810190612d87565b8760600151876001600160a01b031663d4cadf686040518163ffffffff1660e01b815260040160206040518083038186803b1580156111cf57600080fd5b505afa1580156111e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112079190810190612d87565b6040518763ffffffff1660e01b8152600401611228969594939291906132c3565b60206040518083038186803b15801561124057600080fd5b505afa158015611254573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112789190810190612d87565b92506112826127e4565b8a868151811061128e57fe5b60200260200101516000815181106112a257fe5b602090810291909101810151908101518151604051636eb1769f60e11b81529293509091600019906001600160a01b0384169063dd62ed3e906112eb9030908690600401613108565b60206040518083038186803b15801561130357600080fd5b505afa158015611317573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061133b9190810190612d87565b10156113c657825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b39161137291906000199060040161319c565b602060405180830381600087803b15801561138c57600080fd5b505af11580156113a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c49190810190612d23565b505b806001600160a01b0316637c5e9ea48460200151856080015186604001518a8860a001516040518663ffffffff1660e01b815260040161140a9594939291906131aa565b6040805180830381600087803b15801561142357600080fd5b505af1158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061145b9190810190612da5565b5060208601518651604051636eb1769f60e11b81529299509091600019916001600160a01b0384169163dd62ed3e9161149991309190600401613108565b60206040518083038186803b1580156114b157600080fd5b505afa1580156114c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114e99190810190612d87565b101561157457855160405163095ea7b360e01b81526001600160a01b0383169163095ea7b39161152091906000199060040161319c565b602060405180830381600087803b15801561153a57600080fd5b505af115801561154e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115729190810190612d23565b505b846001600160a01b0316637c5e9ea48760200151886080015189604001518a606001518b60a001516040518663ffffffff1660e01b81526004016115bc9594939291906131aa565b6040805180830381600087803b1580156115d557600080fd5b505af11580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061160d9190810190612da5565b5050505050505050505b611627818463ffffffff611e4a16565b925050600101610cb5565b600061163e8584611d28565b5060005b86518110156118c5576116536127e4565b87828151811061165f57fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e906116a79030908690600401613108565b60206040518083038186803b1580156116bf57600080fd5b505afa1580156116d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116f79190810190612d87565b111561178157825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b39161172d9190600090600401613181565b602060405180830381600087803b15801561174757600080fd5b505af115801561175b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061177f9190810190612d23565b505b8251606084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b3926117b29260040161319c565b602060405180830381600087803b1580156117cc57600080fd5b505af11580156117e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118049190810190612d23565b5060208301516060840151604080860151608087015160a08801519251638201aa3f60e01b81526000956001600160a01b03881695638201aa3f9561184f95929491936004016131aa565b6040805180830381600087803b15801561186857600080fd5b505af115801561187c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118a09190810190612da5565b5090506118b3818763ffffffff611e4a16565b95505060019093019250611642915050565b50818110156118e65760405162461bcd60e51b815260040161056890613255565b6118f08482611f39565b506118fe8561057e87611e76565b5095945050505050565b6000546001600160a01b031690565b600080546001600160a01b031661192c6126ab565b6001600160a01b031614905090565b611943611917565b61195f5760405162461bcd60e51b815260040161056890613285565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000606061198e87611d02565b156119b3576001546119ab906001600160a01b031687878661059a565b5090506119ea565b6119bc86611d02565b156119da576001546119ab9088906001600160a01b0316878661059a565b6119e68787878661059a565b5090505b6102a9818888876102b4565b6000611a028584611d28565b5060005b86518110156118c5576000805b888381518110611a1f57fe5b602002602001015151811015611cb657611a376127e4565b898481518110611a4357fe5b60200260200101518281518110611a5657fe5b602002602001015190506000816020015190508260011415611a7a57606082018490525b8151604051636eb1769f60e11b81526000906001600160a01b0384169063dd62ed3e90611aad9030908690600401613108565b60206040518083038186803b158015611ac557600080fd5b505afa158015611ad9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611afd9190810190612d87565b1115611b8757825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b391611b339190600090600401613181565b602060405180830381600087803b158015611b4d57600080fd5b505af1158015611b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b859190810190612d23565b505b8251606084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b392611bb89260040161319c565b602060405180830381600087803b158015611bd257600080fd5b505af1158015611be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c0a9190810190612d23565b50806001600160a01b0316638201aa3f84602001518560600151866040015187608001518860a001516040518663ffffffff1660e01b8152600401611c539594939291906131aa565b6040805180830381600087803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ca49190810190612da5565b5094505060019092019150611a139050565b50611cc7818463ffffffff611e4a16565b925050600101611a06565b611cda611917565b611cf65760405162461bcd60e51b815260040161056890613285565b611cff816126af565b50565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b919050565b6000611d3383611d02565b15611da657600160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d8857600080fd5b505af1158015611d9c573d6000803e3d6000fd5b5050505050611e44565b6040516323b872dd60e01b81526001600160a01b038416906323b872dd90611dd690339030908790600401613123565b602060405180830381600087803b158015611df057600080fd5b505af1158015611e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e289190810190612d23565b611e445760405162461bcd60e51b8152600401610568906132a5565b92915050565b600082820183811015611e6f5760405162461bcd60e51b815260040161056890613245565b9392505050565b6000611e8182611d02565b15611f0d576001546040516370a0823160e01b81526001600160a01b03909116906370a0823190611eb69030906004016130fa565b60206040518083038186803b158015611ece57600080fd5b505afa158015611ee2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f069190810190612d87565b9050611d23565b6040516370a0823160e01b81526001600160a01b038316906370a0823190611eb69030906004016130fa565b600081611f4857506001611e44565b611f5183611d02565b1561203a57600154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90611f869085906004016132b5565b600060405180830381600087803b158015611fa057600080fd5b505af1158015611fb4573d6000803e3d6000fd5b505050506000336001600160a01b031683604051611fd1906130e1565b60006040518083038185875af1925050503d806000811461200e576040519150601f19603f3d011682016040523d82523d6000602084013e612013565b606091505b50509050806120345760405162461bcd60e51b815260040161056890613295565b50611e44565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb90611dd6903390869060040161314b565b612070612835565b60405163f8b2cb4f60e01b815282906000906001600160a01b0383169063f8b2cb4f906120a19089906004016130ec565b60206040518083038186803b1580156120b957600080fd5b505afa1580156120cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120f19190810190612d87565b90506000826001600160a01b031663f8b2cb4f876040518263ffffffff1660e01b815260040161212191906130ec565b60206040518083038186803b15801561213957600080fd5b505afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121719190810190612d87565b90506000836001600160a01b031663948d8ce6896040518263ffffffff1660e01b81526004016121a191906130ec565b60206040518083038186803b1580156121b957600080fd5b505afa1580156121cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121f19190810190612d87565b90506000846001600160a01b031663948d8ce6896040518263ffffffff1660e01b815260040161222191906130ec565b60206040518083038186803b15801561223957600080fd5b505afa15801561224d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122719190810190612d87565b90506000856001600160a01b031663d4cadf686040518163ffffffff1660e01b815260040160206040518083038186803b1580156122ae57600080fd5b505afa1580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122e69190810190612d87565b905060006122f5848685612730565b90506122ff612835565b506040805160e0810182526001600160a01b038b16815260208101979097528601939093526060850193909352608084015260a083019190915260c08201529150509392505050565b60008261235757506000611e44565b8282028284828161236457fe5b0414611e6f5760405162461bcd60e51b815260040161056890613275565b6000611e6f83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612781565b6000611e6f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506127b8565b6000805b835181101561255557600083828151811061242157fe5b6020026020010151600001516001600160a01b031663f8d6aed485848151811061244757fe5b60200260200101516020015186858151811061245f57fe5b60200260200101516040015187868151811061247757fe5b60200260200101516060015188878151811061248f57fe5b6020026020010151608001518a88815181106124a757fe5b60200260200101518a89815181106124bb57fe5b602002602001015160a001516040518763ffffffff1660e01b81526004016124e8969594939291906132c3565b60206040518083038186803b15801561250057600080fd5b505afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125389190810190612d87565b905061254a838263ffffffff611e4a16565b92505060010161240a565b5092915050565b6000805b835181101561255557600083828151811061257757fe5b6020026020010151600001516001600160a01b031663ba9530a685848151811061259d57fe5b6020026020010151602001518685815181106125b557fe5b6020026020010151604001518786815181106125cd57fe5b6020026020010151606001518887815181106125e557fe5b6020026020010151608001518a88815181106125fd57fe5b60200260200101518a898151811061261157fe5b602002602001015160a001516040518763ffffffff1660e01b815260040161263e969594939291906132c3565b60206040518083038186803b15801561265657600080fd5b505afa15801561266a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061268e9190810190612d87565b90506126a0838263ffffffff611e4a16565b925050600101612560565b3390565b6001600160a01b0381166126d55760405162461bcd60e51b815260040161056890613235565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612779670de0b6b3a764000061074c8561276d612755878a63ffffffff611e4a16565b61074c8a670de0b6b3a764000063ffffffff61234816565b9063ffffffff61234816565b949350505050565b600081836127a25760405162461bcd60e51b81526004016105689190613224565b5060008385816127ae57fe5b0495945050505050565b600081848411156127dc5760405162461bcd60e51b81526004016105689190613224565b505050900390565b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b6040518060e0016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8035611e44816133e3565b8051611e44816133e3565b600082601f8301126128a257600080fd5b81516128b56128b082613339565b613312565b915081818352602084019350602081019050838560208402820111156128da57600080fd5b60005b8381101561290657816128f08882612886565b84525060209283019291909101906001016128dd565b5050505092915050565b600082601f83011261292157600080fd5b813561292f6128b082613339565b81815260209384019390925082018360005b838110156129065781358601612957888261296d565b8452506020928301929190910190600101612941565b600082601f83011261297e57600080fd5b813561298c6128b082613339565b915081818352602084019350602081019050838560c08402820111156129b157600080fd5b60005b8381101561290657816129c78882612a67565b84525060209092019160c091909101906001016129b4565b600082601f8301126129f057600080fd5b81356129fe6128b082613339565b915081818352602084019350602081019050838560c0840282011115612a2357600080fd5b60005b838110156129065781612a398882612a67565b84525060209092019160c09190910190600101612a26565b8051611e44816133f7565b8035611e4481613400565b600060c08284031215612a7957600080fd5b612a8360c0613312565b90506000612a91848461287b565b8252506020612aa28484830161287b565b6020830152506040612ab68482850161287b565b6040830152506060612aca84828501612afe565b6060830152506080612ade84828501612afe565b60808301525060a0612af284828501612afe565b60a08301525092915050565b8035611e4481613409565b8051611e4481613409565b600060208284031215612b2657600080fd5b6000612779848461287b565b60008060008060808587031215612b4857600080fd5b6000612b54878761287b565b9450506020612b658782880161287b565b9350506040612b7687828801612afe565b9250506060612b8787828801612afe565b91505092959194509250565b600060208284031215612ba557600080fd5b815167ffffffffffffffff811115612bbc57600080fd5b61277984828501612891565b60008060008060808587031215612bde57600080fd5b843567ffffffffffffffff811115612bf557600080fd5b612c0187828801612910565b9450506020612c1287828801612a5c565b9350506040612b7687828801612a5c565b600080600080600060a08688031215612c3b57600080fd5b853567ffffffffffffffff811115612c5257600080fd5b612c5e88828901612910565b9550506020612c6f88828901612a5c565b9450506040612c8088828901612a5c565b9350506060612c9188828901612afe565b9250506080612ca288828901612afe565b9150509295509295909350565b60008060008060808587031215612cc557600080fd5b843567ffffffffffffffff811115612cdc57600080fd5b612c01878288016129df565b600080600080600060a08688031215612d0057600080fd5b853567ffffffffffffffff811115612d1757600080fd5b612c5e888289016129df565b600060208284031215612d3557600080fd5b60006127798484612a51565b600080600080600060a08688031215612d5957600080fd5b6000612d658888612a5c565b9550506020612d7688828901612a5c565b9450506040612c8088828901612afe565b600060208284031215612d9957600080fd5b60006127798484612b09565b60008060408385031215612db857600080fd5b6000612dc48585612b09565b9250506020612dd585828601612b09565b9150509250929050565b6000612deb8383613062565b505060c00190565b612dfc81613397565b82525050565b612dfc8161336d565b6000612e1682613360565b612e208185613364565b9350612e2b8361335a565b8060005b83811015612e59578151612e438882612ddf565b9750612e4e8361335a565b925050600101612e2f565b509495945050505050565b612dfc81613378565b612dfc816133a2565b6000612e8182613360565b612e8b8185613364565b9350612e9b8185602086016133ad565b612ea4816133d9565b9093019392505050565b6000612ebb602683613364565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000612f03601b83613364565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000612f3c600d83613364565b6c11549497d31253525517d3d555609a1b815260200192915050565b6000612f65600c83613364565b6b22a9292fa624a6a4aa2fa4a760a11b815260200192915050565b6000612f8d602183613364565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000612fd0602083613364565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613009600e83613364565b6d11549497d1551217d1905253115160921b815260200192915050565b6000611e44600083611d23565b6000613040601383613364565b7211549497d514905394d1915497d19052531151606a1b815260200192915050565b805160c08301906130738482612e02565b5060208201516130866020850182612e02565b5060408201516130996040850182612e02565b5060608201516130ac60608501826130d8565b5060808201516130bf60808501826130d8565b5060a08201516130d260a08501826130d8565b50505050565b612dfc81613394565b6000611e4482613026565b60208101611e448284612e02565b60208101611e448284612df3565b604081016131168285612df3565b611e6f6020830184612e02565b606081016131318286612df3565b61313e6020830185612df3565b61277960408301846130d8565b604081016131598285612df3565b611e6f60208301846130d8565b606081016131748286612e02565b61313e6020830185612e02565b6040810161318f8285612e02565b611e6f6020830184612e6d565b604081016131598285612e02565b60a081016131b88288612e02565b6131c560208301876130d8565b6131d26040830186612e02565b6131df60608301856130d8565b6131ec60808301846130d8565b9695505050505050565b604080825281016132078185612e0b565b9050611e6f60208301846130d8565b60208101611e448284612e64565b60208082528101611e6f8184612e76565b60208082528101611e4481612eae565b60208082528101611e4481612ef6565b60208082528101611e4481612f2f565b60208082528101611e4481612f58565b60208082528101611e4481612f80565b60208082528101611e4481612fc3565b60208082528101611e4481612ffc565b60208082528101611e4481613033565b60208101611e4482846130d8565b60c081016132d182896130d8565b6132de60208301886130d8565b6132eb60408301876130d8565b6132f860608301866130d8565b61330560808301856130d8565b6102a960a08301846130d8565b60405181810167ffffffffffffffff8111828210171561333157600080fd5b604052919050565b600067ffffffffffffffff82111561335057600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b6000611e4482613388565b151590565b6000611e448261336d565b6001600160a01b031690565b90565b6000611e448261337d565b6000611e4482613394565b60005b838110156133c85781810151838201526020016133b0565b838111156130d25750506000910152565b601f01601f191690565b6133ec8161336d565b8114611cff57600080fd5b6133ec81613378565b6133ec8161337d565b6133ec8161339456fea365627a7a723158207d8b781f026c8e7032775d04416bdecff0427eb53e69ad3ff924bf75be9fe5216c6578706572696d656e74616cf564736f6c634300050c0040", + "deployedBytecode": "0x6080604052600436106100c25760003560e01c80638743ad581161007f578063a91ee0dc11610059578063a91ee0dc146101cd578063b40f39ee146101ed578063e2b3974614610200578063f2fde38b14610213576100c2565b80638743ad58146101765780638da5cb5b146101895780638f32d59b146101ab576100c2565b806321b0eb85146100c45780632db58134146100ed578063368bb1fc146101005780634b0f93fb1461012e578063715018a61461014e57806386b2ecc414610163575b005b6100d76100d2366004612d41565b610233565b6040516100e491906132b5565b60405180910390f35b6100d76100fb366004612caf565b6102b4565b34801561010c57600080fd5b5061012061011b366004612b32565b61059a565b6040516100e49291906131f6565b34801561013a57600080fd5b50610120610149366004612b32565b610947565b34801561015a57600080fd5b506100c2610c37565b6100d7610171366004612bc8565b610ca5565b6100d7610184366004612ce8565b611632565b34801561019557600080fd5b5061019e611908565b6040516100e491906130ec565b3480156101b757600080fd5b506101c0611917565b6040516100e49190613216565b3480156101d957600080fd5b506100c26101e8366004612b14565b61193b565b6100d76101fb366004612d41565b611981565b6100d761020e366004612c23565b6119f6565b34801561021f57600080fd5b506100c261022e366004612b14565b611cd2565b6000606061024087611d02565b156102655760015461025d906001600160a01b0316878786610947565b50905061029c565b61026e86611d02565b1561028c5760015461025d9088906001600160a01b03168786610947565b61029887878786610947565b5090505b6102a98188888888611632565b979650505050505050565b60006102c08483611d28565b5060005b8551811015610547576102d56127e4565b8682815181106102e157fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e906103299030908690600401613108565b60206040518083038186803b15801561034157600080fd5b505afa158015610355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103799190810190612d87565b111561040357825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b3916103af9190600090600401613181565b602060405180830381600087803b1580156103c957600080fd5b505af11580156103dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104019190810190612d23565b505b8251608084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b3926104349260040161319c565b602060405180830381600087803b15801561044e57600080fd5b505af1158015610462573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104869190810190612d23565b5060208301516080840151604080860151606087015160a08801519251631f17a7a960e21b81526000956001600160a01b03881695637c5e9ea4956104d195929491936004016131aa565b6040805180830381600087803b1580156104ea57600080fd5b505af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105229190810190612da5565b509050610535818763ffffffff611e4a16565b955050600190930192506102c4915050565b50818111156105715760405162461bcd60e51b815260040161056890613265565b60405180910390fd5b6105838361057e85611e76565b611f39565b506105918461057e86611e76565b50949350505050565b60025460405163bfdbfc4360e01b815260609160009183916001600160a01b03169063bfdbfc43906105d4908a908a908990600401613166565b60006040518083038186803b1580156105ec57600080fd5b505afa158015610600573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106289190810190612b93565b90506060815160405190808252806020026020018201604052801561066757816020015b610654612835565b81526020019060019003908161064c5790505b5090506000805b83518110156106e0576106958a8a86848151811061068857fe5b6020026020010151612068565b8382815181106106a157fe5b60200260200101819052506106d68382815181106106bb57fe5b602002602001015160c0015183611e4a90919063ffffffff16565b915060010161066e565b506060825160405190808252806020026020018201604052801561070e578160200160208202803883390190505b5090506000805b84518110156107a0576107588461074c87848151811061073157fe5b602002602001015160c001518d61234890919063ffffffff16565b9063ffffffff61238216565b83828151811061076457fe5b60200260200101818152505061079683828151811061077f57fe5b602002602001015183611e4a90919063ffffffff16565b9150600101610715565b50888110156107fd576107df6107bc8a8363ffffffff6123c416565b836000815181106107c957fe5b6020026020010151611e4a90919063ffffffff16565b826000815181106107ec57fe5b60200260200101818152505061084d565b610833610810828b63ffffffff6123c416565b8360008151811061081d57fe5b60200260200101516123c490919063ffffffff16565b8260008151811061084057fe5b6020026020010181815250505b835160405190808252806020026020018201604052801561088857816020015b6108756127e4565b81526020019060019003908161086d5790505b50965060005b845181101561092c576040518060c001604052808683815181106108ae57fe5b6020026020010151600001516001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b031681526020018483815181106108f257fe5b60200260200101518152602001600019815260200160001981525088828151811061091957fe5b602090810291909101015260010161088e565b506109378285612406565b9550505050505094509492505050565b60025460405163bfdbfc4360e01b815260609160009183916001600160a01b03169063bfdbfc4390610981908a908a908990600401613166565b60006040518083038186803b15801561099957600080fd5b505afa1580156109ad573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109d59190810190612b93565b905060608151604051908082528060200260200182016040528015610a1457816020015b610a01612835565b8152602001906001900390816109f95790505b5090506000805b8351811015610a6557610a358a8a86848151811061068857fe5b838281518110610a4157fe5b6020026020010181905250610a5b8382815181106106bb57fe5b9150600101610a1b565b5060608251604051908082528060200260200182016040528015610a93578160200160208202803883390190505b5090506000805b8451811015610ae757610ab68461074c87848151811061073157fe5b838281518110610ac257fe5b602002602001018181525050610add83828151811061077f57fe5b9150600101610a9a565b5088811015610b2157610b036107bc8a8363ffffffff6123c416565b82600081518110610b1057fe5b602002602001018181525050610b4e565b610b34610810828b63ffffffff6123c416565b82600081518110610b4157fe5b6020026020010181815250505b8351604051908082528060200260200182016040528015610b8957816020015b610b766127e4565b815260200190600190039081610b6e5790505b50965060005b8451811015610c2c576040518060c00160405280868381518110610baf57fe5b6020026020010151600001516001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b03168152602001848381518110610bf357fe5b6020026020010151815260200160008152602001600019815250888281518110610c1957fe5b6020908102919091010152600101610b8f565b50610937828561255c565b610c3f611917565b610c5b5760405162461bcd60e51b815260040161056890613285565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000610cb18483611d28565b5060005b8551811015610547576000868281518110610ccc57fe5b60200260200101515160011415610f5057610ce56127e4565b878381518110610cf157fe5b6020026020010151600081518110610d0557fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e90610d4d9030908690600401613108565b60206040518083038186803b158015610d6557600080fd5b505afa158015610d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d9d9190810190612d87565b1115610e2757825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b391610dd39190600090600401613181565b602060405180830381600087803b158015610ded57600080fd5b505af1158015610e01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e259190810190612d23565b505b8251608084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b392610e589260040161319c565b602060405180830381600087803b158015610e7257600080fd5b505af1158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610eaa9190810190612d23565b50806001600160a01b0316637c5e9ea484602001518560800151866040015187606001518860a001516040518663ffffffff1660e01b8152600401610ef39594939291906131aa565b6040805180830381600087803b158015610f0c57600080fd5b505af1158015610f20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f449190810190612da5565b50935061161792505050565b6000610f5a6127e4565b888481518110610f6657fe5b6020026020010151600181518110610f7a57fe5b60209081029190910181015180519181015160405163f8b2cb4f60e01b81529193506001600160a01b0383169163f8d6aed491839163f8b2cb4f91610fc1916004016130ec565b60206040518083038186803b158015610fd957600080fd5b505afa158015610fed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110119190810190612d87565b6020850151604051634a46c67360e11b81526001600160a01b0386169163948d8ce69161104191906004016130ec565b60206040518083038186803b15801561105957600080fd5b505afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110919190810190612d87565b604080870151905163f8b2cb4f60e01b81526001600160a01b0387169163f8b2cb4f916110c191906004016130ec565b60206040518083038186803b1580156110d957600080fd5b505afa1580156110ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111119190810190612d87565b6040808801519051634a46c67360e11b81526001600160a01b0388169163948d8ce69161114191906004016130ec565b60206040518083038186803b15801561115957600080fd5b505afa15801561116d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111919190810190612d87565b8760600151876001600160a01b031663d4cadf686040518163ffffffff1660e01b815260040160206040518083038186803b1580156111cf57600080fd5b505afa1580156111e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112079190810190612d87565b6040518763ffffffff1660e01b8152600401611228969594939291906132c3565b60206040518083038186803b15801561124057600080fd5b505afa158015611254573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112789190810190612d87565b92506112826127e4565b8a868151811061128e57fe5b60200260200101516000815181106112a257fe5b602090810291909101810151908101518151604051636eb1769f60e11b81529293509091600019906001600160a01b0384169063dd62ed3e906112eb9030908690600401613108565b60206040518083038186803b15801561130357600080fd5b505afa158015611317573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061133b9190810190612d87565b10156113c657825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b39161137291906000199060040161319c565b602060405180830381600087803b15801561138c57600080fd5b505af11580156113a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113c49190810190612d23565b505b806001600160a01b0316637c5e9ea48460200151856080015186604001518a8860a001516040518663ffffffff1660e01b815260040161140a9594939291906131aa565b6040805180830381600087803b15801561142357600080fd5b505af1158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061145b9190810190612da5565b5060208601518651604051636eb1769f60e11b81529299509091600019916001600160a01b0384169163dd62ed3e9161149991309190600401613108565b60206040518083038186803b1580156114b157600080fd5b505afa1580156114c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114e99190810190612d87565b101561157457855160405163095ea7b360e01b81526001600160a01b0383169163095ea7b39161152091906000199060040161319c565b602060405180830381600087803b15801561153a57600080fd5b505af115801561154e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115729190810190612d23565b505b846001600160a01b0316637c5e9ea48760200151886080015189604001518a606001518b60a001516040518663ffffffff1660e01b81526004016115bc9594939291906131aa565b6040805180830381600087803b1580156115d557600080fd5b505af11580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061160d9190810190612da5565b5050505050505050505b611627818463ffffffff611e4a16565b925050600101610cb5565b600061163e8584611d28565b5060005b86518110156118c5576116536127e4565b87828151811061165f57fe5b602090810291909101810151908101518151604051636eb1769f60e11b815292935090916000906001600160a01b0384169063dd62ed3e906116a79030908690600401613108565b60206040518083038186803b1580156116bf57600080fd5b505afa1580156116d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116f79190810190612d87565b111561178157825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b39161172d9190600090600401613181565b602060405180830381600087803b15801561174757600080fd5b505af115801561175b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061177f9190810190612d23565b505b8251606084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b3926117b29260040161319c565b602060405180830381600087803b1580156117cc57600080fd5b505af11580156117e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118049190810190612d23565b5060208301516060840151604080860151608087015160a08801519251638201aa3f60e01b81526000956001600160a01b03881695638201aa3f9561184f95929491936004016131aa565b6040805180830381600087803b15801561186857600080fd5b505af115801561187c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118a09190810190612da5565b5090506118b3818763ffffffff611e4a16565b95505060019093019250611642915050565b50818110156118e65760405162461bcd60e51b815260040161056890613255565b6118f08482611f39565b506118fe8561057e87611e76565b5095945050505050565b6000546001600160a01b031690565b600080546001600160a01b031661192c6126ab565b6001600160a01b031614905090565b611943611917565b61195f5760405162461bcd60e51b815260040161056890613285565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000606061198e87611d02565b156119b3576001546119ab906001600160a01b031687878661059a565b5090506119ea565b6119bc86611d02565b156119da576001546119ab9088906001600160a01b0316878661059a565b6119e68787878661059a565b5090505b6102a9818888876102b4565b6000611a028584611d28565b5060005b86518110156118c5576000805b888381518110611a1f57fe5b602002602001015151811015611cb657611a376127e4565b898481518110611a4357fe5b60200260200101518281518110611a5657fe5b602002602001015190506000816020015190508260011415611a7a57606082018490525b8151604051636eb1769f60e11b81526000906001600160a01b0384169063dd62ed3e90611aad9030908690600401613108565b60206040518083038186803b158015611ac557600080fd5b505afa158015611ad9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611afd9190810190612d87565b1115611b8757825160405163095ea7b360e01b81526001600160a01b0384169163095ea7b391611b339190600090600401613181565b602060405180830381600087803b158015611b4d57600080fd5b505af1158015611b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b859190810190612d23565b505b8251606084015160405163095ea7b360e01b81526001600160a01b0385169263095ea7b392611bb89260040161319c565b602060405180830381600087803b158015611bd257600080fd5b505af1158015611be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c0a9190810190612d23565b50806001600160a01b0316638201aa3f84602001518560600151866040015187608001518860a001516040518663ffffffff1660e01b8152600401611c539594939291906131aa565b6040805180830381600087803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ca49190810190612da5565b5094505060019092019150611a139050565b50611cc7818463ffffffff611e4a16565b925050600101611a06565b611cda611917565b611cf65760405162461bcd60e51b815260040161056890613285565b611cff816126af565b50565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b919050565b6000611d3383611d02565b15611da657600160009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d8857600080fd5b505af1158015611d9c573d6000803e3d6000fd5b5050505050611e44565b6040516323b872dd60e01b81526001600160a01b038416906323b872dd90611dd690339030908790600401613123565b602060405180830381600087803b158015611df057600080fd5b505af1158015611e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e289190810190612d23565b611e445760405162461bcd60e51b8152600401610568906132a5565b92915050565b600082820183811015611e6f5760405162461bcd60e51b815260040161056890613245565b9392505050565b6000611e8182611d02565b15611f0d576001546040516370a0823160e01b81526001600160a01b03909116906370a0823190611eb69030906004016130fa565b60206040518083038186803b158015611ece57600080fd5b505afa158015611ee2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f069190810190612d87565b9050611d23565b6040516370a0823160e01b81526001600160a01b038316906370a0823190611eb69030906004016130fa565b600081611f4857506001611e44565b611f5183611d02565b1561203a57600154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90611f869085906004016132b5565b600060405180830381600087803b158015611fa057600080fd5b505af1158015611fb4573d6000803e3d6000fd5b505050506000336001600160a01b031683604051611fd1906130e1565b60006040518083038185875af1925050503d806000811461200e576040519150601f19603f3d011682016040523d82523d6000602084013e612013565b606091505b50509050806120345760405162461bcd60e51b815260040161056890613295565b50611e44565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb90611dd6903390869060040161314b565b612070612835565b60405163f8b2cb4f60e01b815282906000906001600160a01b0383169063f8b2cb4f906120a19089906004016130ec565b60206040518083038186803b1580156120b957600080fd5b505afa1580156120cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506120f19190810190612d87565b90506000826001600160a01b031663f8b2cb4f876040518263ffffffff1660e01b815260040161212191906130ec565b60206040518083038186803b15801561213957600080fd5b505afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121719190810190612d87565b90506000836001600160a01b031663948d8ce6896040518263ffffffff1660e01b81526004016121a191906130ec565b60206040518083038186803b1580156121b957600080fd5b505afa1580156121cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121f19190810190612d87565b90506000846001600160a01b031663948d8ce6896040518263ffffffff1660e01b815260040161222191906130ec565b60206040518083038186803b15801561223957600080fd5b505afa15801561224d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122719190810190612d87565b90506000856001600160a01b031663d4cadf686040518163ffffffff1660e01b815260040160206040518083038186803b1580156122ae57600080fd5b505afa1580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122e69190810190612d87565b905060006122f5848685612730565b90506122ff612835565b506040805160e0810182526001600160a01b038b16815260208101979097528601939093526060850193909352608084015260a083019190915260c08201529150509392505050565b60008261235757506000611e44565b8282028284828161236457fe5b0414611e6f5760405162461bcd60e51b815260040161056890613275565b6000611e6f83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612781565b6000611e6f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506127b8565b6000805b835181101561255557600083828151811061242157fe5b6020026020010151600001516001600160a01b031663f8d6aed485848151811061244757fe5b60200260200101516020015186858151811061245f57fe5b60200260200101516040015187868151811061247757fe5b60200260200101516060015188878151811061248f57fe5b6020026020010151608001518a88815181106124a757fe5b60200260200101518a89815181106124bb57fe5b602002602001015160a001516040518763ffffffff1660e01b81526004016124e8969594939291906132c3565b60206040518083038186803b15801561250057600080fd5b505afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125389190810190612d87565b905061254a838263ffffffff611e4a16565b92505060010161240a565b5092915050565b6000805b835181101561255557600083828151811061257757fe5b6020026020010151600001516001600160a01b031663ba9530a685848151811061259d57fe5b6020026020010151602001518685815181106125b557fe5b6020026020010151604001518786815181106125cd57fe5b6020026020010151606001518887815181106125e557fe5b6020026020010151608001518a88815181106125fd57fe5b60200260200101518a898151811061261157fe5b602002602001015160a001516040518763ffffffff1660e01b815260040161263e969594939291906132c3565b60206040518083038186803b15801561265657600080fd5b505afa15801561266a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061268e9190810190612d87565b90506126a0838263ffffffff611e4a16565b925050600101612560565b3390565b6001600160a01b0381166126d55760405162461bcd60e51b815260040161056890613235565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612779670de0b6b3a764000061074c8561276d612755878a63ffffffff611e4a16565b61074c8a670de0b6b3a764000063ffffffff61234816565b9063ffffffff61234816565b949350505050565b600081836127a25760405162461bcd60e51b81526004016105689190613224565b5060008385816127ae57fe5b0495945050505050565b600081848411156127dc5760405162461bcd60e51b81526004016105689190613224565b505050900390565b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b6040518060e0016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8035611e44816133e3565b8051611e44816133e3565b600082601f8301126128a257600080fd5b81516128b56128b082613339565b613312565b915081818352602084019350602081019050838560208402820111156128da57600080fd5b60005b8381101561290657816128f08882612886565b84525060209283019291909101906001016128dd565b5050505092915050565b600082601f83011261292157600080fd5b813561292f6128b082613339565b81815260209384019390925082018360005b838110156129065781358601612957888261296d565b8452506020928301929190910190600101612941565b600082601f83011261297e57600080fd5b813561298c6128b082613339565b915081818352602084019350602081019050838560c08402820111156129b157600080fd5b60005b8381101561290657816129c78882612a67565b84525060209092019160c091909101906001016129b4565b600082601f8301126129f057600080fd5b81356129fe6128b082613339565b915081818352602084019350602081019050838560c0840282011115612a2357600080fd5b60005b838110156129065781612a398882612a67565b84525060209092019160c09190910190600101612a26565b8051611e44816133f7565b8035611e4481613400565b600060c08284031215612a7957600080fd5b612a8360c0613312565b90506000612a91848461287b565b8252506020612aa28484830161287b565b6020830152506040612ab68482850161287b565b6040830152506060612aca84828501612afe565b6060830152506080612ade84828501612afe565b60808301525060a0612af284828501612afe565b60a08301525092915050565b8035611e4481613409565b8051611e4481613409565b600060208284031215612b2657600080fd5b6000612779848461287b565b60008060008060808587031215612b4857600080fd5b6000612b54878761287b565b9450506020612b658782880161287b565b9350506040612b7687828801612afe565b9250506060612b8787828801612afe565b91505092959194509250565b600060208284031215612ba557600080fd5b815167ffffffffffffffff811115612bbc57600080fd5b61277984828501612891565b60008060008060808587031215612bde57600080fd5b843567ffffffffffffffff811115612bf557600080fd5b612c0187828801612910565b9450506020612c1287828801612a5c565b9350506040612b7687828801612a5c565b600080600080600060a08688031215612c3b57600080fd5b853567ffffffffffffffff811115612c5257600080fd5b612c5e88828901612910565b9550506020612c6f88828901612a5c565b9450506040612c8088828901612a5c565b9350506060612c9188828901612afe565b9250506080612ca288828901612afe565b9150509295509295909350565b60008060008060808587031215612cc557600080fd5b843567ffffffffffffffff811115612cdc57600080fd5b612c01878288016129df565b600080600080600060a08688031215612d0057600080fd5b853567ffffffffffffffff811115612d1757600080fd5b612c5e888289016129df565b600060208284031215612d3557600080fd5b60006127798484612a51565b600080600080600060a08688031215612d5957600080fd5b6000612d658888612a5c565b9550506020612d7688828901612a5c565b9450506040612c8088828901612afe565b600060208284031215612d9957600080fd5b60006127798484612b09565b60008060408385031215612db857600080fd5b6000612dc48585612b09565b9250506020612dd585828601612b09565b9150509250929050565b6000612deb8383613062565b505060c00190565b612dfc81613397565b82525050565b612dfc8161336d565b6000612e1682613360565b612e208185613364565b9350612e2b8361335a565b8060005b83811015612e59578151612e438882612ddf565b9750612e4e8361335a565b925050600101612e2f565b509495945050505050565b612dfc81613378565b612dfc816133a2565b6000612e8182613360565b612e8b8185613364565b9350612e9b8185602086016133ad565b612ea4816133d9565b9093019392505050565b6000612ebb602683613364565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000612f03601b83613364565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000612f3c600d83613364565b6c11549497d31253525517d3d555609a1b815260200192915050565b6000612f65600c83613364565b6b22a9292fa624a6a4aa2fa4a760a11b815260200192915050565b6000612f8d602183613364565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000612fd0602083613364565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613009600e83613364565b6d11549497d1551217d1905253115160921b815260200192915050565b6000611e44600083611d23565b6000613040601383613364565b7211549497d514905394d1915497d19052531151606a1b815260200192915050565b805160c08301906130738482612e02565b5060208201516130866020850182612e02565b5060408201516130996040850182612e02565b5060608201516130ac60608501826130d8565b5060808201516130bf60808501826130d8565b5060a08201516130d260a08501826130d8565b50505050565b612dfc81613394565b6000611e4482613026565b60208101611e448284612e02565b60208101611e448284612df3565b604081016131168285612df3565b611e6f6020830184612e02565b606081016131318286612df3565b61313e6020830185612df3565b61277960408301846130d8565b604081016131598285612df3565b611e6f60208301846130d8565b606081016131748286612e02565b61313e6020830185612e02565b6040810161318f8285612e02565b611e6f6020830184612e6d565b604081016131598285612e02565b60a081016131b88288612e02565b6131c560208301876130d8565b6131d26040830186612e02565b6131df60608301856130d8565b6131ec60808301846130d8565b9695505050505050565b604080825281016132078185612e0b565b9050611e6f60208301846130d8565b60208101611e448284612e64565b60208082528101611e6f8184612e76565b60208082528101611e4481612eae565b60208082528101611e4481612ef6565b60208082528101611e4481612f2f565b60208082528101611e4481612f58565b60208082528101611e4481612f80565b60208082528101611e4481612fc3565b60208082528101611e4481612ffc565b60208082528101611e4481613033565b60208101611e4482846130d8565b60c081016132d182896130d8565b6132de60208301886130d8565b6132eb60408301876130d8565b6132f860608301866130d8565b61330560808301856130d8565b6102a960a08301846130d8565b60405181810167ffffffffffffffff8111828210171561333157600080fd5b604052919050565b600067ffffffffffffffff82111561335057600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b6000611e4482613388565b151590565b6000611e448261336d565b6001600160a01b031690565b90565b6000611e448261337d565b6000611e4482613394565b60005b838110156133c85781810151838201526020016133b0565b838111156130d25750506000910152565b601f01601f191690565b6133ec8161336d565b8114611cff57600080fd5b6133ec81613378565b6133ec8161337d565b6133ec8161339456fea365627a7a723158207d8b781f026c8e7032775d04416bdecff0427eb53e69ad3ff924bf75be9fe5216c6578706572696d656e74616cf564736f6c634300050c0040", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/static/abi.js b/src/static/abi.js new file mode 100644 index 0000000..8762479 --- /dev/null +++ b/src/static/abi.js @@ -0,0 +1,234 @@ +/* eslint-disable */ + +const ERC20Abi = [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] + +const KovanWETHAbi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}] + +const KovanFaucetAddress = '0xb48Cc42C45d262534e46d5965a9Ac496F1B7a830' + +module.exports = { + ERC20Abi, + KovanWETHAbi, + KovanFaucetAddress, +}; diff --git a/src/static/erc20_tokens_kovan.json b/src/static/erc20_tokens_kovan.json new file mode 100644 index 0000000..d4bb4e5 --- /dev/null +++ b/src/static/erc20_tokens_kovan.json @@ -0,0 +1,55 @@ +{ + "name": "kovan", + "tokens": [ + { + "symbol": "BAT", + "address": "0x1f1f156E0317167c11Aa412E3d1435ea29Dc3cCE", + "decimals": 18 + }, + { + "symbol": "WETH", + "address": "0xd0A1E359811322d97991E03f863a0C30C2cF029C", + "decimals": 18 + }, + { + "symbol": "DAI", + "address": "0x1528F3FCc26d13F7079325Fb78D9442607781c8C", + "decimals": 18 + }, + { + "symbol": "MKR", + "address": "0xef13C0c8abcaf5767160018d268f9697aE4f5375", + "decimals": 18 + }, + { + "symbol": "USDC", + "address": "0x2F375e94FC336Cdec2Dc0cCB5277FE59CBf1cAe5", + "decimals": 6 + }, + { + "symbol": "REP", + "address": "0x8c9e6c40d3402480ACE624730524fACC5482798c", + "decimals": 18 + }, + { + "symbol": "WBTC", + "address": "0xe0C9275E44Ea80eF17579d33c55136b7DA269aEb", + "decimals": 18 + }, + { + "symbol": "SNX", + "address": "0x86436BcE20258a6DcfE48C9512d4d49A30C4d8c4", + "decimals": 18 + }, + { + "symbol": "ANT", + "address": "0x37f03a12241E9FD3658ad6777d289c3fb8512Bc9", + "decimals": 18 + }, + { + "symbol": "ZRX", + "address": "0xccb0F4Cf5D3F97f4a55bb5f5cA321C3ED033f244", + "decimals": 18 + } + ] +} diff --git a/src/static/uniswap_route_tokens.json b/src/static/uniswap_route_tokens.json new file mode 100644 index 0000000..08c66bf --- /dev/null +++ b/src/static/uniswap_route_tokens.json @@ -0,0 +1,15 @@ +{"mainnet": [ + {"address":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","name":"WrappedEther","symbol":"WETH","decimals":18}, + {"address":"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599","name":"WrappedBTC","symbol":"WBTC","decimals":8}, + {"address":"0x6B175474E89094C44Da98b954EedeAC495271d0F","name":"DaiStablecoin","symbol":"DAI","decimals":18}, + {"address":"0xdAC17F958D2ee523a2206206994597C13D831ec7","name":"TetherUSD","symbol":"USDT","decimals":6}, + {"address":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","name":"USDCoin","symbol":"USDC","decimals":6}, + {"address":"0xba100000625a3754423978a60c9317c58a424e3D","name":"Balancer","symbol":"BAL","decimals":18}, + {"address":"0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD","name":"Loopring","symbol":"LRC","decimals":18} +], +"kovan":[ + {"address":"0xd0A1E359811322d97991E03f863a0C30C2cF029C","name":"WrappedEther","symbol":"WETH","decimals":18}, + {"address":"0xe0C9275E44Ea80eF17579d33c55136b7DA269aEb","name":"WrappedBTC","symbol":"WBTC","decimals":8}, + {"address":"0x1528F3FCc26d13F7079325Fb78D9442607781c8C","name":"DaiStablecoin","symbol":"DAI","decimals":18}, + {"address":"0x2F375e94FC336Cdec2Dc0cCB5277FE59CBf1cAe5","name":"USDCoin","symbol":"USDC","decimals":6} +]} diff --git a/src/static/uniswap_v2_router_abi.json b/src/static/uniswap_v2_router_abi.json new file mode 100644 index 0000000..e2eac42 --- /dev/null +++ b/src/static/uniswap_v2_router_abi.json @@ -0,0 +1,1924 @@ +{ + "abi": [ + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountADesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountTokenDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsIn", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsOut", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveB", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETHSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapETHForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETHSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + } + }, + "interface": [ + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountADesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountTokenDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsIn", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsOut", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveB", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETHSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapETHForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETHSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "" +} diff --git a/test/command.md b/test/command.md new file mode 100644 index 0000000..7ddb10c --- /dev/null +++ b/test/command.md @@ -0,0 +1,3 @@ + +# test endpoint +curl --insecure --key /home/dev/bots/hbot_files/hummingbot_certs/client_key.pem --cert /home/dev/bots/hbot_files/hummingbot_certs/client_cert.pem https://localhost:5000/api diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..ff7bd09 --- /dev/null +++ b/test/index.js @@ -0,0 +1 @@ +// placeholder diff --git a/test/postman/Gateway-Ethereum-Base.postman_collection.json b/test/postman/Gateway-Ethereum-Base.postman_collection.json new file mode 100644 index 0000000..20622ac --- /dev/null +++ b/test/postman/Gateway-Ethereum-Base.postman_collection.json @@ -0,0 +1,1264 @@ +{ + "info": { + "_postman_id": "e39af94e-6095-479e-8ba0-66930b12e364", + "name": "Gateway-Ethereum-Base", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "ethereum", + "item": [ + { + "name": "eth/balances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenAddressList", + "value": "{ \"{{WETH}}\": 18, \"{{DAI}}\": 18}", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balances", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "balances" + ] + } + }, + "response": [] + }, + { + "name": "eth/allowances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenAddressList", + "value": "{ \"{{BAT}}\": 18, \"{{DAI}}\": 18 }", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/allowances", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "allowances" + ] + } + }, + "response": [] + }, + { + "name": "eth/approve", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenAddress", + "value": "{{WETH}}", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "gasPrice", + "value": "23", + "type": "text" + }, + { + "key": "decimals", + "value": "18", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "amount", + "value": "999999", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/approve", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "approve" + ] + } + }, + "response": [] + }, + { + "name": "eth/get-weth", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "31", + "type": "text" + }, + { + "key": "amount", + "value": "0.03", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "tokenAddress", + "value": "{{WETH}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/get-weth", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "get-weth" + ] + } + }, + "response": [] + }, + { + "name": "eth/get-receipt", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "txHash", + "value": "{{txHash}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/get-receipt", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "get-receipt" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "balancer", + "item": [ + { + "name": "balancer", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/balancer", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "balancer" + ] + } + }, + "response": [] + }, + { + "name": "balancer/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "maxSwaps", + "value": "3", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/gas-limit", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "balancer", + "gas-limit" + ] + } + }, + "response": [] + }, + { + "name": "balancer/buy-price/", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "maxSwaps", + "value": "4", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/buy-price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "balancer", + "buy-price" + ] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "balancer/sell-price/", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "maxSwaps", + "value": "4", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/sell-price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "balancer", + "sell-price" + ] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "balancer/buy", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "maxSwaps", + "value": "4", + "type": "text" + }, + { + "key": "maxPrice", + "value": "0.19767217120251", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/buy", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "balancer", + "buy" + ] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "balancer/sell", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "0.1", + "type": "text" + }, + { + "key": "maxSwaps", + "value": "4", + "type": "text" + }, + { + "key": "maxPrice", + "value": "0.2685681573104575", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/sell", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "balancer", + "sell" + ] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "uniswap", + "item": [ + { + "name": "uniswap", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/uniswap", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "uniswap" + ] + } + }, + "response": [] + }, + { + "name": "uniswap/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/uniswap/gas-limit", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "uniswap", + "gas-limit" + ] + } + }, + "response": [] + }, + { + "name": "uniswap/buy-price/", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/uniswap/buy-price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "uniswap", + "buy-price" + ] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "uniswap/sell-price/", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/uniswap/sell-price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "uniswap", + "sell-price" + ] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + } + ], + "protocolProfileBehavior": {} + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/test/postman/Gateway-Terra.postman_collection.json b/test/postman/Gateway-Terra.postman_collection.json new file mode 100644 index 0000000..40866b8 --- /dev/null +++ b/test/postman/Gateway-Terra.postman_collection.json @@ -0,0 +1,328 @@ +{ + "info": { + "_postman_id": "3cca9e73-0e1f-4e4f-8973-87c985a43219", + "name": "Gateway-Terra", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "terra", + "item": [ + { + "name": "terra/balances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "address", + "value": "{{address}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/terra/balances", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "terra", + "balances" + ] + } + }, + "response": [] + }, + { + "name": "terra/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "SDT", + "type": "text" + }, + { + "key": "quote", + "value": "KRT", + "type": "text" + }, + { + "key": "trade_type", + "value": "buy", + "type": "text" + }, + { + "key": "amount", + "value": "3", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "terra", + "price" + ] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "terra/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "SDT", + "type": "text" + }, + { + "key": "quote", + "value": "KRT", + "type": "text" + }, + { + "key": "trade_type", + "value": "buy", + "type": "text" + }, + { + "key": "amount", + "value": "3", + "type": "text" + }, + { + "key": "secret", + "value": "{{secret}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/trade", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "terra", + "trade" + ] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + } + ], + "protocolProfileBehavior": {} + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/test/postman/PERPFI.postman_collection.json b/test/postman/PERPFI.postman_collection.json new file mode 100644 index 0000000..513a083 --- /dev/null +++ b/test/postman/PERPFI.postman_collection.json @@ -0,0 +1,454 @@ +{ + "info": { + "_postman_id": "08bf4528-5e70-42cd-bf71-b97f81088b9c", + "name": "PERPFI", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "default", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:{{port}}/perpfi/", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/load-metadata", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:{{port}}/perpfi/load-metadata", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "load-metadata" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/pairs", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:{{port}}/perpfi/pairs", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "pairs" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/balances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/balances", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "balances" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/allowances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/allowances", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "allowances" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/approve", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/approve", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "approve" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/open", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "margin", + "value": "15", + "type": "text" + }, + { + "key": "leverage", + "value": "2", + "type": "text" + }, + { + "key": "side", + "value": "{{SHORT}}", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/open", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "open" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/close", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/close", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "close" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/receipt", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "txHash", + "value": "0xd29120d947319c880f68a44b897c733c07ec313d670a7df55e523b501d7a03a2", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/receipt", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "receipt" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/position", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/position", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "position" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/margin", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/margin", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "margin" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/pnl", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/pnl", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "pnl" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/funding", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/funding", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "funding" + ] + } + }, + "response": [] + }, + { + "name": "perpfi/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "side", + "value": "buy", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "perpfi", + "price" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/test/postman/terra.postman_environment.json b/test/postman/terra.postman_environment.json new file mode 100644 index 0000000..735927a --- /dev/null +++ b/test/postman/terra.postman_environment.json @@ -0,0 +1,29 @@ +{ + "id": "aebe7d1f-0e85-4441-8679-2ddc38d74350", + "name": "terra", + "values": [ + { + "key": "protocol", + "value": "terra", + "enabled": true + }, + { + "key": "port", + "value": "5000", + "enabled": true + }, + { + "key": "address", + "value": "myaddresss", + "enabled": true + }, + { + "key": "secret", + "value": "mysupersecret", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2020-11-13T06:00:14.142Z", + "_postman_exported_using": "Postman/7.35.0" +} \ No newline at end of file diff --git a/test/postman/v2/Gateway.postman_collection.json b/test/postman/v2/Gateway.postman_collection.json new file mode 100644 index 0000000..949efe0 --- /dev/null +++ b/test/postman/v2/Gateway.postman_collection.json @@ -0,0 +1,1001 @@ +{ + "info": { + "_postman_id": "e39af94e-6095-479e-8ba0-66930b12e364", + "name": "Gateway", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "v2", + "item": [ + { + "name": "ethereum", + "item": [ + { + "name": "eth", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth" + ] + } + }, + "response": [] + }, + { + "name": "eth/balances", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenList", + "value": "[\"BAT\",\"USDC\",\"DAI\",\"WETH\",\"ZRX\"]", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balances", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "balances" + ] + } + }, + "response": [] + }, + { + "name": "eth/allowances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenList", + "value": "[\"BAT\",\"USDC\",\"DAI\",\"WETH\",\"ZRX\"]", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/allowances", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "allowances" + ] + } + }, + "response": [] + }, + { + "name": "eth/approve", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "token", + "value": "ZRX", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "gasPrice", + "value": "23", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "amount", + "value": "999", + "type": "text", + "disabled": true + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/approve", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "approve" + ] + } + }, + "response": [] + }, + { + "name": "eth/get-weth", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "31", + "type": "text" + }, + { + "key": "amount", + "value": "0.03", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "tokenAddress", + "value": "{{WETH}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/get-weth", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "get-weth" + ] + } + }, + "response": [] + }, + { + "name": "eth/poll", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "txHash", + "value": "{{txHash}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/poll", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "poll" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "balancer", + "item": [ + { + "name": "eth/balancer", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "balancer" + ] + } + }, + "response": [] + }, + { + "name": "eth/balancer/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer/gas-limit", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "balancer", + "gas-limit" + ] + } + }, + "response": [] + }, + { + "name": "eth/balancer/start", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "BAT", + "type": "text" + }, + { + "key": "quote", + "value": "dai", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "approvalAmount", + "value": "1", + "type": "text", + "disabled": true + }, + { + "key": "gasPrice", + "value": "50", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer/start", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "balancer", + "start" + ] + } + }, + "response": [] + }, + { + "name": "eth/balancer/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "BAT", + "type": "text" + }, + { + "key": "quote", + "value": "dai", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer/price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "balancer", + "price" + ] + } + }, + "response": [] + }, + { + "name": "eth/balancer/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "BAT", + "type": "text" + }, + { + "key": "quote", + "value": "USDC", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "limitPrice", + "value": "0.19767217120251", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "side", + "value": "sell", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer/trade", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "balancer", + "trade" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + }, + { + "name": "uniswap", + "item": [ + { + "name": "eth/uniswap", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/gas-limit", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "gas-limit" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/start", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "WETH", + "type": "text" + }, + { + "key": "quote", + "value": "USDC", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "approvalAmount", + "value": "1", + "type": "text", + "disabled": true + }, + { + "key": "gasPrice", + "value": "50", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/start", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "start" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "WETH", + "type": "text" + }, + { + "key": "quote", + "value": "DAI", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "price" + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "BAT", + "type": "text" + }, + { + "key": "quote", + "value": "DAI", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "limitPrice", + "value": "0.19767217120251", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "side", + "value": "sell", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/trade", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "eth", + "uniswap", + "trade" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "terra", + "item": [ + { + "name": "terra", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "address", + "value": "{{address}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/terra", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "terra" + ] + } + }, + "response": [] + }, + { + "name": "terra/balances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "address", + "value": "{{terraWalletAddress}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/terra/balances", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "terra", + "balances" + ] + } + }, + "response": [] + }, + { + "name": "terra/start", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "LUNA", + "type": "text" + }, + { + "key": "quote", + "value": "UST", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/start", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "terra", + "start" + ] + } + }, + "response": [] + }, + { + "name": "terra/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "UST", + "type": "text" + }, + { + "key": "quote", + "value": "KRT", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/price", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "terra", + "price" + ] + } + }, + "response": [] + }, + { + "name": "terra/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "UST", + "type": "text" + }, + { + "key": "quote", + "value": "KRT", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{terraSeeds}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/trade", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "terra", + "trade" + ] + } + }, + "response": [] + } + ] + } + ] + }, + { + "name": "/api", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/api", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "api" + ] + } + }, + "response": [] + }, + { + "name": "/", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/", + "protocol": "https", + "host": [ + "localhost" + ], + "port": "{{port}}", + "path": [ + "" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/test/postman/v2/Gateway.postman_environment.json b/test/postman/v2/Gateway.postman_environment.json new file mode 100644 index 0000000..834026f --- /dev/null +++ b/test/postman/v2/Gateway.postman_environment.json @@ -0,0 +1,34 @@ +{ + "id": "4436d04a-e8eb-451b-b7ef-851b171508e8", + "name": "Gateway", + "values": [ + { + "key": "port", + "value": "5000", + "enabled": true + }, + { + "key": "privateKey", + "value": "myprivatekey", + "enabled": true + }, + { + "key": "txHash", + "value": "transactionhash", + "enabled": true + }, + { + "key": "terraWalletAddress", + "value": "terrawalletaddress", + "enabled": true + }, + { + "key": "terraSeeds", + "value": "terraseeds", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2021-01-30T13:04:21.323Z", + "_postman_exported_using": "Postman/8.0.3" +} \ No newline at end of file diff --git a/test/ssl-scripts.sh b/test/ssl-scripts.sh new file mode 100755 index 0000000..316f2ae --- /dev/null +++ b/test/ssl-scripts.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +##### Server Ceritification Creation ##### +########################################## + +# CA configuration file: ca.cnf + +# create a new certificate authority using this configuration. +# we now have our certificate authority in ca_key.pem and ca_cert.pem +openssl req -new -x509 -days 9999 -config ./conf/ca.cnf -keyout ../certs/ca_key.pem -out ../certs/ca_cert.pem + +# generate a private key for the server. +openssl genrsa -out ../certs/server_key.pem 4096 + +# generate a certificate signing request +openssl req -new -config ./conf/server.cnf -key ../certs/server_key.pem -out ../certs/server_csr.pem + +# sign the request. +openssl x509 -req -extfile ./conf/server.cnf -days 999 -passin "pass:password" -in ../certs/server_csr.pem -CA ../certs/ca_cert.pem -CAkey ../certs/ca_key.pem -CAcreateserial -out ../certs/server_cert.pem + + +##### Client Ceritification Creation ##### +########################################## + +# create client key +openssl genrsa -out ../certs/client_key.pem 4096 + +# create certificate signing requests. +openssl req -new -config ./conf/client.cnf -key ../certs/client_key.pem -out ../certs/client_csr.pem + +# sign new client certs. +openssl x509 -req -extfile ./conf/client.cnf -days 999 -passin "pass:password" -in ../certs/client_csr.pem -CA ../certs/ca_cert.pem -CAkey ../certs/ca_key.pem -CAcreateserial -out ../certs/client_cert.pem + +# verify our certs +echo +echo "verifying server certs" +echo +openssl verify -CAfile ../certs/ca_cert.pem ../certs/server_cert.pem +echo +echo "verifying client certs" +openssl verify -CAfile ../certs/ca_cert.pem ../certs/client_cert.pem +echo + + +echo +echo "note: restart node server to load new certs" +echo + +# test after restarting node server +# use -v to see details in verbose mode +# curl --insecure --key ../certs/client_key.pem --cert ../certs/client_cert.pem https://localhost:5000/api +# curl --insecure --key ../certs/client_key.pem --cert ../certs/client_cert.pem https://localhost:5000/terra +# curl --insecure --key ../certs/client_key.pem --cert ../certs/client_cert.pem https://localhost:5000/balancer + From 0eab173273022fbfd1e6dadd766a4bd32dce80e2 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 31 May 2021 21:40:17 +0100 Subject: [PATCH 18/31] update config manager and gitignore files --- .gitignore | 2 +- conf/global_conf.yml.example | 84 +++++++++++++++++++++++++++ src/services/configuration_manager.js | 5 ++ test/conf/ca.cnf | 25 ++++++++ test/conf/client.cnf | 13 +++++ test/conf/server.cnf | 13 +++++ 6 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 conf/global_conf.yml.example create mode 100644 test/conf/ca.cnf create mode 100644 test/conf/client.cnf create mode 100644 test/conf/server.cnf diff --git a/.gitignore b/.gitignore index 8f2de05..c5a466d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ Desktop.ini .idea # Configuration files -*conf/ +conf/* # except the example conf/global_conf.yml.example !conf/global_conf.yml.example diff --git a/conf/global_conf.yml.example b/conf/global_conf.yml.example new file mode 100644 index 0000000..b8c262a --- /dev/null +++ b/conf/global_conf.yml.example @@ -0,0 +1,84 @@ +CORE: + APPNAME: Hummingbot Gateway API + NODE_ENV: dev + PORT: 5000 + + # use only if ip whitelist is required for local or docker instance + # note that docker instance does not use 127.0.0.1 address + # ipv6 format for locahost ["::ffff:127.0.0.1", "::ffff:1", "fe80::1", "::1"] + IP_WHITELIST: + +HUMMINGBOT_INSTANCE_ID: + +# Celo + +# Terra +# - mainnet: https://lcd.terra.dev +# - mainnet chain: columbus-4 +# - testnet: https://tequila-lcd.terra.dev +# - testnet chain: tequila-0004 +TERRA_LCD_URL: +TERRA_CHAIN: + +# Ethereum +# - chain: mainnet, kovan, etc +# - rpc url: infura or other rpc url +# - token list: erc20 token list source (ref: https://tokenlists.org/) +ETHEREUM_CHAIN: +ETHEREUM_RPC_URL: https://{chain}.infura.io/v3/{api_key} +ETHEREUM_TOKEN_LIST_URL: https://wispy-bird-88a7.uniswap.workers.dev/?url=http://tokens.1inch.eth.link + +# Balancer +# subgraph_chain +# Reference: https://docs.balancer.finance/sor/development#subgraph +# - mainnet: balancer +# - kovan: balancer-kovan +# Note: REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor +REACT_APP_SUBGRAPH_URL: https://api.thegraph.com/subgraphs/name/balancer-labs/{subgraph_chain} + +# exchange_proxy: +# Reference: https://docs.balancer.finance/smart-contracts/addresses +# - mainnet: 0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21 +# - kovan: 0x4e67bf5bD28Dd4b570FBAFe11D0633eCbA2754Ec +EXCHANGE_PROXY: + +# Uniswap +# Reference: https://uniswap.org/docs/v2/smart-contracts/router02/ +# UniswapV2Router02 is deployed at 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets. +# It was built from commit 6961711. +UNISWAP_ROUTER: 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D +# allowed slippage for swap transactions +UNISWAP_ALLOWED_SLIPPAGE: 1.5 +# restrict updating pairs that have no reserves or failed for 5 minutes +UNISWAP_NO_RESERVE_CHECK_INTERVAL: 300000 +# cache info about pair for 1 second +UNISWAP_PAIRS_CACHE_TIME: 1000 + +# cert +CERT_PATH: +CERT_PASSPHRASE: + +# logs +# default to ./logs if path is not set +LOG_PATH: ./logs + +# GMT offset for logging (alpine docker image default to UTC timezone) +# -0800, -0500, +0200, +0800 +GMT_OFFSET: +0800 + +# EthGasStation +# API key for defipulse.com gas station API +# Gas level you want to use for Ethereum transactions (fast, fastest, safeLow, average) +ENABLE_ETH_GAS_STATION: true +ETH_GAS_STATION_API_KEY: +ETH_GAS_STATION_GAS_LEVEL: fast +ETH_GAS_STATION_REFRESH_TIME: 60 +MANUAL_GAS_PRICE: 100 + +# Balancer Config +BALANCER_MAX_SWAPS: 4 + + +# Perpetual Finance Provider URL +# default: https://dai.poa.network , https://rpc.xdaichain.com, etc +XDAI_PROVIDER: diff --git a/src/services/configuration_manager.js b/src/services/configuration_manager.js index a8b901a..26a6fcd 100644 --- a/src/services/configuration_manager.js +++ b/src/services/configuration_manager.js @@ -9,7 +9,12 @@ const GlobalConfigFilePath = "./conf/global_conf.yml" export default class ConfigurationManager { constructor () { + try{ this.globalConfFile = fs.readFileSync(GlobalConfigFilePath, 'utf8') + } catch (err) { + fs.copyFileSync(GlobalConfigFilePath + ".example", GlobalConfigFilePath) + this.globalConfFile = fs.readFileSync(GlobalConfigFilePath, 'utf8') + } this.configs = YAML.parseDocument(this.globalConfFile) this.fileWatcher() } diff --git a/test/conf/ca.cnf b/test/conf/ca.cnf new file mode 100644 index 0000000..d415734 --- /dev/null +++ b/test/conf/ca.cnf @@ -0,0 +1,25 @@ +[ ca ] +default_ca = CA_default + +[ CA_default ] +serial = ca-serial +crl = ca-crl.pem +database = ca-database.txt +name_opt = CA_default +cert_opt = CA_default +default_crl_days = 365 +default_md = md5 + +[ req ] +default_bits = 4096 +days = 365 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no +output_password = password + +[ req_distinguished_name ] +CN = ca + +[ req_attributes ] +challengePassword = test diff --git a/test/conf/client.cnf b/test/conf/client.cnf new file mode 100644 index 0000000..4bf4921 --- /dev/null +++ b/test/conf/client.cnf @@ -0,0 +1,13 @@ +[ req ] +default_bits = 4096 +days = 365 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no + +[ req_distinguished_name ] +O = Hummingbot +CN = client + +[ req_attributes ] +challengePassword = password diff --git a/test/conf/server.cnf b/test/conf/server.cnf new file mode 100644 index 0000000..0dd2c3a --- /dev/null +++ b/test/conf/server.cnf @@ -0,0 +1,13 @@ +[ req ] +default_bits = 4096 +days = 365 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no + +[ req_distinguished_name ] +O = Hummingbot +CN = localhost + +[ req_attributes ] +challengePassword = password From 239f81292c7af4fcb8aefa44fa0ffcbe269c39ba Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 31 May 2021 21:43:31 +0100 Subject: [PATCH 19/31] cleanup unused yml file --- env.yaml | 87 -------------------------------------------------------- 1 file changed, 87 deletions(-) delete mode 100644 env.yaml diff --git a/env.yaml b/env.yaml deleted file mode 100644 index fbb28a9..0000000 --- a/env.yaml +++ /dev/null @@ -1,87 +0,0 @@ -APPNAME: Hummingbot Gateway API -NODE_ENV: dev -PORT: 5000 - -# use only if ip whitelist is required for local or docker instance -# note that docker instance does not use 127.0.0.1 address -# ipv6 format for locahost ["::ffff:127.0.0.1", "::ffff:1", "fe80::1", "::1"] -IP_WHITELIST: - -HUMMINGBOT_INSTANCE_ID: {client_id} - -# Celo - -# Terra -# - mainnet: https://lcd.terra.dev -# - mainnet chain: columbus-4 -# - testnet: https://tequila-lcd.terra.dev -# - testnet chain: tequila-0004 -TERRA_LCD_URL: {testnet_lcd_url} -TERRA_CHAIN: {testnet_chain_id} - -# Ethereum -# - chain: mainnet, kovan, etc -# - rpc url: infura or other rpc url -# - token list: erc20 token list source (ref: https://tokenlists.org/) -ETHEREUM_CHAIN: kovan -# ETHEREUM_RPC_URL: https://mainnet.infura.io/v3/117bfd0769f54bd2b91f50d2b1c19f9a -ETHEREUM_RPC_URL: https://kovan.infura.io/v3/117bfd0769f54bd2b91f50d2b1c19f9a -ETHEREUM_TOKEN_LIST_URL: https://wispy-bird-88a7.uniswap.workers.dev/?url=http://tokens.1inch.eth.link - -# Balancer -# subgraph_chain -# Reference: https://docs.balancer.finance/sor/development#subgraph -# - mainnet: balancer -# - kovan: balancer-kovan -# Note: REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor -REACT_APP_SUBGRAPH_URL: https://api.thegraph.com/subgraphs/name/balancer-labs/{subgraph_chain} - -# exchange_proxy: -# Reference: https://docs.balancer.finance/smart-contracts/addresses -# - mainnet: 0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21 -# - kovan: 0x4e67bf5bD28Dd4b570FBAFe11D0633eCbA2754Ec -EXCHANGE_PROXY: "0x3E66B66Fd1d0b02fDa6C811Da9E0547970DB2f21" - -# Uniswap -# Reference: https://uniswap.org/docs/v2/smart-contracts/router02/ -# UniswapV2Router02 is deployed at 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets. -# It was built from commit 6961711. -UNISWAP_ROUTER: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D" -UNISWAP_V3_CORE: "0x1F98431c8aD98523631AE4a59f267346ea31F984" -UNISWAP_V3_ROUTER: "0xE592427A0AEce92De3Edee1F18E0157C05861564" -UNISWAP_V3_NFT_MANAGER: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88" -# allowed slippage for swap transactions -UNISWAP_ALLOWED_SLIPPAGE: 1.5 -# restrict updating pairs that have no reserves or failed for 5 minutes -uNISWAP_NO_RESERVE_CHECK_INTERVALL: 300011 -# cache info about pair for 1 second -UNISWAP_PAIRS_CACHE_TIME: 1000 - -# cert -CERT_PATH: /home/vic/hummingbot/certs/ -CERT_PASSPHRASE: a - -# logs -# default to ./logs if path is not set -# LOG_PATH: /Users/hbot/hummingbot_files/hummingbot_logs - -# GMT offset for logging (alpine docker image default to UTC timezone) -# -0800, -0500, +0200, +0800 -GMT_OFFSET: "+0800" - -# EthGasStation -# API key for defipulse.com gas station API -# Gas level you want to use for Ethereum transactions (fast, fastest, safeLow, average) -ENABLE_ETH_GAS_STATION: true -ETH_GAS_STATION_API_KEY: {apikey} -ETH_GAS_STATION_GAS_LEVEL: fast -ETH_GAS_STATION_REFRESH_TIME: 60 -MANUAL_GAS_PRICE: 100 - -# Balancer Config -BALANCER_MAX_SWAPS: 4 - - -# Perpetual Finance Provider URL -# default: https://dai.poa.network , https://rpc.xdaichain.com, etc -XDAI_PROVIDER: https://xdai.poanetwork.dev From ee38e1a476ef0bbef51e413c73891d6a7a43cb26 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 31 May 2021 21:50:23 +0100 Subject: [PATCH 20/31] add function to get core config --- src/app.js | 2 +- src/services/configuration_manager.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/app.js b/src/app.js index 87bebf0..24b216e 100644 --- a/src/app.js +++ b/src/app.js @@ -26,7 +26,7 @@ const app = express(); // https://www.npmjs.com/package/helmet app.use(helmet()); -const ipWhitelist = globalConfig.getConfig("IP_WHITELIST") +const ipWhitelist = globalConfig.getCoreConfig("IP_WHITELIST") if (ipWhitelist) { app.use(IpFilter(JSON.parse(ipWhitelist), { mode: 'allow' })) } diff --git a/src/services/configuration_manager.js b/src/services/configuration_manager.js index 26a6fcd..5985463 100644 --- a/src/services/configuration_manager.js +++ b/src/services/configuration_manager.js @@ -48,6 +48,10 @@ export default class ConfigurationManager { return this.configs.get(key) } + getCoreConfig(key) { + return this.configs.get('CORE').get(key) + } + fileWatcher() { fs.watchFile(GlobalConfigFilePath, { persistent: true, interval: 1000 }, (curr, prev) => { if (prev.mtime !== curr.mtime) { From 0aa4c122c772f7f187c3488100f55ce9ada586d1 Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 31 May 2021 22:07:01 +0100 Subject: [PATCH 21/31] fix convertion of port number --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 53787d4..eaba28e 100644 --- a/src/index.js +++ b/src/index.js @@ -11,7 +11,7 @@ import { logger } from './services/logger' const globalConfig = require('./services/configuration_manager').configManagerInstance.readAllConfigs() const env = globalConfig.CORE.NODE_ENV -const port = int(globalConfig.CORE.PORT) +const port = globalConfig.CORE.PORT const certPassphrase = globalConfig.CERT_PASSPHRASE const ethereumChain = globalConfig.ETHEREUM_CHAIN const terraChain = globalConfig.TERRA_CHAIN From 4eca588f800c7f5c014897a0beed9f1bcb254099 Mon Sep 17 00:00:00 2001 From: vic-en Date: Thu, 3 Jun 2021 10:24:14 +0100 Subject: [PATCH 22/31] update config and docker files --- .dockerignore | 10 +++++----- Dockerfile | 4 ++-- conf/global_conf.yml.example | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.dockerignore b/.dockerignore index cd75aae..77bd0b9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,11 +2,11 @@ node_modules npm-debug.log .git -# Environment files -*.env -*.env.* -# except the example .env.example -!.env.example + +# Configuration files +conf/* +# except the example conf/global_conf.yml.example +!conf/global_conf.yml.example # Gateway API files *.pem diff --git a/Dockerfile b/Dockerfile index 47d8c7c..1d5240d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:10.22.0-alpine +FROM node:12.13.0-alpine # Add timezone database RUN apk add --no-cache tzdata @@ -31,4 +31,4 @@ RUN touch .env EXPOSE 5000 -CMD ["yarn", "run", "start"] \ No newline at end of file +CMD ["yarn", "run", "start"] diff --git a/conf/global_conf.yml.example b/conf/global_conf.yml.example index b8c262a..8a67df0 100644 --- a/conf/global_conf.yml.example +++ b/conf/global_conf.yml.example @@ -25,7 +25,7 @@ TERRA_CHAIN: # - rpc url: infura or other rpc url # - token list: erc20 token list source (ref: https://tokenlists.org/) ETHEREUM_CHAIN: -ETHEREUM_RPC_URL: https://{chain}.infura.io/v3/{api_key} +ETHEREUM_RPC_URL: "https://{chain}.infura.io/v3/{api_key}" ETHEREUM_TOKEN_LIST_URL: https://wispy-bird-88a7.uniswap.workers.dev/?url=http://tokens.1inch.eth.link # Balancer @@ -46,7 +46,7 @@ EXCHANGE_PROXY: # Reference: https://uniswap.org/docs/v2/smart-contracts/router02/ # UniswapV2Router02 is deployed at 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets. # It was built from commit 6961711. -UNISWAP_ROUTER: 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D +UNISWAP_ROUTER: # allowed slippage for swap transactions UNISWAP_ALLOWED_SLIPPAGE: 1.5 # restrict updating pairs that have no reserves or failed for 5 minutes From af8a899c50fbeed28edafc89a9d08f4bcfa910b7 Mon Sep 17 00:00:00 2001 From: vic-en Date: Thu, 3 Jun 2021 11:45:49 +0100 Subject: [PATCH 23/31] update uniswap v3 to use new configuration --- src/routes/uniswap_v3.route.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js index f252b33..dfcaddf 100644 --- a/src/routes/uniswap_v3.route.js +++ b/src/routes/uniswap_v3.route.js @@ -8,12 +8,12 @@ import Ethereum from '../services/eth'; import UniswapV3 from '../services/uniswap_v3'; import Fees from '../services/fees'; -require('dotenv').config(); +const globalConfig = require('../services/configuration_manager').configManagerInstance const debug = require('debug')('router'); const router = express.Router(); -const eth = new Ethereum(process.env.ETHEREUM_CHAIN); -const uniswap = new UniswapV3(process.env.ETHEREUM_CHAIN); +const eth = new Ethereum(globalConfig.getConfig("ETHEREUM_CHAIN")); +const uniswap = new UniswapV3(globalConfig.getConfig("ETHEREUM_CHAIN")); const fees = new Fees(); From ad859e55fc5a788e0f8bb85a4432879ed91cf4e3 Mon Sep 17 00:00:00 2001 From: james-hummingbot Date: Thu, 3 Jun 2021 13:18:06 +0200 Subject: [PATCH 24/31] Apply simplified lint rules to all files and make eslint a part of the precommit --- .eslintrc.js | 33 +- package.json | 6 +- src/app.js | 38 +- src/index.js | 78 +- src/routes/balancer.route.js | 306 +-- src/routes/celo.route.js | 272 +- src/routes/eth.route.js | 377 ++- src/routes/index.route.js | 2 +- src/routes/perpetual_finance.route.js | 474 ++-- src/routes/terra.route.js | 207 +- src/routes/uniswap.route.js | 309 ++- src/services/access.js | 25 +- src/services/balancer.js | 191 +- src/services/eth.js | 168 +- src/services/fees.js | 57 +- src/services/logger.js | 39 +- src/services/perpetual_finance.js | 346 ++- src/services/terra.js | 355 +-- src/services/uniswap.js | 209 +- src/services/utils.js | 93 +- yarn.lock | 3443 +++++++++++++------------ 21 files changed, 3641 insertions(+), 3387 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 8156b59..96a7ca9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,14 +1,27 @@ module.exports = { - extends: 'standard', + extends: 'airbnb-base', + env: { + node: true, + }, rules: { - // disable semicolon check - semi: 'off', - - // override default options for rules from base configurations - 'comma-dangle': 'off', - - // disable rules from base configurations + camelcase: 'off', + 'consistent-return': 'off', + 'class-methods-use-this': 'off', + 'guard-for-in': 'off', + 'import/prefer-default-export': 'off', + 'max-len': 'off', + 'no-await-in-loop': 'off', + 'no-case-declarations': 'off', 'no-console': 'off', - 'no-multi-spaces': 'off', - } + 'no-mixed-operators': 'off', + 'no-plusplus': 'off', + 'no-prototype-builtins': 'off', + 'no-restricted-syntax': 'off', + 'no-return-assign': 'off', + 'no-unused-expressions': 'off', + 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + 'no-underscore-dangle': 'off', + 'prefer-destructuring': 'off', + radix: 'off', + }, }; diff --git a/package.json b/package.json index 817ee0d..40b9c09 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "start": "babel-node src/index.js", "dev": "nodemon --exec babel-node src/index.js", "debug": "DEBUG=*router nodemon --exec babel-node src/index.js", + "lint": "node_modules/.bin/eslint src --format table", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { @@ -40,9 +41,10 @@ "@babel/core": "^7.11.6", "@babel/node": "^7.10.5", "@babel/preset-env": "^7.11.5", - "eslint": "^7.10.0", + "eslint": "^7.27.0", + "eslint-config-airbnb-base": "^14.2.1", "eslint-config-standard": "^14.1.1", - "eslint-plugin-import": "^2.22.1", + "eslint-plugin-import": "^2.23.3", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", diff --git a/src/app.js b/src/app.js index 647b14f..81ff332 100644 --- a/src/app.js +++ b/src/app.js @@ -1,20 +1,20 @@ import dotenv from 'dotenv'; -import bodyParser from 'body-parser' -import express from 'express' -import helmet from 'helmet' +import bodyParser from 'body-parser'; +import express from 'express'; +import helmet from 'helmet'; +import { IpFilter } from 'express-ipfilter'; import { statusMessages } from './services/utils'; import { validateAccess } from './services/access'; -import { IpFilter } from 'express-ipfilter' import { logger } from './services/logger'; // Routes -import apiRoutes from './routes/index.route' -import balancerRoutes from './routes/balancer.route' +import apiRoutes from './routes/index.route'; +import balancerRoutes from './routes/balancer.route'; // import celoRoutes from './routes/celo.route' -import ethRoutes from './routes/eth.route' -import terraRoutes from './routes/terra.route' -import uniswapRoutes from './routes/uniswap.route' -import perpFiRoutes from './routes/perpetual_finance.route' +import ethRoutes from './routes/eth.route'; +import terraRoutes from './routes/terra.route'; +import uniswapRoutes from './routes/uniswap.route'; +import perpFiRoutes from './routes/perpetual_finance.route'; // terminate if environment not found const result = dotenv.config(); @@ -33,12 +33,12 @@ app.use(helmet()); const ipWhitelist = process.env.IP_WHITELIST; if (ipWhitelist) { - app.use(IpFilter(JSON.parse(ipWhitelist), { mode: 'allow' })) + app.use(IpFilter(JSON.parse(ipWhitelist), { mode: 'allow' })); } app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); -app.use(validateAccess) +app.use(validateAccess); // mount routes to specific path app.use('/api', apiRoutes); @@ -49,19 +49,19 @@ app.use('/terra', terraRoutes); app.use('/perpfi', perpFiRoutes); // app.use('/celo', celoRoutes); -app.get('/', (req, res, next) => { - res.send('ok') -}) +app.get('/', (req, res, _next) => { + res.send('ok'); +}); /** * Catch all 404 response when routes are not found */ -app.use((req, res, next) => { - const message = `${statusMessages.page_not_found} at ${req.originalUrl}` - logger.error(message) +app.use((req, res, _next) => { + const message = `${statusMessages.page_not_found} at ${req.originalUrl}`; + logger.error(message); res.status(404).send({ error: 'Page not found', - message: message + message, }); }); diff --git a/src/index.js b/src/index.js index 957acc3..4e977dd 100644 --- a/src/index.js +++ b/src/index.js @@ -1,13 +1,13 @@ #!/usr/bin/env node // absolute imports -import https from 'https' -import dotenv from 'dotenv' -import fs from 'fs' +import https from 'https'; +import dotenv from 'dotenv'; +import fs from 'fs'; // relative imports -import app from './app' -import { logger } from './services/logger' +import app from './app'; +import { logger } from './services/logger'; // terminate if environment not found const result = dotenv.config(); @@ -16,22 +16,22 @@ if (result.error) { process.exit(1); } -const env = process.env.NODE_ENV -const port = process.env.PORT -const certPassphrase = process.env.CERT_PASSPHRASE -const ethereumChain = process.env.ETHEREUM_CHAIN -const terraChain = process.env.TERRA_CHAIN -let certPath = process.env.CERT_PATH +const env = process.env.NODE_ENV; +const port = process.env.PORT; +const certPassphrase = process.env.CERT_PASSPHRASE; +const ethereumChain = process.env.ETHEREUM_CHAIN; +const terraChain = process.env.TERRA_CHAIN; +let certPath = process.env.CERT_PATH; if ((typeof certPath === 'undefined' && certPath == null) || certPath === '') { // assuming it is local development using test script to generate certs - certPath = './certs' + certPath = './certs'; } else { certPath = certPath.replace(/\/$/, ''); } // set app environment -app.set('env', env) +app.set('env', env); const options = { key: fs.readFileSync(certPath.concat('/server_key.pem'), { encoding: 'utf-8' }), cert: fs.readFileSync(certPath.concat('/server_cert.pem'), { encoding: 'utf-8' }), @@ -41,51 +41,53 @@ const options = { rejectUnauthorized: true, // use ca cert created with own key for self-signed ca: [fs.readFileSync(certPath.concat('/ca_cert.pem'), { encoding: 'utf-8' })], - passphrase: certPassphrase + passphrase: certPassphrase, }; -const server = https.createServer(options, app) +const server = https.createServer(options, app); // event listener for "error" event -const onError = error => { +const onError = (error) => { if (error.syscall !== 'listen') { - throw error + throw error; } - const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port + const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': - console.error(bind + ' requires elevated privileges') - process.exit(1) + console.error(`${bind} requires elevated privileges`); + process.exit(1); + break; case 'EADDRINUSE': - console.error(bind + ' is already in use') - process.exit(1) + console.error(`${bind} is already in use`); + process.exit(1); + break; default: - throw error + throw error; } -} +}; // event listener for "listening" event. const onListening = () => { - const addr = server.address() - const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port - console.log('listening on ' + bind) - logger.debug('listening on ' + bind) -} + const addr = server.address(); + const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`; + console.log(`listening on ${bind}`); + logger.debug(`listening on ${bind}`); +}; // listen on provided port, on all network interfaces. -server.listen(port) -server.on('error', onError) -server.on('listening', onListening) +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); const serverConfig = { app: 'gateway-api', - port: port, - ethereumChain: ethereumChain, - terraChain: terraChain -} + port, + ethereumChain, + terraChain, +}; -logger.info(JSON.stringify(serverConfig)) -console.log(serverConfig) +logger.info(JSON.stringify(serverConfig)); +console.log(serverConfig); diff --git a/src/routes/balancer.route.js b/src/routes/balancer.route.js index a27fe5d..358bd9d 100644 --- a/src/routes/balancer.route.js +++ b/src/routes/balancer.route.js @@ -2,26 +2,29 @@ import BigNumber from 'bignumber.js'; import { ethers } from 'ethers'; import express from 'express'; -import { getParamData, latency, reportConnectionError, statusMessages } from '../services/utils'; +import { + getParamData, latency, statusMessages, +} from '../services/utils'; import Ethereum from '../services/eth'; import Balancer from '../services/balancer'; import Fees from '../services/fees'; import { logger } from '../services/logger'; -const debug = require('debug')('router') -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) -const balancer = new Balancer(process.env.ETHEREUM_CHAIN) -const fees = new Fees() +const debug = require('debug')('router'); -const swapMoreThanMaxPriceError = 'Price too high' -const swapLessThanMaxPriceError = 'Price too low' +const router = express.Router(); +const eth = new Ethereum(process.env.ETHEREUM_CHAIN); +const balancer = new Balancer(process.env.ETHEREUM_CHAIN); +const fees = new Fees(); + +const swapMoreThanMaxPriceError = 'Price too high'; +const swapLessThanMaxPriceError = 'Price too low'; const estimateGasLimit = (maxswaps) => { - const gasLimit = balancer.gasBase + maxswaps * balancer.gasPerSwap - return gasLimit -} + const gasLimit = balancer.gasBase + maxswaps * balancer.gasPerSwap; + return gasLimit; +}; router.post('/', async (req, res) => { /* @@ -34,8 +37,8 @@ router.post('/', async (req, res) => { subgraphUrl: balancer.subgraphUrl, connection: true, timestamp: Date.now(), - }) -}) + }); +}); router.post('/gas-limit', async (req, res) => { /* @@ -44,85 +47,84 @@ router.post('/gas-limit', async (req, res) => { "maxSwaps":4 } */ - const paramData = getParamData(req.body) + const paramData = getParamData(req.body); try { - const swaps = paramData.maxSwaps - const maxSwaps = typeof swaps === 'undefined' || parseInt(swaps) === 0 ? balancer.maxSwaps : parseInt(swaps) - const gasLimit = estimateGasLimit(maxSwaps) + const swaps = paramData.maxSwaps; + const maxSwaps = typeof swaps === 'undefined' || parseInt(swaps) === 0 ? balancer.maxSwaps : parseInt(swaps); + const gasLimit = estimateGasLimit(maxSwaps); res.status(200).json({ network: balancer.network, - gasLimit: gasLimit, + gasLimit, timestamp: Date.now(), - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.get('/start', async (req, res) => { - /* + /* POST: /eth/balancer/start x-www-form-urlencoded: { "pairs":'["ETH-USDT", ...]' "gasPrice":30 } */ - const initTime = Date.now() - const paramData = getParamData(req.query) - const pairs = JSON.parse(paramData.pairs) - let gasPrice + const initTime = Date.now(); + const paramData = getParamData(req.query); + const pairs = JSON.parse(paramData.pairs); + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } // get token contract address and cache pools - for (let pair of pairs){ - pair = pair.split("-") - const baseTokenSymbol = pair[0] - const quoteTokenSymbol = pair[1] - const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) + for (let pair of pairs) { + pair = pair.split('-'); + const baseTokenSymbol = pair[0]; + const quoteTokenSymbol = pair[1]; + const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol); // check for valid token symbols if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { - const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol + const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol; res.status(500).json({ error: `Token ${undefinedToken} contract address not found`, message: `Token contract address not found for ${undefinedToken}. Check token list source`, - }) - return + }); + return; } await Promise.allSettled([balancer.fetchPool(baseTokenContractInfo.address, quoteTokenContractInfo.address), - balancer.fetchPool(quoteTokenContractInfo.address, baseTokenContractInfo.address)]) + balancer.fetchPool(quoteTokenContractInfo.address, baseTokenContractInfo.address)]); } - - const gasLimit = estimateGasLimit(balancer.maxSwaps) - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(balancer.maxSwaps); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); const result = { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), success: true, - pairs: pairs, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - } - console.log('Initializing balancer') - res.status(200).json(result) -}) + pairs, + gasPrice, + gasLimit, + gasCost, + }; + console.log('Initializing balancer'); + res.status(200).json(result); +}); router.post('/price', async (req, res) => { /* @@ -134,48 +136,48 @@ router.post('/price', async (req, res) => { "side":buy } */ - const initTime = Date.now() + const initTime = Date.now(); // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body) - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals - const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals - const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) - const maxSwaps = balancer.maxSwaps - const side = paramData.side.toUpperCase() - let gasPrice + const paramData = getParamData(req.body); + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals; + const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals; + const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)); + const maxSwaps = balancer.maxSwaps; + const side = paramData.side.toUpperCase(); + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } try { // fetch the optimal pool mix from balancer-sor const { swaps, expectedAmount } = side === 'BUY' ? await balancer.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset amount, maxSwaps, ) : await balancer.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset amount, maxSwaps, - ) + ); if (swaps != null && expectedAmount != null) { - const gasLimit = estimateGasLimit(swaps.length) - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(swaps.length); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); - const tradeAmount = parseFloat(amount) - const expectedTradeAmount = parseInt(expectedAmount) / quoteDenomMultiplier - const tradePrice = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier + const tradeAmount = parseFloat(amount); + const expectedTradeAmount = parseInt(expectedAmount) / quoteDenomMultiplier; + const tradePrice = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier; const result = { network: balancer.network, @@ -184,32 +186,32 @@ router.post('/price', async (req, res) => { base: baseTokenContractInfo, quote: quoteTokenContractInfo, amount: tradeAmount, - side: side, + side, expectedAmount: expectedTradeAmount, price: tradePrice, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - swaps: swaps, - } - debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) - res.status(200).json(result) + gasPrice, + gasLimit, + gasCost, + swaps, + }; + debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`); + res.status(200).json(result); } else { // no pool available res.status(200).json({ info: statusMessages.no_pool_available, - message: statusMessages.no_pool_available - }) + message: statusMessages.no_pool_available, + }); } } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/trade', async (req, res) => { /* @@ -224,65 +226,65 @@ router.post('/trade', async (req, res) => { "privateKey":{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, balancer.provider) + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, balancer.provider); - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals - const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals - const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals; + const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals; + const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)); - const maxSwaps = balancer.maxSwaps - const side = paramData.side.toUpperCase() + const maxSwaps = balancer.maxSwaps; + const side = paramData.side.toUpperCase(); - let limitPrice + let limitPrice; if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice) + limitPrice = parseFloat(paramData.limitPrice); } - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } try { // fetch the optimal pool mix from balancer-sor const { swaps, expectedAmount } = side === 'BUY' ? await balancer.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset amount, maxSwaps, ) : await balancer.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset amount, maxSwaps, - ) + ); - const gasLimit = estimateGasLimit(swaps.length) - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(swaps.length); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); if (side === 'BUY') { - const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier - logger.info(`Price: ${price.toString()}`) + const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier; + logger.info(`Price: ${price.toString()}`); if (!limitPrice || price <= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await balancer.swapExactOut( wallet, swaps, - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset expectedAmount.toString(), gasPrice, - ) + ); // submit response res.status(200).json({ @@ -293,36 +295,36 @@ router.post('/trade', async (req, res) => { quote: quoteTokenContractInfo, amount: parseFloat(paramData.amount), expectedIn: expectedAmount / quoteDenomMultiplier, - price: price, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, + price, + gasPrice, + gasLimit, + gasCost, txHash: tx.hash, - }) + }); } else { res.status(200).json({ error: swapMoreThanMaxPriceError, - message: `Swap price ${price} exceeds limitPrice ${limitPrice}` - }) - debug(`Swap price ${price} exceeds limitPrice ${limitPrice}`) + message: `Swap price ${price} exceeds limitPrice ${limitPrice}`, + }); + debug(`Swap price ${price} exceeds limitPrice ${limitPrice}`); } } else { // sell - const minAmountOut = limitPrice / amount * baseDenomMultiplier - debug('minAmountOut', minAmountOut) - const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier - logger.info(`Price: ${price.toString()}`) + const minAmountOut = limitPrice / amount * baseDenomMultiplier; + debug('minAmountOut', minAmountOut); + const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier; + logger.info(`Price: ${price.toString()}`); if (!limitPrice || price >= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await balancer.swapExactIn( wallet, swaps, - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset amount.toString(), parseInt(expectedAmount) / quoteDenomMultiplier, gasPrice, - ) + ); // submit response res.status(200).json({ network: balancer.network, @@ -332,29 +334,29 @@ router.post('/trade', async (req, res) => { quote: quoteTokenContractInfo, amount: parseFloat(paramData.amount), expectedOut: expectedAmount / quoteDenomMultiplier, - price: price, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, + price, + gasPrice, + gasLimit, + gasCost, txHash: tx.hash, - }) + }); } else { res.status(200).json({ error: swapLessThanMaxPriceError, - message: `Swap price ${price} lower than limitPrice ${limitPrice}` - }) - debug(`Swap price ${price} lower than limitPrice ${limitPrice}`) + message: `Swap price ${price} lower than limitPrice ${limitPrice}`, + }); + debug(`Swap price ${price} lower than limitPrice ${limitPrice}`); } } } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); export default router; diff --git a/src/routes/celo.route.js b/src/routes/celo.route.js index a5ad910..f305edc 100644 --- a/src/routes/celo.route.js +++ b/src/routes/celo.route.js @@ -1,26 +1,26 @@ -'use strict' +const express = require('express'); -const express = require('express') -const router = express.Router() +const router = express.Router(); const BigNumber = require('bignumber.js'); -const debug = require('debug')('router') -const spawn = require('child_process').spawn +const debug = require('debug')('router'); +const spawn = require('child_process').spawn; -const network = 'celo' -const celocli = 'celocli' -const DENOM_UNIT_MULTIPLIER = BigNumber('1e+18') +const network = 'celo'; +const celocli = 'celocli'; +const DENOM_UNIT_MULTIPLIER = BigNumber('1e+18'); -const hbUtils = require('../services/utils') -const separator = '=>' +const hbUtils = require('../services/utils'); + +const separator = '=>'; router.use((req, res, next) => { - debug('celo route:', Date.now()) - next() -}) + debug('celo route:', Date.now()); + next(); +}); router.get('/', (req, res) => { - res.status(200).send(network) -}) + res.status(200).send(network); +}); router.get('/status', (req, res) => { /* @@ -29,147 +29,143 @@ router.get('/status', (req, res) => { const nodeSync = spawn(celocli, ['node:synced']); - let err_message = [], out_message = [] + const err_message = []; const + out_message = []; - nodeSync.stdout.on( 'data', out => { - out_message.push(out.toString().trim()) - debug('out_message', out_message) - }) + nodeSync.stdout.on('data', (out) => { + out_message.push(out.toString().trim()); + debug('out_message', out_message); + }); - nodeSync.stderr.on( 'data', err => { - err_message.push(err.toString().trim()) - debug('err_message', err_message) - }) + nodeSync.stderr.on('data', (err) => { + err_message.push(err.toString().trim()); + debug('err_message', err_message); + }); - nodeSync.on( 'close', code => { + nodeSync.on('close', (code) => { if (code === 0) { res.status(200).json({ synced: out_message[0].toLowerCase() === 'true', - message: err_message.join('') - }) + message: err_message.join(''), + }); } else { res.status(401).json({ - error: err_message.join('') - }) + error: err_message.join(''), + }); } - }) -}) - + }); +}); router.get('/price', (req, res) => { /* api request format: /price?trading_pair=CELO-CUSD&trade_type=sell&amount=1.2345 */ - const keyFormat = ['trading_pair', 'trade_type', 'amount'] + const keyFormat = ['trading_pair', 'trade_type', 'amount']; - const initTime = Date.now() + const initTime = Date.now(); - const paramData = hbUtils.getParamData(req.query, keyFormat) - const tradingPair = paramData.trading_pair - const tradeType = paramData.trade_type - const requestAmount = paramData.amount - const amount = parseFloat(requestAmount) * DENOM_UNIT_MULTIPLIER - debug('params', req.params) - debug('paramData', paramData) + const paramData = hbUtils.getParamData(req.query, keyFormat); + const tradingPair = paramData.trading_pair; + const requestAmount = paramData.amount; + const amount = parseFloat(requestAmount) * DENOM_UNIT_MULTIPLIER; + debug('params', req.params); + debug('paramData', paramData); - const nodeSync = spawn(celocli, ["exchange:show", "--amount", amount]); + const nodeSync = spawn(celocli, ['exchange:show', '--amount', amount]); - let err_message = [], out_message = [] + const err_message = []; const + out_message = []; - nodeSync.stdout.on( 'data', out => { - out_message.push(out.toString().trim()) - }) + nodeSync.stdout.on('data', (out) => { + out_message.push(out.toString().trim()); + }); - nodeSync.stderr.on( 'data', err => { - err_message.push(err.toString().trim()) - }) + nodeSync.stderr.on('data', (err) => { + err_message.push(err.toString().trim()); + }); - nodeSync.on( 'close', code => { - - let exchange_rates = {} - let price + nodeSync.on('close', (code) => { + const exchange_rates = {}; + let price; if (code === 0) { // extract exchange rate from cli output - out_message.forEach((item, index) => { + out_message.forEach((item, _index) => { if (item.includes(separator)) { - let exchangeInfo = item.split(separator) - let base = exchangeInfo[0].trim().split(' ') - let quote = exchangeInfo[1].trim().split(' ') - let market = [base[1].toUpperCase(), quote[1].toUpperCase()].join('-') - exchange_rates[market] = quote[0]/DENOM_UNIT_MULTIPLIER - debug (exchangeInfo, exchange_rates) + const exchangeInfo = item.split(separator); + const base = exchangeInfo[0].trim().split(' '); + const quote = exchangeInfo[1].trim().split(' '); + const market = [base[1].toUpperCase(), quote[1].toUpperCase()].join('-'); + exchange_rates[market] = quote[0] / DENOM_UNIT_MULTIPLIER; + debug(exchangeInfo, exchange_rates); } - }) + }); - price = exchange_rates[tradingPair] + price = exchange_rates[tradingPair]; const result = Object.assign(paramData, { - price: price, - timestamp: initTime, - latency: hbUtils.latency(initTime, Date.now()), - } - ) - res.status(200).json(result) + price, + timestamp: initTime, + latency: hbUtils.latency(initTime, Date.now()), + }); + res.status(200).json(result); } - }) - -}) + }); +}); router.get('/balance', (req, res) => { /* api request format: /balance?address=0x87A4...b120 */ - const keyFormat = ['address'] - const paramData = hbUtils.getParamData(req.query, keyFormat) - const address = paramData.address - debug(paramData) + const keyFormat = ['address']; + const paramData = hbUtils.getParamData(req.query, keyFormat); + const address = paramData.address; + debug(paramData); - const balance = spawn(celocli, ["account:balance", address]); + const balance = spawn(celocli, ['account:balance', address]); - let err_message = [], out_message = [] - let walletBalances = {} + const err_message = []; const + out_message = []; + const walletBalances = {}; - balance.stdout.on( 'data', out => { - out_message.push(out.toString().trim()) - debug(out_message) - }) + balance.stdout.on('data', (out) => { + out_message.push(out.toString().trim()); + debug(out_message); + }); - balance.stderr.on( 'data', err => { - err_message.push(err.toString().trim()) - debug(err_message) - }) + balance.stderr.on('data', (err) => { + err_message.push(err.toString().trim()); + debug(err_message); + }); - balance.on( 'close', code => { + balance.on('close', (code) => { if (code === 0) { - out_message.forEach((item, index) => { + out_message.forEach((item, _index) => { // key indicator in balance result: "celo", "gold", "lockedcelo", "lockedgold", "usd", "pending" - if (item.toLowerCase().includes( "lockedcelo") || item.toLowerCase().includes("lockedgold")) { - let balanceArray = item.split('\n') + if (item.toLowerCase().includes('lockedcelo') || item.toLowerCase().includes('lockedgold')) { + const balanceArray = item.split('\n'); balanceArray.forEach((x) => { - let keyValue = x.split(':') - walletBalances[keyValue[0].trim()] = keyValue[1].trim()/DENOM_UNIT_MULTIPLIER - } - ) - debug('walletBalances', walletBalances) + const keyValue = x.split(':'); + walletBalances[keyValue[0].trim()] = keyValue[1].trim() / DENOM_UNIT_MULTIPLIER; + }); + debug('walletBalances', walletBalances); } - }) + }); res.status(200).json({ - address: address, + address, balance: walletBalances, - timestamp: Date.now() - }) + timestamp: Date.now(), + }); } else { res.status(401).json({ error: err_message, - }) + }); } - }) -}) - + }); +}); router.post('/unlock', (req, res) => { /* @@ -180,52 +176,53 @@ router.post('/unlock', (req, res) => { "secret": "mysupersecret" } */ - const keyFormat = ['address', 'secret'] - const paramData = hbUtils.getParamData(req.body, keyFormat) - const address = paramData.address - const secret = paramData.secret + const keyFormat = ['address', 'secret']; + const paramData = hbUtils.getParamData(req.body, keyFormat); + const address = paramData.address; + const secret = paramData.secret; - debug(paramData) - debug(req.body) + debug(paramData); + debug(req.body); - const lockStatus = spawn(celocli, ["account:unlock", address, "--password", secret]); + const lockStatus = spawn(celocli, ['account:unlock', address, '--password', secret]); - let err_message = [], out_message = [] + const err_message = []; const + out_message = []; - lockStatus.stdout.on( 'data', out => { - out_message.push(out.toString().trim()) - debug(out_message) - }) + lockStatus.stdout.on('data', (out) => { + out_message.push(out.toString().trim()); + debug(out_message); + }); - lockStatus.stderr.on( 'data', err => { - err_message.push(err.toString().trim()) - debug(err_message) - }) + lockStatus.stderr.on('data', (err) => { + err_message.push(err.toString().trim()); + debug(err_message); + }); - lockStatus.on( 'close', code => { - let unlocked = false + lockStatus.on('close', (code) => { + let unlocked = false; if (code === 0) { if (out_message.length > 0) { - out_message.forEach((item, index) => { + out_message.forEach((item, _index) => { if (item.includes(separator)) { - debug('item', item) + debug('item', item); } - }) + }); } else { - unlocked = true + unlocked = true; } res.status(200).json({ - unlocked: unlocked, + unlocked, message: out_message.join(), - timestamp: Date.now() - }) + timestamp: Date.now(), + }); } else { res.status(401).json({ error: err_message.join(), - }) + }); } - }) -}) + }); +}); router.post('/trade', (req, res) => { /* @@ -238,15 +235,14 @@ router.post('/trade', (req, res) => { "price": 3.512 } */ - const keyFormat = ['trading_pair', 'trade_type', 'amount', 'price'] - const paramData = hbUtils.getParamData(req.body, keyFormat) - debug(paramData) + const keyFormat = ['trading_pair', 'trade_type', 'amount', 'price']; + const paramData = hbUtils.getParamData(req.body, keyFormat); + debug(paramData); // const result = Object.assign(paramData, { // message: 'WIP', // timestamp: Date.now() // }) - res.status(200).json({"status": "WIP"}) -}) - + res.status(200).json({ status: 'WIP' }); +}); -module.exports = router +module.exports = router; diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index 53dfe79..daf02ab 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -6,14 +6,15 @@ import Ethereum from '../services/eth'; import Fees from '../services/fees'; import { logger } from '../services/logger'; -const debug = require('debug')('router') -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) +const debug = require('debug')('router'); + +const router = express.Router(); +const eth = new Ethereum(process.env.ETHEREUM_CHAIN); const spenders = { balancer: process.env.EXCHANGE_PROXY, - uniswap: process.env.UNISWAP_ROUTER -} -const fees = new Fees() + uniswap: process.env.UNISWAP_ROUTER, +}; +const fees = new Fees(); router.post('/', async (req, res) => { /* @@ -24,8 +25,8 @@ router.post('/', async (req, res) => { rpcUrl: eth.provider.connection.url, connection: true, timestamp: Date.now(), - }) -}) + }); +}); router.post('/balances', async (req, res) => { /* @@ -35,65 +36,65 @@ router.post('/balances', async (req, res) => { tokenList:{{tokenList}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } // populate token contract info using token symbol list - const tokenContractList = [] - const tokenList = JSON.parse(paramData.tokenList) - tokenList.forEach(symbol => { - const tokenContractInfo = eth.getERC20TokenAddresses(symbol) - tokenContractList[symbol] = tokenContractInfo + const tokenContractList = []; + const tokenList = JSON.parse(paramData.tokenList); + tokenList.forEach((symbol) => { + const tokenContractInfo = eth.getERC20TokenAddresses(symbol); + tokenContractList[symbol] = tokenContractInfo; }); - const balances = {} - balances.ETH = await eth.getETHBalance(wallet, privateKey) + const balances = {}; + balances.ETH = await eth.getETHBalance(wallet, privateKey); try { Promise.all( - Object.keys(tokenContractList).map(async (symbol, index) => { - if (tokenContractList[symbol] !== undefined) { - const address = tokenContractList[symbol].address - const decimals = tokenContractList[symbol].decimals - balances[symbol] = await eth.getERC20Balance(wallet, address, decimals) - } else { - const err = `Token contract info for ${symbol} not found` - logger.error('Token info not found', { message: err }) - debug(err) - } + Object.keys(tokenContractList).map(async (symbol, _index) => { + if (tokenContractList[symbol] !== undefined) { + const address = tokenContractList[symbol].address; + const decimals = tokenContractList[symbol].decimals; + balances[symbol] = await eth.getERC20Balance(wallet, address, decimals); + } else { + const err = `Token contract info for ${symbol} not found`; + logger.error('Token info not found', { message: err }); + debug(err); } - )).then(() => { - console.log('eth.route - Get Account Balance', { message: JSON.stringify(tokenList) }) - res.status(200).json({ + }), + ).then(() => { + console.log('eth.route - Get Account Balance', { message: JSON.stringify(tokenList) }); + res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances: balances - }) - }) + balances, + }); + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/allowances', async (req, res) => { /* @@ -104,61 +105,60 @@ router.post('/allowances', async (req, res) => { connector:{{connector_name}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const spender = spenders[paramData.connector] - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const spender = spenders[paramData.connector]; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } // populate token contract info using token symbol list - const tokenContractList = [] - const tokenList = JSON.parse(paramData.tokenList) - tokenList.forEach(symbol => { - const tokenContractInfo = eth.getERC20TokenAddresses(symbol) - tokenContractList[symbol] = tokenContractInfo + const tokenContractList = []; + const tokenList = JSON.parse(paramData.tokenList); + tokenList.forEach((symbol) => { + const tokenContractInfo = eth.getERC20TokenAddresses(symbol); + tokenContractList[symbol] = tokenContractInfo; }); - const approvals = {} + const approvals = {}; try { Promise.all( - Object.keys(tokenContractList).map(async (symbol, index) => { - const address = tokenContractList[symbol].address - const decimals = tokenContractList[symbol].decimals - approvals[symbol] = await eth.getERC20Allowance(wallet, spender, address, decimals) - } - )).then(() => { - logger.info('eth.route - Getting allowances', { message: JSON.stringify(tokenList) }) + Object.keys(tokenContractList).map(async (symbol, _index) => { + const address = tokenContractList[symbol].address; + const decimals = tokenContractList[symbol].decimals; + approvals[symbol] = await eth.getERC20Allowance(wallet, spender, address, decimals); + }), + ).then(() => { + logger.info('eth.route - Getting allowances', { message: JSON.stringify(tokenList) }); res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - spender: spender, - approvals: approvals, - }) - } - ) + spender, + approvals, + }); + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/balances-2', async (req, res) => { /* @@ -169,53 +169,52 @@ router.post('/balances-2', async (req, res) => { tokenDecimalList:{{tokenDecimalList}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } - let tokenAddressList + let tokenAddressList; if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(',') + tokenAddressList = paramData.tokenAddressList.split(','); } - let tokenDecimalList + let tokenDecimalList; if (paramData.tokenDecimalList) { - tokenDecimalList = paramData.tokenDecimalList.split(',') + tokenDecimalList = paramData.tokenDecimalList.split(','); } - const balances = {} - balances.ETH = await eth.getETHBalance(wallet, privateKey) + const balances = {}; + balances.ETH = await eth.getETHBalance(wallet, privateKey); try { Promise.all( - tokenAddressList.map(async (value, index) => - balances[value] = await eth.getERC20Balance(wallet, value, tokenDecimalList[index]) - )).then(() => { + tokenAddressList.map(async (value, index) => balances[value] = await eth.getERC20Balance(wallet, value, tokenDecimalList[index])), + ).then(() => { res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances: balances - }) - }) + balances, + }); + }); } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/allowances-2', async (req, res) => { /* @@ -227,55 +226,53 @@ router.post('/allowances-2', async (req, res) => { connector:{{connector_name}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const spender = spenders[paramData.connector] - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const spender = spenders[paramData.connector]; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } - let tokenAddressList + let tokenAddressList; if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(',') + tokenAddressList = paramData.tokenAddressList.split(','); } - let tokenDecimalList + let tokenDecimalList; if (paramData.tokenDecimalList) { - tokenDecimalList = paramData.tokenDecimalList.split(',') + tokenDecimalList = paramData.tokenDecimalList.split(','); } - const approvals = {} + const approvals = {}; try { Promise.all( - tokenAddressList.map(async (value, index) => - approvals[value] = await eth.getERC20Allowance(wallet, spender, value, tokenDecimalList[index]) - )).then(() => { + tokenAddressList.map(async (value, index) => approvals[value] = await eth.getERC20Allowance(wallet, spender, value, tokenDecimalList[index])), + ).then(() => { res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - spender: spender, - approvals: approvals, - }) - } - ) + spender, + approvals, + }); + }); } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/approve', async (req, res) => { /* @@ -288,87 +285,87 @@ router.post('/approve', async (req, res) => { amount:{{amount}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const spender = spenders[paramData.connector] - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const spender = spenders[paramData.connector]; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } - const token = paramData.token - const tokenContractInfo = eth.getERC20TokenAddresses(token) - const tokenAddress = tokenContractInfo.address - const decimals = tokenContractInfo.decimals + const token = paramData.token; + const tokenContractInfo = eth.getERC20TokenAddresses(token); + const tokenAddress = tokenContractInfo.address; + const decimals = tokenContractInfo.decimals; - let amount - paramData.amount ? amount = ethers.utils.parseUnits(paramData.amount, decimals) - : amount = ethers.utils.parseUnits('1000000000', decimals) // approve for 1 billion units if no amount specified - let gasPrice + let amount; + paramData.amount ? amount = ethers.utils.parseUnits(paramData.amount, decimals) + : amount = ethers.utils.parseUnits('1000000000', decimals); // approve for 1 billion units if no amount specified + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } try { // call approve function - const approval = await eth.approveERC20(wallet, spender, tokenAddress, amount, gasPrice) + const approval = await eth.approveERC20(wallet, spender, tokenAddress, amount, gasPrice); // console.log('eth.route - Approving allowance', { message: approval }) // submit response res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - tokenAddress: tokenAddress, - spender: spender, + tokenAddress, + spender, amount: amount / 1e18.toString(), - approval: approval - }) + approval, + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/poll', async (req, res) => { - const initTime = Date.now() - const paramData = getParamData(req.body) - const txHash = paramData.txHash - const txReceipt = await eth.provider.getTransactionReceipt(txHash) - const receipt = {} - const confirmed = txReceipt && txReceipt.blockNumber ? true : false + const initTime = Date.now(); + const paramData = getParamData(req.body); + const txHash = paramData.txHash; + const txReceipt = await eth.provider.getTransactionReceipt(txHash); + const receipt = {}; + const confirmed = !!(txReceipt && txReceipt.blockNumber); if (confirmed) { - receipt.gasUsed = BigNumber.from(txReceipt.gasUsed).toNumber() - receipt.blockNumber = txReceipt.blockNumber - receipt.confirmations = txReceipt.confirmations - receipt.status = txReceipt.status + receipt.gasUsed = BigNumber.from(txReceipt.gasUsed).toNumber(); + receipt.blockNumber = txReceipt.blockNumber; + receipt.confirmations = txReceipt.confirmations; + receipt.status = txReceipt.status; } - logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }) + logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }); res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - txHash: txHash, - confirmed: confirmed, - receipt: receipt, - }) - return txReceipt -}) + txHash, + confirmed, + receipt, + }); + return txReceipt; +}); // Kovan faucet to get test tokens (wip) & weth conversion // router.post('/get-weth', async (req, res) => { diff --git a/src/routes/index.route.js b/src/routes/index.route.js index 1ea698f..fbe93c6 100644 --- a/src/routes/index.route.js +++ b/src/routes/index.route.js @@ -11,6 +11,6 @@ router.get('/', (req, res) => { config: loadConfig(), status: 'ok', }); -}) +}); module.exports = router; diff --git a/src/routes/perpetual_finance.route.js b/src/routes/perpetual_finance.route.js index f16b30e..46eb82a 100644 --- a/src/routes/perpetual_finance.route.js +++ b/src/routes/perpetual_finance.route.js @@ -1,23 +1,15 @@ -import { ethers, BigNumber } from 'ethers'; +import { ethers } from 'ethers'; import express from 'express'; import { getParamData, latency, statusMessages } from '../services/utils'; import { logger } from '../services/logger'; import PerpetualFinance from '../services/perpetual_finance'; -require('dotenv').config() +require('dotenv').config(); -const router = express.Router() -const perpFi = new PerpetualFinance(process.env.ETHEREUM_CHAIN) -setTimeout(perpFi.update_price_loop.bind(perpFi), 2000) - -const getErrorMessage = (err) => { - /* - [WIP] Custom error message based-on string match - */ - let message = err - return message -} +const router = express.Router(); +const perpFi = new PerpetualFinance(process.env.ETHEREUM_CHAIN); +setTimeout(perpFi.update_price_loop.bind(perpFi), 2000); router.get('/', async (req, res) => { /* @@ -29,22 +21,22 @@ router.get('/', async (req, res) => { loadedMetadata: perpFi.loadedMetadata, connection: true, timestamp: Date.now(), - }) -}) + }); +}); router.get('/load-metadata', async (req, res) => { /* GET / */ - const loadedMetadata = await perpFi.load_metadata() + const loadedMetadata = await perpFi.load_metadata(); res.status(200).json({ network: perpFi.network, provider: perpFi.provider.connection.url, - loadedMetadata: loadedMetadata, + loadedMetadata, connection: true, timestamp: Date.now(), - }) -}) + }); +}); router.post('/balances', async (req, res) => { /* @@ -53,41 +45,41 @@ router.post('/balances', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } - const balances = {} - balances["XDAI"] = await perpFi.getXdaiBalance(wallet) - balances["USDC"] = await perpFi.getUSDCBalance(wallet) + const balances = {}; + balances.XDAI = await perpFi.getXdaiBalance(wallet); + balances.USDC = await perpFi.getUSDCBalance(wallet); try { res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances: balances - }) + balances, + }); } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/allowances', async (req, res) => { /* @@ -96,40 +88,40 @@ router.post('/allowances', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } - const approvals = {} - approvals["USDC"] = await perpFi.getAllowance(wallet) + const approvals = {}; + approvals.USDC = await perpFi.getAllowance(wallet); try { - res.status(200).json({ - network: perpFi.network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - approvals: approvals - }) + res.status(200).json({ + network: perpFi.network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + approvals, + }); } catch (err) { - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/approve', async (req, res) => { /* @@ -139,48 +131,48 @@ router.post('/approve', async (req, res) => { amount:{{amount}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let amount - paramData.amount ? amount = paramData.amount - : amount = '1000000000' - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let amount; + paramData.amount ? amount = paramData.amount + : amount = '1000000000'; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } try { // call approve function - const approval = await perpFi.approve(wallet, amount) - logger.info('perpFi.route - Approving allowance') + const approval = await perpFi.approve(wallet, amount); + logger.info('perpFi.route - Approving allowance'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - amount: amount, - approval: approval - }) + amount, + approval, + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/open', async (req, res) => { /* @@ -194,54 +186,54 @@ router.post('/open', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const side = paramData.side - const pair = paramData.pair - const margin = paramData.margin - const leverage = paramData.leverage - const minBaseAssetAmount = paramData.minBaseAssetAmount - console.log(minBaseAssetAmount) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const side = paramData.side; + const pair = paramData.pair; + const margin = paramData.margin; + const leverage = paramData.leverage; + const minBaseAssetAmount = paramData.minBaseAssetAmount; + console.log(minBaseAssetAmount); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } try { // call openPosition function - const tx = await perpFi.openPosition(side, margin, leverage, pair, minBaseAssetAmount, wallet) - logger.info('perpFi.route - Opening position') + const tx = await perpFi.openPosition(side, margin, leverage, pair, minBaseAssetAmount, wallet); + logger.info('perpFi.route - Opening position'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - margin: margin, - side: side, - leverage: leverage, - minBaseAssetAmount: minBaseAssetAmount, - txHash: tx.hash - }) + margin, + side, + leverage, + minBaseAssetAmount, + txHash: tx.hash, + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/close', async (req, res) => { /* @@ -252,48 +244,47 @@ router.post('/close', async (req, res) => { pair:{{pair}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const minimalQuoteAsset = paramData.minimalQuoteAsset - const privateKey = paramData.privateKey - const pair = paramData.pair - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const minimalQuoteAsset = paramData.minimalQuoteAsset; + const privateKey = paramData.privateKey; + const pair = paramData.pair; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } try { // call closePosition function - const tx = await perpFi.closePosition(wallet, pair, minimalQuoteAsset) - logger.info('perpFi.route - Closing position') + const tx = await perpFi.closePosition(wallet, pair, minimalQuoteAsset); + logger.info('perpFi.route - Closing position'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - minimalQuoteAsset: minimalQuoteAsset, - txHash: tx.hash - }) + minimalQuoteAsset, + txHash: tx.hash, + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) - +}); router.post('/position', async (req, res) => { /* @@ -303,45 +294,45 @@ router.post('/position', async (req, res) => { pair:{{pair}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const pair = paramData.pair - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const pair = paramData.pair; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } try { // call getPosition function - const position = await perpFi.getPosition(wallet, pair) - logger.info('perpFi.route - getting active position') + const position = await perpFi.getPosition(wallet, pair); + logger.info('perpFi.route - getting active position'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - position: position - }) + position, + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/margin', async (req, res) => { /* @@ -350,44 +341,44 @@ router.post('/margin', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = 'Error getting wallet' + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = 'Error getting wallet'; res.status(500).json({ error: reason, - message: err - }) - return + message: err, + }); + return; } try { // call getAllBalances function - const allBalances = await perpFi.getActiveMargin(wallet) - logger.info('perpFi.route - Getting all balances') + const allBalances = await perpFi.getActiveMargin(wallet); + logger.info('perpFi.route - Getting all balances'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - margin: allBalances - }) + margin: allBalances, + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/receipt', async (req, res) => { /* @@ -396,29 +387,29 @@ router.post('/receipt', async (req, res) => { txHash:{{txHash}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const txHash = paramData.txHash - const txReceipt = await perpFi.provider.getTransactionReceipt(txHash) - const receipt = {} - const confirmed = txReceipt && txReceipt.blockNumber ? true : false + const initTime = Date.now(); + const paramData = getParamData(req.body); + const txHash = paramData.txHash; + const txReceipt = await perpFi.provider.getTransactionReceipt(txHash); + const receipt = {}; + const confirmed = !!(txReceipt && txReceipt.blockNumber); if (txReceipt !== null) { - receipt.gasUsed = ethers.utils.formatEther(txReceipt.gasUsed) - receipt.blockNumber = txReceipt.blockNumber - receipt.confirmations = txReceipt.confirmations - receipt.status = txReceipt.status + receipt.gasUsed = ethers.utils.formatEther(txReceipt.gasUsed); + receipt.blockNumber = txReceipt.blockNumber; + receipt.confirmations = txReceipt.confirmations; + receipt.status = txReceipt.status; } - logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }) + logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }); res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - txHash: txHash, - confirmed: confirmed, - receipt: receipt, - }) - return txReceipt -}) + txHash, + confirmed, + receipt, + }); + return txReceipt; +}); router.post('/price', async (req, res) => { /* @@ -429,59 +420,58 @@ router.post('/price', async (req, res) => { amount:{{amount}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const side = paramData.side - const pair = paramData.pair - const amount = paramData.amount + const initTime = Date.now(); + const paramData = getParamData(req.body); + const side = paramData.side; + const pair = paramData.pair; + const amount = paramData.amount; try { // call getPrice function - const price = await perpFi.getPrice(side, amount, pair) - logger.info('perpFi.route - Getting price') + const price = await perpFi.getPrice(side, amount, pair); + logger.info('perpFi.route - Getting price'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - side: side, - price: price - }) + side, + price, + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) - +}); router.get('/pairs', async (req, res) => { /* GET */ - const initTime = Date.now() + const initTime = Date.now(); try { res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - pairs: Object.keys(perpFi.amm) - }) + pairs: Object.keys(perpFi.amm), + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/funding', async (req, res) => { /* @@ -490,30 +480,30 @@ router.post('/funding', async (req, res) => { pair:{{pair}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const pair = paramData.pair + const initTime = Date.now(); + const paramData = getParamData(req.body); + const pair = paramData.pair; try { // call getFundingRate function - const fr = await perpFi.getFundingRate(pair) - logger.info('perpFi.route - Getting funding info') + const fr = await perpFi.getFundingRate(pair); + logger.info('perpFi.route - Getting funding info'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - fr: fr - }) + fr, + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); export default router; diff --git a/src/routes/terra.route.js b/src/routes/terra.route.js index f2c64c3..506935f 100644 --- a/src/routes/terra.route.js +++ b/src/routes/terra.route.js @@ -1,80 +1,79 @@ -'use strict' - -import express from 'express' -import { getParamData, latency, reportConnectionError, statusMessages } from '../services/utils'; +import express from 'express'; +import { + getParamData, latency, reportConnectionError, statusMessages, +} from '../services/utils'; import { logger } from '../services/logger'; import Terra from '../services/terra'; -const debug = require('debug')('router') const router = express.Router(); -const terra = new Terra() +const terra = new Terra(); // constants -const network = terra.lcd.config.chainID -const denomUnitMultiplier = terra.denomUnitMultiplier +const network = terra.lcd.config.chainID; +const denomUnitMultiplier = terra.denomUnitMultiplier; router.post('/', async (req, res) => { /* POST / */ res.status(200).json({ - network: network, + network, lcdUrl: terra.lcd.config.URL, gasPrices: terra.lcd.config.gasPrices, gasAdjustment: terra.lcd.config.gasAdjustment, connection: true, - timestamp: Date.now() - }) -}) + timestamp: Date.now(), + }); +}); router.post('/balances', async (req, res) => { /* POST: address:{{address}} */ - const initTime = Date.now() + const initTime = Date.now(); - const paramData = getParamData(req.body) - const address = paramData.address + const paramData = getParamData(req.body); + const address = paramData.address; - let balances = {} + const balances = {}; try { - await terra.lcd.bank.balance(address).then(bal => { + await terra.lcd.bank.balance(address).then((bal) => { bal.toArray().forEach(async (x) => { - const item = x.toData() - const denom = item.denom - const amount = item.amount / denomUnitMultiplier - const symbol = terra.tokens[denom].symbol - balances[symbol] = amount - }) - }) - logger.info('terra.route - Get Account Balance') + const item = x.toData(); + const denom = item.denom; + const amount = item.amount / denomUnitMultiplier; + const symbol = terra.tokens[denom].symbol; + balances[symbol] = amount; + }); + }); + logger.info('terra.route - Get Account Balance'); res.status(200).json({ - network: network, + network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances: balances, - }) + balances, + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let message - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - const isAxiosError = err.isAxiosError + logger.error(req.originalUrl, { message: err }); + let message; + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; + const isAxiosError = err.isAxiosError; if (isAxiosError) { - reason = err.response.status - message = err.response.statusText + reason = err.response.status; + message = err.response.statusText; } else { - message = err + message = err; } res.status(500).json({ error: reason, - message: message - }) + message, + }); } -}) +}); router.post('/start', async (req, res) => { /* @@ -85,21 +84,21 @@ router.post('/start', async (req, res) => { "amount":1 } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const baseTokenSymbol = paramData.base - const quoteTokenSymbol = paramData.quote + const initTime = Date.now(); + const paramData = getParamData(req.body); + const baseTokenSymbol = paramData.base; + const quoteTokenSymbol = paramData.quote; const result = { - network: network, + network, timestamp: initTime, latency: latency(initTime, Date.now()), success: true, base: baseTokenSymbol, quote: quoteTokenSymbol, - } - res.status(200).json(result) -}) + }; + res.status(200).json(result); +}); router.post('/price', async (req, res) => { /* @@ -111,55 +110,55 @@ router.post('/price', async (req, res) => { "amount":1 } */ - const initTime = Date.now() + const initTime = Date.now(); - const paramData = getParamData(req.body) - const baseToken = paramData.base - const quoteToken = paramData.quote - const tradeType = paramData.side.toUpperCase() - const amount = parseFloat(paramData.amount) + const paramData = getParamData(req.body); + const baseToken = paramData.base; + const quoteToken = paramData.quote; + const tradeType = paramData.side.toUpperCase(); + const amount = parseFloat(paramData.amount); - let exchangeRate + let exchangeRate; try { await terra.getSwapRate(baseToken, quoteToken, amount, tradeType).then((rate) => { - exchangeRate = rate + exchangeRate = rate; }).catch((err) => { - reportConnectionError(res, err) - }) + reportConnectionError(res, err); + }); res.status(200).json( { - network: network, + network, timestamp: initTime, latency: latency(initTime, Date.now()), base: baseToken, quote: quoteToken, - amount: amount, - tradeType: tradeType, + amount, + tradeType, price: exchangeRate.price.amount, cost: exchangeRate.cost.amount, txFee: exchangeRate.txFee.amount, - } - ) + }, + ); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let message - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - const isAxiosError = err.isAxiosError + logger.error(req.originalUrl, { message: err }); + let message; + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; + const isAxiosError = err.isAxiosError; if (isAxiosError) { - reason = err.response.status - message = err.response.statusText + reason = err.response.status; + message = err.response.statusText; } else { - message = err + message = err; } res.status(500).json({ error: reason, - message: message - }) + message, + }); } -}) +}); router.post('/trade', async (req, res) => { /* @@ -172,57 +171,57 @@ router.post('/trade', async (req, res) => { "secret": "mysupersecret" } */ - const initTime = Date.now() + const initTime = Date.now(); - const paramData = getParamData(req.body) - const baseToken = paramData.base - const quoteToken = paramData.quote - const tradeType = paramData.side.toUpperCase() - const amount = parseFloat(paramData.amount) - const gasPrice = parseFloat(paramData.gas_price) || terra.lcd.config.gasPrices.uluna - const gasAdjustment = paramData.gas_adjustment || terra.lcd.config.gasAdjustment - const secret = paramData.privateKey + const paramData = getParamData(req.body); + const baseToken = paramData.base; + const quoteToken = paramData.quote; + const tradeType = paramData.side.toUpperCase(); + const amount = parseFloat(paramData.amount); + const gasPrice = parseFloat(paramData.gas_price) || terra.lcd.config.gasPrices.uluna; + const gasAdjustment = paramData.gas_adjustment || terra.lcd.config.gasAdjustment; + const secret = paramData.privateKey; - let tokenSwaps + let tokenSwaps; try { await terra.swapTokens(baseToken, quoteToken, amount, tradeType, gasPrice, gasAdjustment, secret).then((swap) => { - tokenSwaps = swap + tokenSwaps = swap; }).catch((err) => { - reportConnectionError(res, err) - }) + reportConnectionError(res, err); + }); const swapResult = { - network: network, + network, timestamp: initTime, latency: latency(initTime, Date.now()), base: baseToken, - tradeType: tradeType, + tradeType, quote: quoteToken, - amount: amount, - } + amount, + }; Object.assign(swapResult, tokenSwaps); - logger.info(`terra.route - ${tradeType}: ${baseToken}-${quoteToken} - Amount: ${amount}`) + logger.info(`terra.route - ${tradeType}: ${baseToken}-${quoteToken} - Amount: ${amount}`); res.status(200).json( - swapResult - ) + swapResult, + ); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let message - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error - const isAxiosError = err.isAxiosError + logger.error(req.originalUrl, { message: err }); + let message; + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; + const isAxiosError = err.isAxiosError; if (isAxiosError) { - reason = err.response.status - message = err.response.statusText + reason = err.response.status; + message = err.response.statusText; } else { - message = err + message = err; } res.status(500).json({ error: reason, - message: message - }) + message, + }); } -}) +}); module.exports = router; diff --git a/src/routes/uniswap.route.js b/src/routes/uniswap.route.js index 812e0ef..825bfb8 100644 --- a/src/routes/uniswap.route.js +++ b/src/routes/uniswap.route.js @@ -7,39 +7,38 @@ import Ethereum from '../services/eth'; import Uniswap from '../services/uniswap'; import Fees from '../services/fees'; -require('dotenv').config() +require('dotenv').config(); -const debug = require('debug')('router') -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) -const uniswap = new Uniswap(process.env.ETHEREUM_CHAIN) -uniswap.generate_tokens() -setTimeout(uniswap.update_pairs.bind(uniswap), 2000) -const fees = new Fees() +const debug = require('debug')('router'); -const swapMoreThanMaxPriceError = 'Price too high' -const swapLessThanMaxPriceError = 'Price too low' +const router = express.Router(); +const eth = new Ethereum(process.env.ETHEREUM_CHAIN); +const uniswap = new Uniswap(process.env.ETHEREUM_CHAIN); +uniswap.generate_tokens(); +setTimeout(uniswap.update_pairs.bind(uniswap), 2000); +const fees = new Fees(); -const estimateGasLimit = () => { - return uniswap.gasLimit -} +const swapMoreThanMaxPriceError = 'Price too high'; +const swapLessThanMaxPriceError = 'Price too low'; + +const estimateGasLimit = () => uniswap.gasLimit; const getErrorMessage = (err) => { /* [WIP] Custom error message based-on string match */ - let message = err + let message = err; if (err.includes('failed to meet quorum')) { - message = 'Failed to meet quorum in Uniswap' + message = 'Failed to meet quorum in Uniswap'; } else if (err.includes('Invariant failed: ADDRESSES')) { - message = 'Invariant failed: ADDRESSES' + message = 'Invariant failed: ADDRESSES'; } else if (err.includes('"call revert exception')) { - message = statusMessages.no_pool_available + message = statusMessages.no_pool_available; } else if (err.includes('"trade" is read-only')) { - message = statusMessages.no_pool_available + message = statusMessages.no_pool_available; } - return message -} + return message; +}; router.post('/', async (req, res) => { /* @@ -51,31 +50,31 @@ router.post('/', async (req, res) => { uniswap_router: uniswap.router, connection: true, timestamp: Date.now(), - }) -}) + }); +}); router.post('/gas-limit', async (req, res) => { /* POST: /buy-price */ - const gasLimit = estimateGasLimit() + const gasLimit = estimateGasLimit(); try { res.status(200).json({ network: uniswap.network, - gasLimit: gasLimit, + gasLimit, timestamp: Date.now(), - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.get('/start', async (req, res) => { /* @@ -85,52 +84,51 @@ router.get('/start', async (req, res) => { "gasPrice":30 } */ - const initTime = Date.now() - const paramData = getParamData(req.query) - const pairs = JSON.parse(paramData.pairs) - let gasPrice + const initTime = Date.now(); + const paramData = getParamData(req.query); + const pairs = JSON.parse(paramData.pairs); + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } // get token contract address and cache paths - for (let pair of pairs){ - pair = pair.split("-") - const baseTokenSymbol = pair[0] - const quoteTokenSymbol = pair[1] - const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) + for (let pair of pairs) { + pair = pair.split('-'); + const baseTokenSymbol = pair[0]; + const quoteTokenSymbol = pair[1]; + const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol); // check for valid token symbols if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { - const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol + const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol; res.status(500).json({ error: `Token ${undefinedToken} contract address not found`, message: `Token contract address not found for ${undefinedToken}. Check token list source`, - }) - return + }); + return; } - await Promise.allSettled([uniswap.extend_update_pairs([baseTokenContractInfo.address, quoteTokenContractInfo.address])]) + await Promise.allSettled([uniswap.extend_update_pairs([baseTokenContractInfo.address, quoteTokenContractInfo.address])]); } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) - + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); const result = { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), success: true, - pairs: pairs, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - } - res.status(200).json(result) -}) + pairs, + gasPrice, + gasLimit, + gasCost, + }; + res.status(200).json(result); +}); router.post('/trade', async (req, res) => { /* @@ -145,49 +143,49 @@ router.post('/trade', async (req, res) => { "side":{buy|sell} } */ - const initTime = Date.now() + const initTime = Date.now(); // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) - const amount = paramData.amount + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const amount = paramData.amount; - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const side = paramData.side.toUpperCase(); - let limitPrice + let limitPrice; if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice) + limitPrice = parseFloat(paramData.limitPrice); } - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { // fetch the optimal pool mix from uniswap const { trade, expectedAmount } = side === 'BUY' ? await uniswap.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount, ) : await uniswap.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount - ) + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount, + ); if (side === 'BUY') { - const price = trade.executionPrice.invert().toSignificant(8) - logger.info(`uniswap.route - Price: ${price.toString()}`) + const price = trade.executionPrice.invert().toSignificant(8); + logger.info(`uniswap.route - Price: ${price.toString()}`); if (!limitPrice || price <= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await uniswap.swapExactOut( @@ -195,7 +193,7 @@ router.post('/trade', async (req, res) => { trade, baseTokenAddress, gasPrice, - ) + ); // submit response res.status(200).json({ network: uniswap.network, @@ -203,25 +201,25 @@ router.post('/trade', async (req, res) => { latency: latency(initTime, Date.now()), base: baseTokenAddress, quote: quoteTokenAddress, - amount: amount, + amount, expectedIn: expectedAmount.toSignificant(8), - price: price, - gasPrice: gasPrice, - gasLimit, gasLimit, - gasCost, gasCost, + price, + gasPrice, + gasLimit, + gasCost, txHash: tx.hash, - }) + }); } else { res.status(200).json({ error: swapMoreThanMaxPriceError, - message: `Swap price ${price} exceeds limitPrice ${limitPrice}` - }) - logger.info(`uniswap.route - Swap price ${price} exceeds limitPrice ${limitPrice}`) + message: `Swap price ${price} exceeds limitPrice ${limitPrice}`, + }); + logger.info(`uniswap.route - Swap price ${price} exceeds limitPrice ${limitPrice}`); } } else { // sell - const price = trade.executionPrice.toSignificant(8) - logger.info(`Price: ${price.toString()}`) + const price = trade.executionPrice.toSignificant(8); + logger.info(`Price: ${price.toString()}`); if (!limitPrice || price >= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await uniswap.swapExactIn( @@ -229,7 +227,7 @@ router.post('/trade', async (req, res) => { trade, baseTokenAddress, gasPrice, - ) + ); // submit response res.status(200).json({ network: uniswap.network, @@ -240,29 +238,29 @@ router.post('/trade', async (req, res) => { amount: parseFloat(paramData.amount), expectedOut: expectedAmount.toSignificant(8), price: parseFloat(price), - gasPrice: gasPrice, - gasLimit, gasLimit, - gasCost: gasCost, + gasPrice, + gasLimit, + gasCost, txHash: tx.hash, - }) + }); } else { res.status(200).json({ error: swapLessThanMaxPriceError, - message: `Swap price ${price} lower than limitPrice ${limitPrice}` - }) - logger.info(`uniswap.route - Swap price ${price} lower than limitPrice ${limitPrice}`) + message: `Swap price ${price} lower than limitPrice ${limitPrice}`, + }); + logger.info(`uniswap.route - Swap price ${price} lower than limitPrice ${limitPrice}`); } } } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? reason = err.reason : reason = statusMessages.operation_error + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? reason = err.reason : reason = statusMessages.operation_error; res.status(500).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); router.post('/price', async (req, res) => { /* @@ -273,48 +271,47 @@ router.post('/price', async (req, res) => { "amount":1 } */ - const initTime = Date.now() + const initTime = Date.now(); // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body) - const amount = paramData.amount + const paramData = getParamData(req.body); + const amount = paramData.amount; - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() - let gasPrice + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const side = paramData.side.toUpperCase(); + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) - + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { // fetch the optimal pool mix from uniswap const { trade, expectedAmount } = side === 'BUY' ? await uniswap.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount, ) : await uniswap.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount - ) + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount, + ); if (trade !== null && expectedAmount !== null) { const price = side === 'BUY' ? trade.executionPrice.invert().toSignificant(8) - : trade.executionPrice.toSignificant(8) + : trade.executionPrice.toSignificant(8); - const tradeAmount = parseFloat(amount) - const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)) - const tradePrice = parseFloat(price) + const tradeAmount = parseFloat(amount); + const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)); + const tradePrice = parseFloat(price); const result = { network: uniswap.network, @@ -325,43 +322,43 @@ router.post('/price', async (req, res) => { amount: tradeAmount, expectedAmount: expectedTradeAmount, price: tradePrice, - gasPrice: gasPrice, - gasLimit: gasLimit, - gasCost: gasCost, - trade: trade, - } - debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`) - res.status(200).json(result) + gasPrice, + gasLimit, + gasCost, + trade, + }; + debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`); + res.status(200).json(result); } else { // no pool available res.status(200).json({ info: statusMessages.no_pool_available, - message: '' - }) + message: '', + }); } } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - let errCode = 500 + logger.error(req.originalUrl, { message: err }); + let reason; + let errCode = 500; if (Object.keys(err).includes('isInsufficientReservesError')) { - errCode = 200 - reason = statusMessages.insufficient_reserves + ' in ' + side + ' at Uniswap' + errCode = 200; + reason = `${statusMessages.insufficient_reserves} in ${side} at Uniswap`; } else if (Object.getOwnPropertyNames(err).includes('message')) { - reason = getErrorMessage(err.message) + reason = getErrorMessage(err.message); if (reason === statusMessages.no_pool_available) { - errCode = 200 + errCode = 200; res.status(errCode).json({ info: reason, - message: err - }) + message: err, + }); } } else { - err.reason ? reason = err.reason : reason = statusMessages.operation_error + err.reason ? reason = err.reason : reason = statusMessages.operation_error; } res.status(errCode).json({ error: reason, - message: err - }) + message: err, + }); } -}) +}); export default router; diff --git a/src/services/access.js b/src/services/access.js index 708f3aa..cf374b9 100644 --- a/src/services/access.js +++ b/src/services/access.js @@ -4,22 +4,21 @@ import { logger } from './logger'; import { statusMessages } from './utils'; -const debug = require('debug')('router') export const validateAccess = (req, res, next) => { - const cert = req.connection.getPeerCertificate() + const cert = req.connection.getPeerCertificate(); if (req.client.authorized) { - const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress - const method = req.method - const url = req.url - const requestInfo = 'Request from IP: ' + ip + ' ' + method + ' ' + url - console.log(requestInfo) - next() + const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; + const method = req.method; + const url = req.url; + const requestInfo = `Request from IP: ${ip} ${method} ${url}`; + console.log(requestInfo); + next(); } else if (cert.subject) { - logger.error(statusMessages.ssl_cert_invalid) - res.status(403).send({ error: statusMessages.ssl_cert_invalid }) + logger.error(statusMessages.ssl_cert_invalid); + res.status(403).send({ error: statusMessages.ssl_cert_invalid }); } else { - logger.error(statusMessages.ssl_cert_required) - res.status(401).send({ error: statusMessages.ssl_cert_required }) + logger.error(statusMessages.ssl_cert_required); + res.status(401).send({ error: statusMessages.ssl_cert_required }); } -} +}; diff --git a/src/services/balancer.js b/src/services/balancer.js index dc4bb43..a954f21 100644 --- a/src/services/balancer.js +++ b/src/services/balancer.js @@ -1,10 +1,11 @@ -import { logger } from '../services/logger'; -const debug = require('debug')('router') -require('dotenv').config() // DO NOT REMOVE. needed to configure REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor -const sor = require('@balancer-labs/sor') -const BigNumber = require('bignumber.js') -const ethers = require('ethers') -const proxyArtifact = require('../static/ExchangeProxy.json') +import { logger } from './logger'; + +const debug = require('debug')('router'); +require('dotenv').config(); // DO NOT REMOVE. needed to configure REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor +const sor = require('@balancer-labs/sor'); +const BigNumber = require('bignumber.js'); +const ethers = require('ethers'); +const proxyArtifact = require('../static/ExchangeProxy.json'); // constants const MULTI = '0xeefba1e63905ef1d7acba5a8513c70307c1ce441'; @@ -14,16 +15,16 @@ const GAS_BASE = process.env.BALANCER_GAS_BASE || 200688; const GAS_PER_SWAP = process.env.BALANCER_GAS_PER_SWAP || 100000; export default class Balancer { - constructor (network = 'kovan') { - const providerUrl = process.env.ETHEREUM_RPC_URL - this.network = process.env.ETHEREUM_CHAIN - this.provider = new ethers.providers.JsonRpcProvider(providerUrl) - this.subgraphUrl = process.env.REACT_APP_SUBGRAPH_URL - this.gasBase = GAS_BASE - this.gasPerSwap = GAS_PER_SWAP - this.maxSwaps = process.env.BALANCER_MAX_SWAPS || 4 + constructor(network = 'kovan') { + const providerUrl = process.env.ETHEREUM_RPC_URL; + this.network = process.env.ETHEREUM_CHAIN; + this.provider = new ethers.providers.JsonRpcProvider(providerUrl); + this.subgraphUrl = process.env.REACT_APP_SUBGRAPH_URL; + this.gasBase = GAS_BASE; + this.gasPerSwap = GAS_PER_SWAP; + this.maxSwaps = process.env.BALANCER_MAX_SWAPS || 4; this.exchangeProxy = process.env.EXCHANGE_PROXY; - this.cachedPools = [] + this.cachedPools = []; switch (network) { case 'mainnet': @@ -33,132 +34,132 @@ export default class Balancer { this.multiCall = MULTI_KOVAN; break; default: - const err = `Invalid network ${network}` - logger.error(err) - throw Error(err) + const err = `Invalid network ${network}`; + logger.error(err); + throw Error(err); } } - async fetchPool (tokenIn, tokenOut) { - const pools = await sor.getPoolsWithTokens(tokenIn, tokenOut) - this.cachedPools[tokenIn + tokenOut] = pools + async fetchPool(tokenIn, tokenOut) { + const pools = await sor.getPoolsWithTokens(tokenIn, tokenOut); + this.cachedPools[tokenIn + tokenOut] = pools; if (pools.pools.length === 0) { debug('>>> No pools contain the tokens provided.', { message: this.network }); return {}; } - debug(`>>> ${pools.pools.length} Pools Retrieved.`, { message: this.network }) + debug(`>>> ${pools.pools.length} Pools Retrieved.`, { message: this.network }); } - async getCachedPools (tokenIn, tokenOut) { - const cachePools = this.cachedPools[tokenIn + tokenOut].pools - debug(`>>> get cached Pools. ${tokenIn + tokenOut}`, { message: `total pools: ${cachePools.length}` }) - return cachePools + async getCachedPools(tokenIn, tokenOut) { + const cachePools = this.cachedPools[tokenIn + tokenOut].pools; + debug(`>>> get cached Pools. ${tokenIn + tokenOut}`, { message: `total pools: ${cachePools.length}` }); + return cachePools; } - async priceSwapIn (tokenIn, tokenOut, tokenInAmount, maxSwaps = this.maxSwaps) { + async priceSwapIn(tokenIn, tokenOut, tokenInAmount, maxSwaps = this.maxSwaps) { // Fetch all the pools that contain the tokens provided try { // Get current on-chain data about the fetched pools - await this.fetchPool(tokenIn, tokenOut) + await this.fetchPool(tokenIn, tokenOut); - let poolData - const cachedPools = await this.getCachedPools(tokenIn, tokenOut) + let poolData; + const cachedPools = await this.getCachedPools(tokenIn, tokenOut); if (this.network === 'mainnet') { - poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider) + poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider); } else { // Kovan multicall throws an ENS error - poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) + poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut); } // Parse the pools and pass them to smart order outer to get the swaps needed const sorSwaps = sor.smartOrderRouter( - poolData, // balancers: Pool[] - 'swapExactIn', // swapType: string - tokenInAmount, // targetInputAmount: BigNumber - new BigNumber(maxSwaps.toString()), // maxBalancers: number - 0 // costOutputToken: BigNumber - ) - - const swapsFormatted = sor.formatSwapsExactAmountIn(sorSwaps, MAX_UINT, 0) - const expectedAmount = sor.calcTotalOutput(swapsFormatted, poolData) + poolData, // balancers: Pool[] + 'swapExactIn', // swapType: string + tokenInAmount, // targetInputAmount: BigNumber + new BigNumber(maxSwaps.toString()), // maxBalancers: number + 0, // costOutputToken: BigNumber + ); + + const swapsFormatted = sor.formatSwapsExactAmountIn(sorSwaps, MAX_UINT, 0); + const expectedAmount = sor.calcTotalOutput(swapsFormatted, poolData); debug(`Expected Out: ${expectedAmount.toString()} (${tokenOut})`); // Create correct swap format for new proxy - let swaps = []; + const swaps = []; for (let i = 0; i < swapsFormatted.length; i++) { - let swap = { + const swap = { pool: swapsFormatted[i].pool, - tokenIn: tokenIn, - tokenOut: tokenOut, + tokenIn, + tokenOut, swapAmount: swapsFormatted[i].tokenInParam, limitReturnAmount: swapsFormatted[i].tokenOutParam, maxPrice: swapsFormatted[i].maxPrice.toString(), }; swaps.push(swap); } - return { swaps, expectedAmount } + return { swaps, expectedAmount }; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error in swapExactOut' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error in swapExactOut'; + return reason; } } - async priceSwapOut (tokenIn, tokenOut, tokenOutAmount, maxSwaps = this.maxSwaps) { + async priceSwapOut(tokenIn, tokenOut, tokenOutAmount, maxSwaps = this.maxSwaps) { // Fetch all the pools that contain the tokens provided try { // Get current on-chain data about the fetched pools - await this.fetchPool(tokenIn, tokenOut) + await this.fetchPool(tokenIn, tokenOut); - let poolData - const cachedPools = await this.getCachedPools(tokenIn, tokenOut) + let poolData; + const cachedPools = await this.getCachedPools(tokenIn, tokenOut); if (this.network === 'mainnet') { - poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider) + poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider); } else { // Kovan multicall throws an ENS error - poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) + poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut); } // Parse the pools and pass them to smart order outer to get the swaps needed const sorSwaps = sor.smartOrderRouter( - poolData, // balancers: Pool[] - 'swapExactOut', // swapType: string - tokenOutAmount, // targetInputAmount: BigNumber - new BigNumber(maxSwaps.toString()), // maxBalancers: number - 0 // costOutputToken: BigNumber - ) - const swapsFormatted = sor.formatSwapsExactAmountOut(sorSwaps, MAX_UINT, MAX_UINT) - const expectedAmount = sor.calcTotalInput(swapsFormatted, poolData) + poolData, // balancers: Pool[] + 'swapExactOut', // swapType: string + tokenOutAmount, // targetInputAmount: BigNumber + new BigNumber(maxSwaps.toString()), // maxBalancers: number + 0, // costOutputToken: BigNumber + ); + const swapsFormatted = sor.formatSwapsExactAmountOut(sorSwaps, MAX_UINT, MAX_UINT); + const expectedAmount = sor.calcTotalInput(swapsFormatted, poolData); debug(`Expected In: ${expectedAmount.toString()} (${tokenIn})`); // Create correct swap format for new proxy - let swaps = []; + const swaps = []; for (let i = 0; i < swapsFormatted.length; i++) { - let swap = { + const swap = { pool: swapsFormatted[i].pool, - tokenIn: tokenIn, - tokenOut: tokenOut, + tokenIn, + tokenOut, swapAmount: swapsFormatted[i].tokenOutParam, limitReturnAmount: swapsFormatted[i].tokenInParam, maxPrice: swapsFormatted[i].maxPrice.toString(), }; swaps.push(swap); } - return { swaps, expectedAmount } + return { swaps, expectedAmount }; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error in swapExactOut' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error in swapExactOut'; + return reason; } } - async swapExactIn (wallet, swaps, tokenIn, tokenOut, amountIn, minAmountOut, gasPrice) { - debug(`Number of swaps: ${swaps.length}`) + async swapExactIn(wallet, swaps, tokenIn, tokenOut, amountIn, minAmountOut, gasPrice) { + debug(`Number of swaps: ${swaps.length}`); try { - const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet) + const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet); const tx = await contract.batchSwapExactIn( swaps, tokenIn, @@ -168,22 +169,22 @@ export default class Balancer { { gasPrice: gasPrice * 1e9, gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP, - } - ) + }, + ); debug(`Tx Hash: ${tx.hash}`); - return tx + return tx; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error in swapExactIn' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error in swapExactIn'; + return reason; } } - async swapExactOut (wallet, swaps, tokenIn, tokenOut, expectedIn, gasPrice) { - debug(`Number of swaps: ${swaps.length}`) + async swapExactOut(wallet, swaps, tokenIn, tokenOut, expectedIn, gasPrice) { + debug(`Number of swaps: ${swaps.length}`); try { - const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet) + const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet); const tx = await contract.batchSwapExactOut( swaps, tokenIn, @@ -192,15 +193,15 @@ export default class Balancer { { gasPrice: gasPrice * 1e9, gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP, - } - ) - debug(`Tx Hash: ${tx.hash}`) - return tx + }, + ); + debug(`Tx Hash: ${tx.hash}`); + return tx; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error in swapExactOut' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error in swapExactOut'; + return reason; } } } diff --git a/src/services/eth.js b/src/services/eth.js index 61a51cd..a1dba27 100644 --- a/src/services/eth.js +++ b/src/services/eth.js @@ -1,166 +1,164 @@ +import axios from 'axios'; import { logger } from './logger'; -import axios from 'axios' -const debug = require('debug')('router') -require('dotenv').config() +require('dotenv').config(); const fs = require('fs'); -const ethers = require('ethers') -const abi = require('../static/abi') +const ethers = require('ethers'); +const abi = require('../static/abi'); // constants const APPROVAL_GAS_LIMIT = process.env.ETH_APPROVAL_GAS_LIMIT || 50000; export default class Ethereum { - constructor (network = 'mainnet') { + constructor(network = 'mainnet') { // network defaults to kovan - const providerUrl = process.env.ETHEREUM_RPC_URL - this.provider = new ethers.providers.JsonRpcProvider(providerUrl) - this.erc20TokenListURL = process.env.ETHEREUM_TOKEN_LIST_URL - this.network = network + const providerUrl = process.env.ETHEREUM_RPC_URL; + this.provider = new ethers.providers.JsonRpcProvider(providerUrl); + this.erc20TokenListURL = process.env.ETHEREUM_TOKEN_LIST_URL; + this.network = network; this.spenders = { balancer: process.env.EXCHANGE_PROXY, - uniswap: process.env.UNISWAP_ROUTER - } + uniswap: process.env.UNISWAP_ROUTER, + }; // update token list - this.getERC20TokenList() // erc20TokenList + this.getERC20TokenList(); // erc20TokenList } // get ETH balance - async getETHBalance (wallet) { + async getETHBalance(wallet) { try { - const balance = await wallet.getBalance() - return balance / 1e18.toString() + const balance = await wallet.getBalance(); + return balance / 1e18.toString(); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error ETH balance lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error ETH balance lookup'; + return reason; } } // get ERC-20 token balance - async getERC20Balance (wallet, tokenAddress, decimals = 18) { + async getERC20Balance(wallet, tokenAddress, decimals = 18) { // instantiate a contract and pass in provider for read-only access - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider) + const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider); try { - const balance = await contract.balanceOf(wallet.address) - return balance / Math.pow(10, decimals).toString() + const balance = await contract.balanceOf(wallet.address); + return balance / (10 ** decimals).toString(); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error balance lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error balance lookup'; + return reason; } } // get ERC-20 token allowance - async getERC20Allowance (wallet, spender, tokenAddress, decimals = 18) { + async getERC20Allowance(wallet, spender, tokenAddress, decimals = 18) { // instantiate a contract and pass in provider for read-only access - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider) + const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider); try { - const allowance = await contract.allowance(wallet.address, spender) - return allowance / Math.pow(10, decimals).toString() + const allowance = await contract.allowance(wallet.address, spender); + return allowance / (10 ** decimals).toString(); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error allowance lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error allowance lookup'; + return reason; } } // approve a spender to transfer tokens from a wallet address - async approveERC20 (wallet, spender, tokenAddress, amount, gasPrice = this.gasPrice, gasLimit) { + async approveERC20(wallet, spender, tokenAddress, amount, gasPrice = this.gasPrice, _gasLimit) { try { // fixate gas limit to prevent overwriting - const approvalGasLimit = APPROVAL_GAS_LIMIT + const approvalGasLimit = APPROVAL_GAS_LIMIT; // instantiate a contract and pass in wallet, which act on behalf of that signer - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, wallet) + const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, wallet); return await contract.approve( spender, amount, { gasPrice: gasPrice * 1e9, - gasLimit: approvalGasLimit - } - ) + gasLimit: approvalGasLimit, + }, + ); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error approval' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error approval'; + return reason; } } // get current Gas - async getCurrentGasPrice () { + async getCurrentGasPrice() { try { - this.provider.getGasPrice().then(function (gas) { + this.provider.getGasPrice().then((gas) => { // gasPrice is a BigNumber; convert it to a decimal string const gasPrice = gas.toString(); - return gasPrice - }) + return gasPrice; + }); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error gas lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error gas lookup'; + return reason; } } - async deposit (wallet, tokenAddress, amount, gasPrice = this.gasPrice, gasLimit = this.approvalGasLimit) { + async deposit(wallet, tokenAddress, amount, gasPrice = this.gasPrice, gasLimit = this.approvalGasLimit) { // deposit ETH to a contract address try { - const contract = new ethers.Contract(tokenAddress, abi.KovanWETHAbi, wallet) + const contract = new ethers.Contract(tokenAddress, abi.KovanWETHAbi, wallet); return await contract.deposit( - { value: amount, + { + value: amount, gasPrice: gasPrice * 1e9, - gasLimit: gasLimit - } - ) + gasLimit, + }, + ); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error deposit' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error deposit'; + return reason; } } // get ERC20 Token List - async getERC20TokenList () { - let tokenListSource + async getERC20TokenList() { + let tokenListSource; try { if (this.network === 'kovan') { - tokenListSource = 'src/static/erc20_tokens_kovan.json' - this.erc20TokenList = JSON.parse(fs.readFileSync(tokenListSource)) + tokenListSource = 'src/static/erc20_tokens_kovan.json'; + this.erc20TokenList = JSON.parse(fs.readFileSync(tokenListSource)); } else if (this.network === 'mainnet') { - tokenListSource = this.erc20TokenListURL + tokenListSource = this.erc20TokenListURL; if (tokenListSource === undefined || tokenListSource === null) { - const errMessage = 'Token List source not found' - logger.error('ERC20 Token List Error', { message: errMessage}) - console.log('eth - Error: ', errMessage) + const errMessage = 'Token List source not found'; + logger.error('ERC20 Token List Error', { message: errMessage }); + console.log('eth - Error: ', errMessage); } if (this.erc20TokenList === undefined || this.erc20TokenList === null || this.erc20TokenList === {}) { - const response = await axios.get(tokenListSource) + const response = await axios.get(tokenListSource); if (response.status === 200 && response.data) { - this.erc20TokenList = response.data + this.erc20TokenList = response.data; } } } else { - throw Error(`Invalid network ${this.network}`) + throw Error(`Invalid network ${this.network}`); } - console.log('get ERC20 Token List', this.network, 'source', tokenListSource) + console.log('get ERC20 Token List', this.network, 'source', tokenListSource); } catch (err) { console.log(err); - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error ERC 20 Token List' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error ERC 20 Token List'; + return reason; } } - getERC20TokenAddresses (tokenSymbol) { - const tokenContractAddress = this.erc20TokenList.tokens.filter(obj => { - return obj.symbol === tokenSymbol.toUpperCase() - }) - return tokenContractAddress[0] + getERC20TokenAddresses(tokenSymbol) { + const tokenContractAddress = this.erc20TokenList.tokens.filter((obj) => obj.symbol === tokenSymbol.toUpperCase()); + return tokenContractAddress[0]; } } diff --git a/src/services/fees.js b/src/services/fees.js index 0535897..faa5805 100644 --- a/src/services/fees.js +++ b/src/services/fees.js @@ -1,44 +1,43 @@ +import axios from 'axios'; +import BigNumber from 'bignumber.js'; import { logger } from './logger'; -import axios from 'axios' -import BigNumber from 'bignumber.js' -require('dotenv').config() +require('dotenv').config(); -const debug = require('debug')('router') // constants -const ethGasStationHost = 'https://ethgasstation.info' -const ethGasStationEnabled = process.env.ENABLE_ETH_GAS_STATION || false -const ethGasStationApiKey = process.env.ETH_GAS_STATION_API_KEY -const ethManualGasPrice = parseInt(process.env.MANUAL_GAS_PRICE) -const ethGasStationURL = ethGasStationHost + '/api/ethgasAPI.json?api-key=' + ethGasStationApiKey -const defaultRefreshInterval = 120 -const denom = BigNumber('1e+9') +const ethGasStationHost = 'https://ethgasstation.info'; +const ethGasStationEnabled = process.env.ENABLE_ETH_GAS_STATION || false; +const ethGasStationApiKey = process.env.ETH_GAS_STATION_API_KEY; +const ethManualGasPrice = parseInt(process.env.MANUAL_GAS_PRICE); +const ethGasStationURL = `${ethGasStationHost}/api/ethgasAPI.json?api-key=${ethGasStationApiKey}`; +const defaultRefreshInterval = 120; +const denom = BigNumber('1e+9'); export default class Fees { - constructor () { - this.ethGasStationGasLevel = process.env.ETH_GAS_STATION_GAS_LEVEL - this.ethGasStationRefreshTime = (process.env.ETH_GAS_STATION_REFRESH_TIME || defaultRefreshInterval) * 1000 - this.getETHGasStationFee(this.ethGasStationGasLevel, 0) + constructor() { + this.ethGasStationGasLevel = process.env.ETH_GAS_STATION_GAS_LEVEL; + this.ethGasStationRefreshTime = (process.env.ETH_GAS_STATION_REFRESH_TIME || defaultRefreshInterval) * 1000; + this.getETHGasStationFee(this.ethGasStationGasLevel, 0); } // get ETH Gas Station - async getETHGasStationFee (gasLevel = this.ethGasStationGasLevel, interval = defaultRefreshInterval) { + async getETHGasStationFee(gasLevel = this.ethGasStationGasLevel, interval = defaultRefreshInterval) { try { if (ethGasStationEnabled === true || ethGasStationEnabled.toLowerCase() === 'true') { - const response = await axios.get(ethGasStationURL) + const response = await axios.get(ethGasStationURL); // divite by 10 to convert it to Gwei) - this.ethGasPrice = response.data[gasLevel] / 10 - console.log(`get ETHGasStation gas price (${gasLevel}): ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) + this.ethGasPrice = response.data[gasLevel] / 10; + console.log(`get ETHGasStation gas price (${gasLevel}): ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`); } else { - this.ethGasPrice = ethManualGasPrice - console.log(`get manual fixed gas price: ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`) + this.ethGasPrice = ethManualGasPrice; + console.log(`get manual fixed gas price: ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`); } } catch (err) { console.log(err); - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error ETH gas fee lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error ETH gas fee lookup'; + return reason; } if (interval > 0) { // set to '0' for one-time retrieval setTimeout(this.getETHGasStationFee.bind(this), this.ethGasStationRefreshTime); // update every x seconds @@ -46,8 +45,8 @@ export default class Fees { } // get gas cost - async getGasCost (gasPrice, gasLimit, inGwei = false) { - const cost = gasPrice * gasLimit - return inGwei ? cost : cost / denom - } + async getGasCost(gasPrice, gasLimit, inGwei = false) { + const cost = gasPrice * gasLimit; + return inGwei ? cost : cost / denom; + } } diff --git a/src/services/logger.js b/src/services/logger.js index 90bf160..d12da4c 100644 --- a/src/services/logger.js +++ b/src/services/logger.js @@ -1,27 +1,28 @@ -import { getLocalDate } from './utils' -require('dotenv').config() -const appRoot = require('app-root-path') -const winston = require('winston') +import { getLocalDate } from './utils'; + +require('dotenv').config(); +const appRoot = require('app-root-path'); +const winston = require('winston'); require('winston-daily-rotate-file'); const logFormat = winston.format.combine( winston.format.timestamp(), winston.format.align(), winston.format.printf( - info => { - const localDate = getLocalDate() - return `${localDate} | ${info.level} | ${info.message}` - } + (info) => { + const localDate = getLocalDate(); + return `${localDate} | ${info.level} | ${info.message}`; + }, ), -) +); const getLogPath = () => { - let logPath = process.env.LOG_PATH + let logPath = process.env.LOG_PATH; if (typeof logPath === 'undefined' || logPath == null || logPath === '') { - logPath = [appRoot.path, 'logs'].join('/') + logPath = [appRoot.path, 'logs'].join('/'); } - return logPath -} + return logPath; +}; const config = { file: { @@ -29,16 +30,16 @@ const config = { filename: `${getLogPath()}/logs_gateway_app.log.%DATE%`, datePattern: 'YYYY-MM-DD', handleExceptions: true, - handleRejections: true - } -} + handleRejections: true, + }, +}; -const allLogsFileTransport = new winston.transports.DailyRotateFile(config.file) +const allLogsFileTransport = new winston.transports.DailyRotateFile(config.file); const options = { format: logFormat, transports: [allLogsFileTransport], exitOnError: false, -} +}; -export const logger = winston.createLogger(options) +export const logger = winston.createLogger(options); diff --git a/src/services/perpetual_finance.js b/src/services/perpetual_finance.js index f2d482e..9113ad0 100644 --- a/src/services/perpetual_finance.js +++ b/src/services/perpetual_finance.js @@ -2,34 +2,30 @@ import { logger } from './logger'; const fetch = require('cross-fetch'); -const Ethers = require('ethers') -const AmmArtifact = require("@perp/contract/build/contracts/Amm.json") -const ClearingHouseArtifact = require("@perp/contract/build/contracts/ClearingHouse.json") -const RootBridgeArtifact = require("@perp/contract/build/contracts/RootBridge.json") -const ClientBridgeArtifact = require("@perp/contract/build/contracts/ClientBridge.json") -const ClearingHouseViewerArtifact = require("@perp/contract/build/contracts/ClearingHouseViewer.json") -const TetherTokenArtifact = require("@perp/contract/build/contracts/TetherToken.json") +const Ethers = require('ethers'); +const AmmArtifact = require('@perp/contract/build/contracts/Amm.json'); +const ClearingHouseArtifact = require('@perp/contract/build/contracts/ClearingHouse.json'); +const ClearingHouseViewerArtifact = require('@perp/contract/build/contracts/ClearingHouseViewer.json'); +const TetherTokenArtifact = require('@perp/contract/build/contracts/TetherToken.json'); const GAS_LIMIT = 2123456; const DEFAULT_DECIMALS = 18; const CONTRACT_ADDRESSES = 'https://metadata.perp.exchange/'; const XDAI_PROVIDER = process.env.XDAI_PROVIDER || 'https://dai.poa.network'; const PNL_OPTION_SPOT_PRICE = 0; -const UPDATE_PERIOD = 60000; // stop updating prices after 30 secs from last request - +const UPDATE_PERIOD = 60000; // stop updating prices after 30 secs from last request export default class PerpetualFinance { - constructor (network = 'mainnet') { - this.providerUrl = XDAI_PROVIDER - this.network = network - this.provider = new Ethers.providers.JsonRpcProvider(this.providerUrl) - this.gasLimit = GAS_LIMIT - this.contractAddressesUrl = CONTRACT_ADDRESSES - this.amm = {} - this.priceCache = {} - this.cacheExpirary = {} - this.pairAmountCache = {} - + constructor(network = 'mainnet') { + this.providerUrl = XDAI_PROVIDER; + this.network = network; + this.provider = new Ethers.providers.JsonRpcProvider(this.providerUrl); + this.gasLimit = GAS_LIMIT; + this.contractAddressesUrl = CONTRACT_ADDRESSES; + this.amm = {}; + this.priceCache = {}; + this.cacheExpirary = {}; + this.pairAmountCache = {}; switch (network) { case 'mainnet': @@ -39,260 +35,262 @@ export default class PerpetualFinance { this.contractAddressesUrl += 'staging.json'; break; default: - const err = `Invalid network ${network}` - logger.error(err) - throw Error(err) + const err = `Invalid network ${network}`; + logger.error(err); + throw Error(err); } - this.loadedMetadata = this.load_metadata() - + this.loadedMetadata = this.load_metadata(); } async load_metadata() { - try{ - const metadata = await fetch(this.contractAddressesUrl).then(res => res.json()) - const layer2 = Object.keys(metadata.layers.layer2.contracts) + try { + const metadata = await fetch(this.contractAddressesUrl).then((res) => res.json()); + const layer2 = Object.keys(metadata.layers.layer2.contracts); - for (var key of layer2){ - if (metadata.layers.layer2.contracts[key].name === "Amm") { + for (const key of layer2) { + if (metadata.layers.layer2.contracts[key].name === 'Amm') { this.amm[key] = metadata.layers.layer2.contracts[key].address; - } else{ + } else { this[key] = metadata.layers.layer2.contracts[key].address; } } - this.layer2AmbAddr = metadata.layers.layer2.externalContracts.ambBridgeOnXDai - this.xUsdcAddr = metadata.layers.layer2.externalContracts.usdc - this.loadedMetadata = true - return true - } catch(err) { - return false + this.layer2AmbAddr = metadata.layers.layer2.externalContracts.ambBridgeOnXDai; + this.xUsdcAddr = metadata.layers.layer2.externalContracts.usdc; + this.loadedMetadata = true; + return true; + } catch (err) { + return false; } - } async update_price_loop() { if (Object.keys(this.cacheExpirary).length > 0) { - for (let pair in this.cacheExpirary){ + for (const pair in this.cacheExpirary) { if (this.cacheExpirary[pair] <= Date.now()) { delete this.cacheExpirary[pair]; delete this.priceCache[pair]; } } - for (let pair in this.cacheExpirary){ - let amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider) - await Promise.allSettled([amm.getInputPrice(0, {d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) }), - amm.getOutputPrice(0, {d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) })]) - .then(values => {if (!this.priceCache.hasOwnProperty(pair)) { this.priceCache[pair] = [] }; - this.priceCache[pair][0] = this.pairAmountCache[pair] / Ethers.utils.formatUnits(values[0].value.d); - this.priceCache[pair][1] = Ethers.utils.formatUnits(values[1].value.d) / this.pairAmountCache[pair];})} - + for (const pair in this.cacheExpirary) { + const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider); + await Promise.allSettled([amm.getInputPrice(0, { d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) }), + amm.getOutputPrice(0, { d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) })]) + .then((values) => { + if (!this.priceCache.hasOwnProperty(pair)) { this.priceCache[pair] = []; } + this.priceCache[pair][0] = this.pairAmountCache[pair] / Ethers.utils.formatUnits(values[0].value.d); + this.priceCache[pair][1] = Ethers.utils.formatUnits(values[1].value.d) / this.pairAmountCache[pair]; + }); } - setTimeout(this.update_price_loop.bind(this), 10000); // update every 10 seconds + } + setTimeout(this.update_price_loop.bind(this), 10000); // update every 10 seconds } // get XDai balance - async getXdaiBalance (wallet) { + async getXdaiBalance(wallet) { try { - const xDaiBalance = await wallet.getBalance() - return Ethers.utils.formatEther(xDaiBalance) + const xDaiBalance = await wallet.getBalance(); + return Ethers.utils.formatEther(xDaiBalance); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error xDai balance lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error xDai balance lookup'; + return reason; } } // get XDai USDC balance - async getUSDCBalance (wallet) { + async getUSDCBalance(wallet) { try { - const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet) - let layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address) - const layer2UsdcDecimals = await layer2Usdc.decimals() - return Ethers.utils.formatUnits(layer2UsdcBalance, layer2UsdcDecimals) + const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet); + const layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address); + const layer2UsdcDecimals = await layer2Usdc.decimals(); + return Ethers.utils.formatUnits(layer2UsdcBalance, layer2UsdcDecimals); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error balance lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error balance lookup'; + return reason; } } // get allowance - async getAllowance (wallet) { + async getAllowance(wallet) { // instantiate a contract and pass in provider for read-only access - const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet) + const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet); try { const allowanceForClearingHouse = await layer2Usdc.allowance( - wallet.address, - this.ClearingHouse - ) + wallet.address, + this.ClearingHouse, + ); - return Ethers.utils.formatUnits(allowanceForClearingHouse, DEFAULT_DECIMALS) + return Ethers.utils.formatUnits(allowanceForClearingHouse, DEFAULT_DECIMALS); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error allowance lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error allowance lookup'; + return reason; } } // approve - async approve (wallet, amount) { + async approve(wallet, amount) { try { // instantiate a contract and pass in wallet - const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet) - const tx = await layer2Usdc.approve(this.ClearingHouse, Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS)) + const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet); + const tx = await layer2Usdc.approve(this.ClearingHouse, Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS)); // TO-DO: We may want to supply custom gasLimit value above - return tx.hash + return tx.hash; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error approval' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error approval'; + return reason; } } - //open Position + // open Position async openPosition(side, margin, levrg, pair, minBaseAmount, wallet) { try { - const quoteAssetAmount = { d: Ethers.utils.parseUnits(margin, DEFAULT_DECIMALS) } - const leverage = { d: Ethers.utils.parseUnits(levrg, DEFAULT_DECIMALS) } - const minBaseAssetAmount = { d: Ethers.utils.parseUnits(minBaseAmount, DEFAULT_DECIMALS) } - const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet) + const quoteAssetAmount = { d: Ethers.utils.parseUnits(margin, DEFAULT_DECIMALS) }; + const leverage = { d: Ethers.utils.parseUnits(levrg, DEFAULT_DECIMALS) }; + const minBaseAssetAmount = { d: Ethers.utils.parseUnits(minBaseAmount, DEFAULT_DECIMALS) }; + const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet); const tx = await clearingHouse.openPosition( this.amm[pair], side, quoteAssetAmount, leverage, minBaseAssetAmount, - { gasLimit: this.gasLimit } - ) - return tx + { gasLimit: this.gasLimit }, + ); + return tx; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error opening position' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error opening position'; + return reason; } } - //close Position + // close Position async closePosition(wallet, pair, minimalQuote) { try { - const minimalQuoteAsset = { d: Ethers.utils.parseUnits(minimalQuote, DEFAULT_DECIMALS) } - const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet) - const tx = await clearingHouse.closePosition(this.amm[pair], minimalQuoteAsset, { gasLimit: this.gasLimit } ) - return tx + const minimalQuoteAsset = { d: Ethers.utils.parseUnits(minimalQuote, DEFAULT_DECIMALS) }; + const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet); + const tx = await clearingHouse.closePosition(this.amm[pair], minimalQuoteAsset, { gasLimit: this.gasLimit }); + return tx; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error closing position' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error closing position'; + return reason; } } - //get active position - async getPosition(wallet, pair) { + // get active position + async getPosition(wallet, pair) { try { - const positionValues = {} - const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet) - let premIndex = 0 + const positionValues = {}; + const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet); + let premIndex = 0; await Promise.allSettled([clearingHouse.getPosition(this.amm[pair], - wallet.address), - clearingHouse.getLatestCumulativePremiumFraction(this.amm[pair]), - clearingHouse.getPositionNotionalAndUnrealizedPnl(this.amm[pair], - wallet.address, - Ethers.BigNumber.from(PNL_OPTION_SPOT_PRICE))]) - .then(values => {positionValues.openNotional = Ethers.utils.formatUnits(values[0].value.openNotional.d, DEFAULT_DECIMALS); - positionValues.size = Ethers.utils.formatUnits(values[0].value.size.d, DEFAULT_DECIMALS); - positionValues.margin = Ethers.utils.formatUnits(values[0].value.margin.d, DEFAULT_DECIMALS); - positionValues.cumulativePremiumFraction = Ethers.utils.formatUnits(values[0].value.lastUpdatedCumulativePremiumFraction.d, DEFAULT_DECIMALS); - premIndex = Ethers.utils.formatUnits(values[1].value.d, DEFAULT_DECIMALS); - positionValues.pnl = Ethers.utils.formatUnits(values[2].value.unrealizedPnl.d, DEFAULT_DECIMALS); - positionValues.positionNotional = Ethers.utils.formatUnits(values[2].value.positionNotional.d, DEFAULT_DECIMALS);}) + wallet.address), + clearingHouse.getLatestCumulativePremiumFraction(this.amm[pair]), + clearingHouse.getPositionNotionalAndUnrealizedPnl(this.amm[pair], + wallet.address, + Ethers.BigNumber.from(PNL_OPTION_SPOT_PRICE))]) + .then((values) => { + positionValues.openNotional = Ethers.utils.formatUnits(values[0].value.openNotional.d, DEFAULT_DECIMALS); + positionValues.size = Ethers.utils.formatUnits(values[0].value.size.d, DEFAULT_DECIMALS); + positionValues.margin = Ethers.utils.formatUnits(values[0].value.margin.d, DEFAULT_DECIMALS); + positionValues.cumulativePremiumFraction = Ethers.utils.formatUnits(values[0].value.lastUpdatedCumulativePremiumFraction.d, DEFAULT_DECIMALS); + premIndex = Ethers.utils.formatUnits(values[1].value.d, DEFAULT_DECIMALS); + positionValues.pnl = Ethers.utils.formatUnits(values[2].value.unrealizedPnl.d, DEFAULT_DECIMALS); + positionValues.positionNotional = Ethers.utils.formatUnits(values[2].value.positionNotional.d, DEFAULT_DECIMALS); + }); - positionValues.entryPrice = Math.abs(positionValues.openNotional / positionValues.size) - positionValues.fundingPayment = (premIndex - positionValues.cumulativePremiumFraction) * positionValues.size // * -1 - return positionValues + positionValues.entryPrice = Math.abs(positionValues.openNotional / positionValues.size); + positionValues.fundingPayment = (premIndex - positionValues.cumulativePremiumFraction) * positionValues.size; // * -1 + return positionValues; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error getting active position' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error getting active position'; + return reason; } } - //get active margin + // get active margin async getActiveMargin(wallet) { try { - const clearingHouseViewer = new Ethers.Contract(this.ClearingHouseViewer, ClearingHouseViewerArtifact.abi, wallet) + const clearingHouseViewer = new Ethers.Contract(this.ClearingHouseViewer, ClearingHouseViewerArtifact.abi, wallet); const activeMargin = await clearingHouseViewer.getPersonalBalanceWithFundingPayment( - this.xUsdcAddr, - wallet.address) - return activeMargin / 1e18.toString() + this.xUsdcAddr, + wallet.address, + ); + return activeMargin / 1e18.toString(); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error getting active position' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error getting active position'; + return reason; } } // get Price async getPrice(side, amount, pair) { try { - let price - this.cacheExpirary[pair] = Date.now() + UPDATE_PERIOD - this.pairAmountCache[pair] = amount - if (!this.priceCache.hasOwnProperty(pair)){ - const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider) - if (side === "buy") { - price = await amm.getInputPrice(0, {d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }) - price = amount / Ethers.utils.formatUnits(price.d) - } else { - price = await amm.getOutputPrice(0, {d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }) - price = Ethers.utils.formatUnits(price.d) / amount - } - } else { - if (side === "buy") { - price = this.priceCache[pair][0] - } else { price = this.priceCache[pair][1] } - } - return price + let price; + this.cacheExpirary[pair] = Date.now() + UPDATE_PERIOD; + this.pairAmountCache[pair] = amount; + if (!this.priceCache.hasOwnProperty(pair)) { + const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider); + if (side === 'buy') { + price = await amm.getInputPrice(0, { d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }); + price = amount / Ethers.utils.formatUnits(price.d); + } else { + price = await amm.getOutputPrice(0, { d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }); + price = Ethers.utils.formatUnits(price.d) / amount; + } + } else if (side === 'buy') { + price = this.priceCache[pair][0]; + } else { price = this.priceCache[pair][1]; } + return price; } catch (err) { - console.log(err) - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error getting Price' - return reason + console.log(err); + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error getting Price'; + return reason; } } // get getFundingRate async getFundingRate(pair) { try { - let funding = {} - const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider) + const funding = {}; + const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider); await Promise.allSettled([amm.getUnderlyingTwapPrice(3600), - amm.getTwapPrice(3600), - amm.nextFundingTime()]) - .then(values => {funding.indexPrice = parseFloat(Ethers.utils.formatUnits(values[0].value.d)); - funding.markPrice = parseFloat(Ethers.utils.formatUnits(values[1].value.d)); - funding.nextFundingTime = parseInt(values[2].value.toString());}) + amm.getTwapPrice(3600), + amm.nextFundingTime()]) + .then((values) => { + funding.indexPrice = parseFloat(Ethers.utils.formatUnits(values[0].value.d)); + funding.markPrice = parseFloat(Ethers.utils.formatUnits(values[1].value.d)); + funding.nextFundingTime = parseInt(values[2].value.toString()); + }); - funding.rate = ((funding.markPrice - funding.indexPrice) / 24) / funding.indexPrice - return funding + funding.rate = ((funding.markPrice - funding.indexPrice) / 24) / funding.indexPrice; + return funding; } catch (err) { - console.log(err) - logger.error(err)() - let reason - err.reason ? reason = err.reason : reason = 'error getting fee' - return reason + console.log(err); + logger.error(err)(); + let reason; + err.reason ? reason = err.reason : reason = 'error getting fee'; + return reason; } } - } diff --git a/src/services/terra.js b/src/services/terra.js index 38dac2e..613f284 100644 --- a/src/services/terra.js +++ b/src/services/terra.js @@ -1,10 +1,12 @@ +import { + LCDClient, Coin, MsgSwap, MnemonicKey, isTxError, +} from '@terra-money/terra.js'; +import BigNumber from 'bignumber.js'; import { logger } from './logger'; -import { LCDClient, Coin, MsgSwap, StdTx, StdFee, Dec, MnemonicKey, isTxError, Coins } from '@terra-money/terra.js' -import BigNumber from 'bignumber.js' import { getHummingbotMemo } from './utils'; -const debug = require('debug')('router') -require('dotenv').config() +const debug = require('debug')('router'); +require('dotenv').config(); // constants const TERRA_TOKENS = { @@ -13,304 +15,305 @@ const TERRA_TOKENS = { ukrw: { symbol: 'KRT' }, usdr: { symbol: 'SDT' }, umnt: { symbol: 'MNT' }, -} -const DENOM_UNIT = BigNumber('1e+6') -const TOBIN_TAX = 0.0025 // a Tobin Tax (set at 0.25%) for spot-converting Terra<>Terra swaps -const MIN_SPREAD = 0.02 // a minimum spread (set at 2%) for Terra<>Luna swaps -const GAS_PRICE = { uluna: 0.16 } -const GAS_ADJUSTMENT = 1.4 +}; +const DENOM_UNIT = BigNumber('1e+6'); +const TOBIN_TAX = 0.0025; // a Tobin Tax (set at 0.25%) for spot-converting Terra<>Terra swaps +const MIN_SPREAD = 0.02; // a minimum spread (set at 2%) for Terra<>Luna swaps +const GAS_PRICE = { uluna: 0.16 }; +const GAS_ADJUSTMENT = 1.4; export default class Terra { - constructor () { + constructor() { this.lcdUrl = process.env.TERRA_LCD_URL; - this.network = process.env.TERRA_CHAIN; - this.tokens = TERRA_TOKENS - this.denomUnitMultiplier = DENOM_UNIT - this.tobinTax = TOBIN_TAX - this.minSpread = MIN_SPREAD - this.memo = getHummingbotMemo() + this.network = process.env.TERRA_CHAIN; + this.tokens = TERRA_TOKENS; + this.denomUnitMultiplier = DENOM_UNIT; + this.tobinTax = TOBIN_TAX; + this.minSpread = MIN_SPREAD; + this.memo = getHummingbotMemo(); try { - this.lcd = this.connect() + this.lcd = this.connect(); this.lcd.market.parameters().catch(() => { - throw new Error('Connection error') - }) + throw new Error('Connection error'); + }); // set gas & fee - this.lcd.config.gasAdjustment = GAS_ADJUSTMENT - this.lcd.config.gasPrices = GAS_PRICE + this.lcd.config.gasAdjustment = GAS_ADJUSTMENT; + this.lcd.config.gasPrices = GAS_PRICE; } catch (err) { - logger.error(err) - throw Error(`Connection failed: ${this.network}`) + logger.error(err); + throw Error(`Connection failed: ${this.network}`); } } // connect Terra LCD - connect () { + connect() { try { const lcd = new LCDClient({ URL: this.lcdUrl, chainID: this.network, - }) - lcd.config.gasAdjustment = GAS_ADJUSTMENT - lcd.config.gasPrices = GAS_PRICE - return lcd + }); + lcd.config.gasAdjustment = GAS_ADJUSTMENT; + lcd.config.gasPrices = GAS_PRICE; + return lcd; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra LCD connect' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error Terra LCD connect'; + return reason; } } // get Token Denom - getTokenDenom (symbol) { + getTokenDenom(symbol) { try { - let denom + let denom; Object.keys(TERRA_TOKENS).forEach((item) => { if (TERRA_TOKENS[item].symbol === symbol) { - denom = item + denom = item; } - }) - return denom + }); + return denom; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra Denom lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error Terra Denom lookup'; + return reason; } } // get Token Symbol - getTokenSymbol (denom) { + getTokenSymbol(denom) { try { - const symbol = TERRA_TOKENS[denom].symbol - return symbol + const { symbol } = TERRA_TOKENS[denom]; + return symbol; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra Denom lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error Terra Denom lookup'; + return reason; } } - getTxAttributes (attributes) { - let attrib = {} + getTxAttributes(attributes) { + const attrib = {}; attributes.forEach((item) => { - attrib[item.key] = item.value - }) - return attrib + attrib[item.key] = item.value; + }); + return attrib; } - async getEstimateFee (tx) { + async getEstimateFee(tx) { try { - const fee = await this.lcd.tx.estimateFee(tx) - return fee + const fee = await this.lcd.tx.estimateFee(tx); + return fee; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra estimate fee lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error Terra estimate fee lookup'; + return reason; } } - async getExchangeRate (denom) { + async getExchangeRate(denom) { try { - const exchangeRates = await this.lcd.oracle.exchangeRates() - return exchangeRates.get(denom) + const exchangeRates = await this.lcd.oracle.exchangeRates(); + return exchangeRates.get(denom); } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup'; + return reason; } } - async getTxFee () { + async getTxFee() { try { - const lunaFee = GAS_PRICE.uluna * GAS_ADJUSTMENT - let feeList = { uluna: lunaFee } - await this.lcd.oracle.exchangeRates().then(rates => { - Object.keys(rates._coins).forEach(key => { - feeList[key] = rates._coins[key].amount * lunaFee - }) - }) - debug('lunaFee', lunaFee, feeList) - - return feeList + const lunaFee = GAS_PRICE.uluna * GAS_ADJUSTMENT; + const feeList = { uluna: lunaFee }; + await this.lcd.oracle.exchangeRates().then((rates) => { + Object.keys(rates._coins).forEach((key) => { + feeList[key] = rates._coins[key].amount * lunaFee; + }); + }); + debug('lunaFee', lunaFee, feeList); + + return feeList; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup'; + return reason; } } // get Terra Swap Rate - async getSwapRate (baseToken, quoteToken, amount, tradeType) { + async getSwapRate(baseToken, quoteToken, amount, tradeType) { try { - let exchangeRate, offerCoin, offerDenom, swapDenom, cost, costAmount, offer - let swaps = {} + let exchangeRate; let offerCoin; let offerDenom; let swapDenom; let cost; let costAmount; let + offer; + const swaps = {}; if (tradeType.toLowerCase() === 'sell') { // sell base - offerDenom = this.getTokenDenom(baseToken) - swapDenom = this.getTokenDenom(quoteToken) + offerDenom = this.getTokenDenom(baseToken); + swapDenom = this.getTokenDenom(quoteToken); offerCoin = new Coin(offerDenom, amount * DENOM_UNIT); - await this.lcd.market.swapRate(offerCoin, swapDenom).then(swapCoin => { - offer = { amount: amount } + await this.lcd.market.swapRate(offerCoin, swapDenom).then((swapCoin) => { + offer = { amount }; exchangeRate = { amount: (swapCoin.amount / DENOM_UNIT) / amount, - token: quoteToken - } - costAmount = amount * exchangeRate.amount + token: quoteToken, + }; + costAmount = amount * exchangeRate.amount; cost = { amount: costAmount, - token: quoteToken - } - }) + token: quoteToken, + }; + }); } else { // buy base - offerDenom = this.getTokenDenom(quoteToken) - swapDenom = this.getTokenDenom(baseToken) + offerDenom = this.getTokenDenom(quoteToken); + swapDenom = this.getTokenDenom(baseToken); offerCoin = new Coin(offerDenom, 1 * DENOM_UNIT); - await this.lcd.market.swapRate(offerCoin, swapDenom).then(swapCoin => { + await this.lcd.market.swapRate(offerCoin, swapDenom).then((swapCoin) => { exchangeRate = { amount: (amount / parseInt(swapCoin.amount) * DENOM_UNIT) / amount, // adjusted amount - token: quoteToken - } - costAmount = amount * exchangeRate.amount + token: quoteToken, + }; + costAmount = amount * exchangeRate.amount; cost = { amount: costAmount, - token: quoteToken - } - offer = { amount: cost.amount } - }) + token: quoteToken, + }; + offer = { amount: cost.amount }; + }); } - let txFee - await this.getTxFee().then(fee => { + let txFee; + await this.getTxFee().then((fee) => { // fee in quote - txFee = { amount: parseFloat(fee[this.getTokenDenom(quoteToken)]), token: quoteToken } - }) - - swaps.offer = offer - swaps.price = exchangeRate - swaps.cost = cost - swaps.txFee = txFee - debug('swaps', swaps) - return swaps + txFee = { amount: parseFloat(fee[this.getTokenDenom(quoteToken)]), token: quoteToken }; + }); + + swaps.offer = offer; + swaps.price = exchangeRate; + swaps.cost = cost; + swaps.txFee = txFee; + debug('swaps', swaps); + return swaps; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = 'error swap rate lookup' - return reason + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = 'error swap rate lookup'; + return reason; } } // Swap tokens - async swapTokens (baseToken, quoteToken, amount, tradeType, gasPrice, gasAdjustment, secret) { - let swapResult + async swapTokens(baseToken, quoteToken, amount, tradeType, gasPrice, gasAdjustment, secret) { + let swapResult; try { // connect to lcd - const lcd = this.connect() + const lcd = this.connect(); const mk = new MnemonicKey({ mnemonic: secret, }); - let wallet + let wallet; try { wallet = lcd.wallet(mk); } catch (err) { - logger.error(err) - throw Error('Wallet access error') + logger.error(err); + throw Error('Wallet access error'); } - const address = wallet.key.accAddress + const address = wallet.key.accAddress; // get the current swap rate - const baseDenom = this.getTokenDenom(baseToken) - const quoteDenom = this.getTokenDenom(quoteToken) + const baseDenom = this.getTokenDenom(baseToken); + const quoteDenom = this.getTokenDenom(quoteToken); - let offerDenom, swapDenom - let swaps, txAttributes - let tokenSwap = {} + let offerDenom; let + swapDenom; + let swaps; let + txAttributes; + const tokenSwap = {}; if (tradeType.toLowerCase() === 'sell') { - offerDenom = baseDenom - swapDenom = quoteDenom + offerDenom = baseDenom; + swapDenom = quoteDenom; } else { - offerDenom = quoteDenom - swapDenom = baseDenom + offerDenom = quoteDenom; + swapDenom = baseDenom; } await this.getSwapRate(baseToken, quoteToken, amount, tradeType, secret).then((rate) => { - swaps = rate - }) + swaps = rate; + }); - const offerAmount = parseInt((swaps.offer.amount) * DENOM_UNIT) - const offerCoin = new Coin(offerDenom, offerAmount) + const offerAmount = parseInt((swaps.offer.amount) * DENOM_UNIT); + const offerCoin = new Coin(offerDenom, offerAmount); // Create and Sign Transaction const msgSwap = new MsgSwap(address, offerCoin, swapDenom); - let txOptions + let txOptions; if (gasPrice !== null && gasPrice !== null) { // ignore gasAdjustment when gasPrice is not set txOptions = { msgs: [msgSwap], gasPrices: { uluna: parseFloat(gasPrice) }, - gasAdjustment: gasAdjustment, - memo: this.memo - } + gasAdjustment, + memo: this.memo, + }; } else { txOptions = { msgs: [msgSwap], - memo: this.memo - } + memo: this.memo, + }; } - await wallet.createAndSignTx(txOptions).then(tx => lcd.tx.broadcast(tx)).then((txResult) => { - swapResult = txResult + await wallet.createAndSignTx(txOptions).then((tx) => lcd.tx.broadcast(tx)).then((txResult) => { + swapResult = txResult; - const swapSuccess = !isTxError(txResult) + const swapSuccess = !isTxError(txResult); if (swapSuccess) { - tokenSwap.txSuccess = swapSuccess + tokenSwap.txSuccess = swapSuccess; } else { - tokenSwap.txSuccess = !swapSuccess + tokenSwap.txSuccess = !swapSuccess; throw new Error(`encountered an error while running the transaction: ${txResult.code} ${txResult.codespace}`); } - const txHash = txResult.txhash - const events = JSON.parse(txResult.raw_log)[0].events - const swap = events.find(obj => { - return obj.type === 'swap' - }) - txAttributes = this.getTxAttributes(swap.attributes) - const offer = Coin.fromString(txAttributes.offer) - const ask = Coin.fromString(txAttributes.swap_coin) - const fee = Coin.fromString(txAttributes.swap_fee) - - tokenSwap.expectedIn = { + const txHash = txResult.txhash; + const { events } = JSON.parse(txResult.raw_log)[0]; + const swap = events.find((obj) => obj.type === 'swap'); + txAttributes = this.getTxAttributes(swap.attributes); + const offer = Coin.fromString(txAttributes.offer); + const ask = Coin.fromString(txAttributes.swap_coin); + const fee = Coin.fromString(txAttributes.swap_fee); + + tokenSwap.expectedIn = { amount: parseFloat(offer.amount) / DENOM_UNIT, - token: TERRA_TOKENS[offer.denom].symbol - } + token: TERRA_TOKENS[offer.denom].symbol, + }; tokenSwap.expectedOut = { amount: parseFloat(ask.amount) / DENOM_UNIT, - token: TERRA_TOKENS[ask.denom].symbol - } + token: TERRA_TOKENS[ask.denom].symbol, + }; tokenSwap.fee = { amount: parseFloat(fee.amount) / DENOM_UNIT, - token: TERRA_TOKENS[fee.denom].symbol - } - tokenSwap.txHash = txHash - }) - return tokenSwap + token: TERRA_TOKENS[fee.denom].symbol, + }; + tokenSwap.txHash = txHash; + }); + return tokenSwap; } catch (err) { - logger.error(err) - let reason - err.reason ? reason = err.reason : reason = swapResult - return { txSuccess: false, message: reason } + logger.error(err); + let reason; + err.reason ? reason = err.reason : reason = swapResult; + return { txSuccess: false, message: reason }; } } } diff --git a/src/services/uniswap.js b/src/services/uniswap.js index 8fe7bbb..9298b54 100644 --- a/src/services/uniswap.js +++ b/src/services/uniswap.js @@ -1,35 +1,35 @@ import { logger } from './logger'; -const debug = require('debug')('router') -const math = require('mathjs') -const uni = require('@uniswap/sdk') -const ethers = require('ethers') -const proxyArtifact = require('../static/uniswap_v2_router_abi.json') -const routeTokens = require('../static/uniswap_route_tokens.json') +const debug = require('debug')('router'); +const math = require('mathjs'); +const uni = require('@uniswap/sdk'); +const ethers = require('ethers'); +const proxyArtifact = require('../static/uniswap_v2_router_abi.json'); +const routeTokens = require('../static/uniswap_route_tokens.json'); // constants -const ROUTER = process.env.UNISWAP_ROUTER +const ROUTER = process.env.UNISWAP_ROUTER; const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 150688; const TTL = process.env.UNISWAP_TTL || 300; -const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request +const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request export default class Uniswap { - constructor (network = 'mainnet') { - this.providerUrl = process.env.ETHEREUM_RPC_URL - this.network = process.env.ETHEREUM_CHAIN - this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) + constructor(network = 'mainnet') { + this.providerUrl = process.env.ETHEREUM_RPC_URL; + this.network = process.env.ETHEREUM_CHAIN; + this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl); this.router = ROUTER; - this.slippage = math.fraction(process.env.UNISWAP_ALLOWED_SLIPPAGE) - this.allowedSlippage = new uni.Percent(this.slippage.n, (this.slippage.d * 100)) - this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME - this.gasLimit = GAS_LIMIT - this.expireTokenPairUpdate = UPDATE_PERIOD - this.zeroReserveCheckInterval = process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL - this.zeroReservePairs = {} // No reserve pairs - this.tokenList = {} - this.pairs = [] - this.tokenSwapList = {} - this.cachedRoutes = {} + this.slippage = math.fraction(process.env.UNISWAP_ALLOWED_SLIPPAGE); + this.allowedSlippage = new uni.Percent(this.slippage.n, (this.slippage.d * 100)); + this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME; + this.gasLimit = GAS_LIMIT; + this.expireTokenPairUpdate = UPDATE_PERIOD; + this.zeroReserveCheckInterval = process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL; + this.zeroReservePairs = {}; // No reserve pairs + this.tokenList = {}; + this.pairs = []; + this.tokenSwapList = {}; + this.cachedRoutes = {}; switch (network) { case 'mainnet': @@ -39,45 +39,44 @@ export default class Uniswap { this.chainID = uni.ChainId.KOVAN; break; default: - const err = `Invalid network ${network}` - logger.error(err) - throw Error(err) + const err = `Invalid network ${network}`; + logger.error(err); + throw Error(err); } } - async fetch_route(tIn, tOut){ - var route, pair, pairOne, pairTwo + async fetch_route(tIn, tOut) { + let route; + let pair; - try { - pair = await uni.Fetcher.fetchPairData(tIn, tOut); - route = new uni.Route([pair], tIn, tOut); - } - catch(err) { - logger.error(err); - } - return route; + try { + pair = await uni.Fetcher.fetchPairData(tIn, tOut); + route = new uni.Route([pair], tIn, tOut); + } catch (err) { + logger.error(err); + } + return route; } - - generate_tokens(){ - for (let token of routeTokens[this.network]){ - this.tokenList[token["address"]] = new uni.Token(this.chainID, token["address"], token["decimals"], token["symbol"], token["name"]); + generate_tokens() { + for (const token of routeTokens[this.network]) { + this.tokenList[token.address] = new uni.Token(this.chainID, token.address, token.decimals, token.symbol, token.name); } } - async extend_update_pairs(tokens=[]){ - for (let token of tokens){ - if (!this.tokenList.hasOwnProperty(token)){ - this.tokenList[token] = await uni.Fetcher.fetchTokenData(this.chainID, token); - } - this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate; + async extend_update_pairs(tokens = []) { + for (const token of tokens) { + if (!this.tokenList.hasOwnProperty(token)) { + this.tokenList[token] = await uni.Fetcher.fetchTokenData(this.chainID, token); } + this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate; + } } - async update_pairs(){ + async update_pairs() { // Remove banned pairs after ban period - if (Object.keys(this.zeroReservePairs).length > 0){ - for (let pair in this.zeroReservePairs){ + if (Object.keys(this.zeroReservePairs).length > 0) { + for (const pair in this.zeroReservePairs) { if (this.zeroReservePairs[pair] <= Date.now()) { delete this.zeroReservePairs[pair]; // delete this.tokenList[token]; @@ -86,132 +85,132 @@ export default class Uniswap { } // Generate all possible pair combinations of tokens // This is done by generating an upper triangular matrix or right triangular matrix - if (Object.keys(this.tokenSwapList).length > 0){ - for (let token in this.tokenSwapList){ + if (Object.keys(this.tokenSwapList).length > 0) { + for (const token in this.tokenSwapList) { if (this.tokenSwapList[token] <= Date.now()) { delete this.tokenSwapList[token]; // delete this.tokenList[token]; } } - let tokens = Object.keys(this.tokenList); - var firstToken, secondToken, position; - let length = tokens.length; - let pairs = []; - let pairAddressRequests = []; - let pairAddressResponses = []; - for (firstToken = 0; firstToken < length; firstToken++){ - for (secondToken = firstToken + 1; secondToken < length; secondToken++){ - try{ - let pairString = this.tokenList[tokens[firstToken]].address + '-' + this.tokenList[tokens[secondToken]].address; - if (!this.zeroReservePairs.hasOwnProperty(pairString)){ + const tokens = Object.keys(this.tokenList); + let firstToken; let secondToken; let + position; + const length = tokens.length; + const pairs = []; + const pairAddressRequests = []; + const pairAddressResponses = []; + for (firstToken = 0; firstToken < length; firstToken++) { + for (secondToken = firstToken + 1; secondToken < length; secondToken++) { + try { + const pairString = `${this.tokenList[tokens[firstToken]].address}-${this.tokenList[tokens[secondToken]].address}`; + if (!this.zeroReservePairs.hasOwnProperty(pairString)) { pairs.push(pairString); pairAddressRequests.push(uni.Fetcher.fetchPairData(this.tokenList[tokens[firstToken]], this.tokenList[tokens[secondToken]])); } - } - catch(err) { + } catch (err) { logger.error(err); } } } - await Promise.allSettled(pairAddressRequests).then(values => { for (position = 0; position < pairAddressRequests.length; position++) { - if (values[position].status === "fulfilled"){pairAddressResponses.push(values[position].value)} - else {this.zeroReservePairs[pairs[position]] = Date.now() + this.zeroReserveCheckInterval;}}}) + await Promise.allSettled(pairAddressRequests).then((values) => { + for (position = 0; position < pairAddressRequests.length; position++) { + if (values[position].status === 'fulfilled') { pairAddressResponses.push(values[position].value); } else { this.zeroReservePairs[pairs[position]] = Date.now() + this.zeroReserveCheckInterval; } + } + }); this.pairs = pairAddressResponses; } setTimeout(this.update_pairs.bind(this), 1000); } - async priceSwapIn (tokenIn, tokenOut, tokenInAmount) { + async priceSwapIn(tokenIn, tokenOut, tokenInAmount) { await this.extend_update_pairs([tokenIn, tokenOut]); const tIn = this.tokenList[tokenIn]; const tOut = this.tokenList[tokenOut]; const tokenAmountIn = new uni.TokenAmount(tIn, ethers.utils.parseUnits(tokenInAmount, tIn.decimals)); - if (this.pairs.length === 0){ + if (this.pairs.length === 0) { const route = await this.fetch_route(tIn, tOut); const trade = uni.Trade.exactIn(route, tokenAmountIn); - if ( trade !== undefined ){ + if (trade !== undefined) { const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; - return { trade, expectedAmount } + return { trade, expectedAmount }; } - return "Can't find route to swap, kindly update " + return "Can't find route to swap, kindly update "; } - const trade = uni.Trade.bestTradeExactIn(this.pairs, tokenAmountIn, this.tokenList[tokenOut], { maxHops: 5 })[0]; - if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} - else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} + let trade = uni.Trade.bestTradeExactIn(this.pairs, tokenAmountIn, this.tokenList[tokenOut], { maxHops: 5 })[0]; + if (trade === undefined) { trade = this.cachedRoutes[tIn.symbol + tOut.Symbol]; } else { this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; } const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); - return { trade, expectedAmount } + return { trade, expectedAmount }; } - async priceSwapOut (tokenIn, tokenOut, tokenOutAmount) { + async priceSwapOut(tokenIn, tokenOut, tokenOutAmount) { await this.extend_update_pairs([tokenIn, tokenOut]); const tOut = this.tokenList[tokenOut]; const tIn = this.tokenList[tokenIn]; const tokenAmountOut = new uni.TokenAmount(tOut, ethers.utils.parseUnits(tokenOutAmount, tOut.decimals)); - if (this.pairs.length === 0){ + if (this.pairs.length === 0) { const route = await this.fetch_route(tIn, tOut); const trade = uni.Trade.exactOut(route, tokenAmountOut); - if ( trade !== undefined ){ + if (trade !== undefined) { const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; - return { trade, expectedAmount } + return { trade, expectedAmount }; } - return + return; } - const trade = uni.Trade.bestTradeExactOut(this.pairs, this.tokenList[tokenIn], tokenAmountOut, { maxHops: 5 })[0]; - if (trade === undefined){trade = this.cachedRoutes[tIn.symbol + tOut.Symbol];} - else{this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade;} + let trade = uni.Trade.bestTradeExactOut(this.pairs, this.tokenList[tokenIn], tokenAmountOut, { maxHops: 5 })[0]; + if (trade === undefined) { trade = this.cachedRoutes[tIn.symbol + tOut.Symbol]; } else { this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; } const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); - return { trade, expectedAmount } + return { trade, expectedAmount }; } - async swapExactIn (wallet, trade, tokenAddress, gasPrice) { + async swapExactIn(wallet, trade, tokenAddress, gasPrice) { const result = uni.Router.swapCallParameters( trade, { ttl: TTL, recipient: wallet.address, - allowedSlippage: this.allowedSlippage - } - ) + allowedSlippage: this.allowedSlippage, + }, + ); - const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) - const tx = await contract.[result.methodName]( + const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet); + const tx = await contract[result.methodName]( ...result.args, { gasPrice: gasPrice * 1e9, gasLimit: GAS_LIMIT, - value: result.value - } - ) + value: result.value, + }, + ); debug(`Tx Hash: ${tx.hash}`); - return tx + return tx; } - async swapExactOut (wallet, trade, tokenAddress, gasPrice) { + async swapExactOut(wallet, trade, tokenAddress, gasPrice) { const result = uni.Router.swapCallParameters( trade, { ttl: TTL, recipient: wallet.address, - allowedSlippage: this.allowedSlippage - } - ) + allowedSlippage: this.allowedSlippage, + }, + ); - const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) - const tx = await contract.[result.methodName]( + const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet); + const tx = await contract[result.methodName]( ...result.args, { gasPrice: gasPrice * 1e9, gasLimit: GAS_LIMIT, - value: result.value - } - ) + value: result.value, + }, + ); debug(`Tx Hash: ${tx.hash}`); - return tx + return tx; } } diff --git a/src/services/utils.js b/src/services/utils.js index 23182cc..430936b 100644 --- a/src/services/utils.js +++ b/src/services/utils.js @@ -1,8 +1,8 @@ /* Hummingbot Utils */ -const lodash = require('lodash') -const moment = require('moment') +const lodash = require('lodash'); +const moment = require('moment'); export const statusMessages = { ssl_cert_required: 'SSL Certificate required', @@ -12,74 +12,75 @@ export const statusMessages = { invalid_token_symbol: 'Invalid Token Symbol', insufficient_reserves: 'Insufficient Liquidity Reserves', page_not_found: 'Page not found. Invalid path', -} +}; -export const latency = (startTime, endTime) => parseFloat((endTime - startTime) / 1000) +export const latency = (startTime, endTime) => parseFloat((endTime - startTime) / 1000); export const isValidParams = (params) => { - const values = Object.values(params) - for (let i = 0; i < values.length; i++) { // DO NOT use forEach, it returns callback without breaking the loop + const values = Object.values(params); + // DO NOT use forEach, it returns callback without breaking the loop + for (let i = 0; i < values.length; i++) { if (typeof values[i] === 'undefined') { - throw new Error('Invalid input params') + throw new Error('Invalid input params'); } } - return true -} + return true; +}; export const isValidData = (data, format) => { if (typeof data !== 'undefined' && Object.keys(data).length !== 0 && lodash.isEqual(Object.keys(data).sort(), format.sort())) { - return true + return true; } - return false -} + return false; +}; export const getParamData = (data, format = null) => { - const dataObject = {} + const dataObject = {}; if (format !== null) { if (isValidData(data, format)) { - format.forEach((key, index) => { - dataObject[key] = data[key] - }) + format.forEach((key, _index) => { + dataObject[key] = data[key]; + }); } } else { - Object.keys(data).forEach((key, index) => { - dataObject[key] = data[key] - }) + Object.keys(data).forEach((key, _index) => { + dataObject[key] = data[key]; + }); } - return dataObject -} + return dataObject; +}; export const splitParamData = (param, separator = ',') => { - const dataArray = param.split(separator) - return dataArray -} + const dataArray = param.split(separator); + return dataArray; +}; export const getSymbols = (tradingPair) => { - const symbols = tradingPair.split('-') + const symbols = tradingPair.split('-'); const baseQuotePair = { base: symbols[0].toUpperCase(), - quote: symbols[1].toUpperCase() - } - return baseQuotePair -} + quote: symbols[1].toUpperCase(), + }; + return baseQuotePair; +}; export const reportConnectionError = (res, error) => { res.json({ error: error.errno, code: error.code, - }) -} + }); +}; export const strToDecimal = (str) => parseInt(str) / 100; export const getHummingbotMemo = () => { - const prefix = 'hbot' - const clientId = process.env.HUMMINGBOT_INSTANCE_ID + const prefix = 'hbot'; + const clientId = process.env.HUMMINGBOT_INSTANCE_ID; if ((typeof clientId !== 'undefined' && clientId != null) && clientId !== '') { - return [prefix, clientId].join('-') + return [prefix, clientId].join('-'); } - return prefix -} + return prefix; +}; export const loadConfig = () => { const config = { @@ -87,7 +88,7 @@ export const loadConfig = () => { ethereum_chain: process.env.ETHEREUM_CHAIN, exchange_proxy: process.env.EXCHANGE_PROXY, ethereum_token_list_url: process.env.ETHEREUM_TOKEN_LIST_URL, - enable_eth_gas_station: process.env.ENABLE_ETH_GAS_STATION != null ? (process.env.ENABLE_ETH_GAS_STATION.toLowerCase() == 'true') : false, + enable_eth_gas_station: process.env.ENABLE_ETH_GAS_STATION != null ? (process.env.ENABLE_ETH_GAS_STATION.toLowerCase() === 'true') : false, eth_gas_station_gas_level: process.env.ETH_GAS_STATION_GAS_LEVEL, eth_gas_station_refresh_time: process.env.ETH_GAS_STATION_REFRESH_TIME != null ? parseFloat(process.env.ETH_GAS_STATION_REFRESH_TIME) : null, manual_gas_price: process.env.MANUAL_GAS_PRICE != null ? parseFloat(process.env.MANUAL_GAS_PRICE) : null, @@ -95,16 +96,16 @@ export const loadConfig = () => { balancer_max_swaps: process.env.BALANCER_MAX_SWAPS != null ? parseInt(process.env.BALANCER_MAX_SWAPS) : null, uniswap_router: process.env.UNISWAP_ROUTER, terra_lcd_url: process.env.TERRA_LCD_URL, - terra_chain: process.env.TERRA_CHAIN - } - return config -} + terra_chain: process.env.TERRA_CHAIN, + }; + return config; +}; export const getLocalDate = () => { - const gmtOffset = process.env.GMT_OFFSET - let newDate = moment().format('YYYY-MM-DD hh:mm:ss').trim() + const gmtOffset = process.env.GMT_OFFSET; + let newDate = moment().format('YYYY-MM-DD hh:mm:ss').trim(); if (typeof gmtOffset !== 'undefined' && gmtOffset !== null && gmtOffset !== '') { - newDate = moment().utcOffset(gmtOffset, false).format('YYYY-MM-DD hh:mm:ss').trim() + newDate = moment().utcOffset(gmtOffset, false).format('YYYY-MM-DD hh:mm:ss').trim(); } - return newDate -} + return newDate; +}; diff --git a/yarn.lock b/yarn.lock index a3a5e0c..d7394f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,401 +2,439 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== dependencies: "@babel/highlight" "^7.10.4" -"@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" - integrity sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ== +"@babel/code-frame@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== dependencies: - browserslist "^4.12.0" - invariant "^2.2.4" - semver "^5.5.0" + "@babel/highlight" "^7.12.13" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.4.tgz#45720fe0cecf3fd42019e1d12cc3d27fadc98d58" + integrity sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ== "@babel/core@^7.11.6": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" - integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.6" - "@babel/helper-module-transforms" "^7.11.0" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.5" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.5" - "@babel/types" "^7.11.5" + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.3.tgz#5395e30405f0776067fbd9cf0884f15bfb770a38" + integrity sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.14.3" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-module-transforms" "^7.14.2" + "@babel/helpers" "^7.14.0" + "@babel/parser" "^7.14.3" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.2" + "@babel/types" "^7.14.2" convert-source-map "^1.7.0" debug "^4.1.0" - gensync "^1.0.0-beta.1" + gensync "^1.0.0-beta.2" json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" + semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.11.5", "@babel/generator@^7.11.6": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" - integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== +"@babel/generator@^7.14.2", "@babel/generator@^7.14.3": + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.3.tgz#0c2652d91f7bddab7cccc6ba8157e4f40dcedb91" + integrity sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA== dependencies: - "@babel/types" "^7.11.5" + "@babel/types" "^7.14.2" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" - integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" - integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-compilation-targets@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" - integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== - dependencies: - "@babel/compat-data" "^7.10.4" - browserslist "^4.12.0" - invariant "^2.2.4" - levenary "^1.1.1" - semver "^5.5.0" - -"@babel/helper-create-class-features-plugin@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" - integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.10.5" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - -"@babel/helper-create-regexp-features-plugin@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" - integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== +"@babel/helper-annotate-as-pure@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" + integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - regexpu-core "^4.7.0" + "@babel/types" "^7.12.13" -"@babel/helper-define-map@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" - integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" + integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/types" "^7.10.5" - lodash "^4.17.19" + "@babel/helper-explode-assignable-expression" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/helper-explode-assignable-expression@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" - integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ== +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz#33ebd0ffc34248051ee2089350a929ab02f2a516" + integrity sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA== dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" - integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-get-function-arity@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" - integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-hoist-variables@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" - integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" - integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-module-imports@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" - integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" - integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/template" "^7.10.4" - "@babel/types" "^7.11.0" - lodash "^4.17.19" - -"@babel/helper-optimise-call-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" - integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== - -"@babel/helper-regex@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" - integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== - dependencies: - lodash "^4.17.19" - -"@babel/helper-remap-async-to-generator@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz#4474ea9f7438f18575e30b0cac784045b402a12d" - integrity sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-wrap-function" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-replace-supers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" - integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-simple-access@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" - integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== - dependencies: - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" - integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" - integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== - -"@babel/helper-wrap-function@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" - integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helpers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" - integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== - dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/compat-data" "^7.14.4" + "@babel/helper-validator-option" "^7.12.17" + browserslist "^4.16.6" + semver "^6.3.0" -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" +"@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.0", "@babel/helper-create-class-features-plugin@^7.14.3": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz#abf888d836a441abee783c75229279748705dc42" + integrity sha512-idr3pthFlDCpV+p/rMgGLGYIVtazeatrSOQk8YzO2pAepIjQhCN3myeihVg58ax2bbbGK9PUE1reFi7axOYIOw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.14.2" + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-replace-supers" "^7.14.4" + "@babel/helper-split-export-declaration" "^7.12.13" + +"@babel/helper-create-regexp-features-plugin@^7.12.13": + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.3.tgz#149aa6d78c016e318c43e2409a0ae9c136a86688" + integrity sha512-JIB2+XJrb7v3zceV2XzDhGIB902CmKGSpSl4q2C6agU9SNLG/2V1RtFRGPG1Ajh9STj3+q6zJMOC+N/pp2P9DA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + regexpu-core "^4.7.1" + +"@babel/helper-define-polyfill-provider@^0.2.2": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6" + integrity sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-explode-assignable-expression@^7.12.13": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" + integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== + dependencies: + "@babel/types" "^7.13.0" + +"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz#397688b590760b6ef7725b5f0860c82427ebaac2" + integrity sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ== + dependencies: + "@babel/helper-get-function-arity" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/types" "^7.14.2" + +"@babel/helper-get-function-arity@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" + integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-hoist-variables@^7.13.0": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30" + integrity sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg== + dependencies: + "@babel/traverse" "^7.13.15" + "@babel/types" "^7.13.16" + +"@babel/helper-member-expression-to-functions@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" + integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" + integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0", "@babel/helper-module-transforms@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz#ac1cc30ee47b945e3e0c4db12fa0c5389509dfe5" + integrity sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA== + dependencies: + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-simple-access" "^7.13.12" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-validator-identifier" "^7.14.0" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.2" + "@babel/types" "^7.14.2" + +"@babel/helper-optimise-call-expression@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" + integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" + integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== + +"@babel/helper-remap-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" + integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-wrap-function" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.12", "@babel/helper-replace-supers@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz#b2ab16875deecfff3ddfcd539bc315f72998d836" + integrity sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/traverse" "^7.14.2" + "@babel/types" "^7.14.4" + +"@babel/helper-simple-access@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" + integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" + integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-split-export-declaration@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" + integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== + +"@babel/helper-validator-option@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" + integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== + +"@babel/helper-wrap-function@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" + integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA== + dependencies: + "@babel/helper-function-name" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/helpers@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62" + integrity sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg== + dependencies: + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" chalk "^2.0.0" js-tokens "^4.0.0" "@babel/node@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.10.5.tgz#30866322aa2c0251a9bdd73d07a9167bd1f4ed64" - integrity sha512-suosS7zZ2roj+fYVCnDuVezUbRc0sdoyF0Gj/1FzWxD4ebbGiBGtL5qyqHH4NO34B5m4vWWYWgyNhSsrqS8vwA== + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.14.2.tgz#d860c10306020d18e3fd0327c63bfaf2dbfc7470" + integrity sha512-QB/C+Kl6gIYpTjZ/hcZj+chkiAVGcgSHuR849cdNvNJBz4VztO2775/o2ge8imB94EAsLcgkrdWH/3+UIVv1TA== dependencies: - "@babel/register" "^7.10.5" + "@babel/register" "^7.13.16" commander "^4.0.1" core-js "^3.2.1" - lodash "^4.17.19" node-environment-flags "^1.0.5" regenerator-runtime "^0.13.4" - resolve "^1.13.1" v8flags "^3.1.1" -"@babel/parser@^7.10.4", "@babel/parser@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" - integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== - -"@babel/plugin-proposal-async-generator-functions@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" - integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.10.4" - "@babel/plugin-syntax-async-generators" "^7.8.0" - -"@babel/plugin-proposal-class-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" - integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-proposal-dynamic-import@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" - integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" +"@babel/parser@^7.12.13", "@babel/parser@^7.14.2", "@babel/parser@^7.14.3": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.4.tgz#a5c560d6db6cd8e6ed342368dea8039232cbab18" + integrity sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA== -"@babel/plugin-proposal-export-namespace-from@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz#570d883b91031637b3e2958eea3c438e62c05f54" - integrity sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a" + integrity sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.13.12" -"@babel/plugin-proposal-json-strings@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" - integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== +"@babel/plugin-proposal-async-generator-functions@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.2.tgz#3a2085abbf5d5f962d480dbc81347385ed62eb1e" + integrity sha512-b1AM4F6fwck4N8ItZ/AtC4FP/cqZqmKRQ4FaTDutwSYyjuhtvsGEMLK4N/ztV/ImP40BjIDyMgBQAeAMsQYVFQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-logical-assignment-operators@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz#9f80e482c03083c87125dee10026b58527ea20c8" - integrity sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q== +"@babel/plugin-proposal-class-properties@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" + integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" - integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== +"@babel/plugin-proposal-class-static-block@^7.14.3": + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.3.tgz#5a527e2cae4a4753119c3a3e7f64ecae8ccf1360" + integrity sha512-HEjzp5q+lWSjAgJtSluFDrGGosmwTgKwCXdDQZvhKsRlwv3YdkUEqxNrrjesJd+B9E9zvr1PVPVBvhYZ9msjvQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/helper-create-class-features-plugin" "^7.14.3" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-class-static-block" "^7.12.13" -"@babel/plugin-proposal-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" - integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== +"@babel/plugin-proposal-dynamic-import@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.2.tgz#01ebabd7c381cff231fa43e302939a9de5be9d9f" + integrity sha512-oxVQZIWFh91vuNEMKltqNsKLFWkOIyJc95k2Gv9lWVyDfPUQGSSlbDEgWuJUU1afGE9WwlzpucMZ3yDRHIItkA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-proposal-object-rest-spread@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" - integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== +"@babel/plugin-proposal-export-namespace-from@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz#62542f94aa9ce8f6dba79eec698af22112253791" + integrity sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-optional-catch-binding@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" - integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== +"@babel/plugin-proposal-json-strings@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.2.tgz#830b4e2426a782e8b2878fbfe2cba85b70cbf98c" + integrity sha512-w2DtsfXBBJddJacXMBhElGEYqCZQqN99Se1qeYn8DVLB33owlrlLftIbMzn5nz1OITfDVknXF433tBrLEAOEjA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" - integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== +"@babel/plugin-proposal-logical-assignment-operators@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.2.tgz#222348c080a1678e0e74ea63fe76f275882d1fd7" + integrity sha512-1JAZtUrqYyGsS7IDmFeaem+/LJqujfLZ2weLR9ugB0ufUPjzf8cguyVT1g5im7f7RXxuLq1xUxEzvm68uYRtGg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-private-methods@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" - integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz#425b11dc62fc26939a2ab42cbba680bdf5734546" + integrity sha512-ebR0zU9OvI2N4qiAC38KIAK75KItpIPTpAtd2r4OZmMFeKbKJpUFLYP2EuDut82+BmYi8sz42B+TfTptJ9iG5Q== dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" - integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== +"@babel/plugin-proposal-numeric-separator@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz#82b4cc06571143faf50626104b335dd71baa4f9e" + integrity sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-syntax-async-generators@^7.8.0": +"@babel/plugin-proposal-object-rest-spread@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.4.tgz#0e2b4de419915dc0b409378e829412e2031777c4" + integrity sha512-AYosOWBlyyXEagrPRfLJ1enStufsr7D1+ddpj8OLi9k7B6+NdZ0t/9V7Fh+wJ4g2Jol8z2JkgczYqtWrZd4vbA== + dependencies: + "@babel/compat-data" "^7.14.4" + "@babel/helper-compilation-targets" "^7.14.4" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.14.2" + +"@babel/plugin-proposal-optional-catch-binding@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.2.tgz#150d4e58e525b16a9a1431bd5326c4eed870d717" + integrity sha512-XtkJsmJtBaUbOxZsNk0Fvrv8eiqgneug0A6aqLFZ4TSkar2L5dSXWcnUKHgmjJt49pyB/6ZHvkr3dPgl9MOWRQ== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz#df8171a8b9c43ebf4c1dabe6311b432d83e1b34e" + integrity sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" + integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-proposal-private-property-in-object@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz#b1a1f2030586b9d3489cc26179d2eb5883277636" + integrity sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-private-property-in-object" "^7.14.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" + integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" - integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz#8e3d674b0613e67975ceac2776c97b60cafc5c9c" + integrity sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-dynamic-import@^7.8.0": +"@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== @@ -410,7 +448,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-json-strings@^7.8.0": +"@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== @@ -424,7 +462,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== @@ -438,360 +476,369 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.8.0": +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.8.0": +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-chaining@^7.8.0": +"@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" - integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== +"@babel/plugin-syntax-private-property-in-object@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz#762a4babec61176fec6c88480dec40372b140c0b" + integrity sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-arrow-functions@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" - integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== +"@babel/plugin-syntax-top-level-await@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" + integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-async-to-generator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" - integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== +"@babel/plugin-transform-arrow-functions@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" + integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-block-scoped-functions@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" - integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== +"@babel/plugin-transform-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" + integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" -"@babel/plugin-transform-block-scoping@^7.10.4": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz#5b7efe98852bef8d652c0b28144cd93a9e4b5215" - integrity sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew== +"@babel/plugin-transform-block-scoped-functions@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" + integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-classes@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" - integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== +"@babel/plugin-transform-block-scoping@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.4.tgz#caf140b0b2e2462c509553d140e6d0abefb61ed8" + integrity sha512-5KdpkGxsZlTk+fPleDtGKsA+pon28+ptYmMO8GBSa5fHERCJWAzj50uAfCKBqq42HO+Zot6JF1x37CRprwmN4g== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-define-map" "^7.10.4" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-classes@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.4.tgz#a83c15503fc71a0f99e876fdce7dadbc6575ec3a" + integrity sha512-p73t31SIj6y94RDVX57rafVjttNr8MvKEgs5YFatNB/xC68zM3pyosuOEcQmYsYlyQaGY9R7rAULVRcat5FKJQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.14.2" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-replace-supers" "^7.14.4" + "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" - integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== +"@babel/plugin-transform-computed-properties@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" + integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-destructuring@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" - integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== +"@babel/plugin-transform-destructuring@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.4.tgz#acbec502e9951f30f4441eaca1d2f29efade59ed" + integrity sha512-JyywKreTCGTUsL1OKu1A3ms/R1sTP0WxbpXlALeGzF53eB3bxtNkYdMj9SDgK7g6ImPy76J5oYYKoTtQImlhQA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" - integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== +"@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" + integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-duplicate-keys@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" - integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== +"@babel/plugin-transform-duplicate-keys@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" + integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-exponentiation-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" - integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== +"@babel/plugin-transform-exponentiation-operator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" + integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-for-of@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" - integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== +"@babel/plugin-transform-for-of@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" + integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" - integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== +"@babel/plugin-transform-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" + integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" - integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== +"@babel/plugin-transform-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" + integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-member-expression-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" - integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== +"@babel/plugin-transform-member-expression-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" + integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-modules-amd@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" - integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== +"@babel/plugin-transform-modules-amd@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.2.tgz#6622806fe1a7c07a1388444222ef9535f2ca17b0" + integrity sha512-hPC6XBswt8P3G2D1tSV2HzdKvkqOpmbyoy+g73JG0qlF/qx2y3KaMmXb1fLrpmWGLZYA0ojCvaHdzFWjlmV+Pw== dependencies: - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-transforms" "^7.14.2" + "@babel/helper-plugin-utils" "^7.13.0" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" - integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== +"@babel/plugin-transform-modules-commonjs@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161" + integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ== dependencies: - "@babel/helper-module-transforms" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-simple-access" "^7.13.12" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85" - integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw== +"@babel/plugin-transform-modules-systemjs@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" + integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A== dependencies: - "@babel/helper-hoist-variables" "^7.10.4" - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-hoist-variables" "^7.13.0" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-identifier" "^7.12.11" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" - integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== +"@babel/plugin-transform-modules-umd@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz#2f8179d1bbc9263665ce4a65f305526b2ea8ac34" + integrity sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw== dependencies: - "@babel/helper-module-transforms" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" - integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" + integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" -"@babel/plugin-transform-new-target@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" - integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== +"@babel/plugin-transform-new-target@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" + integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-object-super@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" - integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== +"@babel/plugin-transform-object-super@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" + integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-replace-supers" "^7.12.13" -"@babel/plugin-transform-parameters@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a" - integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw== +"@babel/plugin-transform-parameters@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz#e4290f72e0e9e831000d066427c4667098decc31" + integrity sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A== dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-property-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" - integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== +"@babel/plugin-transform-property-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" + integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-regenerator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" - integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== +"@babel/plugin-transform-regenerator@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39" + integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" - integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== +"@babel/plugin-transform-reserved-words@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" + integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-shorthand-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" - integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== +"@babel/plugin-transform-shorthand-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" + integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-spread@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" - integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== +"@babel/plugin-transform-spread@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" + integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" -"@babel/plugin-transform-sticky-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" - integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== +"@babel/plugin-transform-sticky-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" + integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-regex" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-template-literals@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c" - integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw== +"@babel/plugin-transform-template-literals@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" + integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-typeof-symbol@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" - integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== +"@babel/plugin-transform-typeof-symbol@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" + integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-unicode-escapes@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" - integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== +"@babel/plugin-transform-unicode-escapes@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" + integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-unicode-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" - integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== +"@babel/plugin-transform-unicode-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" + integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/preset-env@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272" - integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA== - dependencies: - "@babel/compat-data" "^7.11.0" - "@babel/helper-compilation-targets" "^7.10.4" - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-proposal-async-generator-functions" "^7.10.4" - "@babel/plugin-proposal-class-properties" "^7.10.4" - "@babel/plugin-proposal-dynamic-import" "^7.10.4" - "@babel/plugin-proposal-export-namespace-from" "^7.10.4" - "@babel/plugin-proposal-json-strings" "^7.10.4" - "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" - "@babel/plugin-proposal-numeric-separator" "^7.10.4" - "@babel/plugin-proposal-object-rest-spread" "^7.11.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" - "@babel/plugin-proposal-optional-chaining" "^7.11.0" - "@babel/plugin-proposal-private-methods" "^7.10.4" - "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.4.tgz#73fc3228c59727e5e974319156f304f0d6685a2d" + integrity sha512-GwMMsuAnDtULyOtuxHhzzuSRxFeP0aR/LNzrHRzP8y6AgDNgqnrfCCBm/1cRdTU75tRs28Eh76poHLcg9VF0LA== + dependencies: + "@babel/compat-data" "^7.14.4" + "@babel/helper-compilation-targets" "^7.14.4" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-option" "^7.12.17" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12" + "@babel/plugin-proposal-async-generator-functions" "^7.14.2" + "@babel/plugin-proposal-class-properties" "^7.13.0" + "@babel/plugin-proposal-class-static-block" "^7.14.3" + "@babel/plugin-proposal-dynamic-import" "^7.14.2" + "@babel/plugin-proposal-export-namespace-from" "^7.14.2" + "@babel/plugin-proposal-json-strings" "^7.14.2" + "@babel/plugin-proposal-logical-assignment-operators" "^7.14.2" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.2" + "@babel/plugin-proposal-numeric-separator" "^7.14.2" + "@babel/plugin-proposal-object-rest-spread" "^7.14.4" + "@babel/plugin-proposal-optional-catch-binding" "^7.14.2" + "@babel/plugin-proposal-optional-chaining" "^7.14.2" + "@babel/plugin-proposal-private-methods" "^7.13.0" + "@babel/plugin-proposal-private-property-in-object" "^7.14.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.12.13" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.10.4" - "@babel/plugin-transform-arrow-functions" "^7.10.4" - "@babel/plugin-transform-async-to-generator" "^7.10.4" - "@babel/plugin-transform-block-scoped-functions" "^7.10.4" - "@babel/plugin-transform-block-scoping" "^7.10.4" - "@babel/plugin-transform-classes" "^7.10.4" - "@babel/plugin-transform-computed-properties" "^7.10.4" - "@babel/plugin-transform-destructuring" "^7.10.4" - "@babel/plugin-transform-dotall-regex" "^7.10.4" - "@babel/plugin-transform-duplicate-keys" "^7.10.4" - "@babel/plugin-transform-exponentiation-operator" "^7.10.4" - "@babel/plugin-transform-for-of" "^7.10.4" - "@babel/plugin-transform-function-name" "^7.10.4" - "@babel/plugin-transform-literals" "^7.10.4" - "@babel/plugin-transform-member-expression-literals" "^7.10.4" - "@babel/plugin-transform-modules-amd" "^7.10.4" - "@babel/plugin-transform-modules-commonjs" "^7.10.4" - "@babel/plugin-transform-modules-systemjs" "^7.10.4" - "@babel/plugin-transform-modules-umd" "^7.10.4" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" - "@babel/plugin-transform-new-target" "^7.10.4" - "@babel/plugin-transform-object-super" "^7.10.4" - "@babel/plugin-transform-parameters" "^7.10.4" - "@babel/plugin-transform-property-literals" "^7.10.4" - "@babel/plugin-transform-regenerator" "^7.10.4" - "@babel/plugin-transform-reserved-words" "^7.10.4" - "@babel/plugin-transform-shorthand-properties" "^7.10.4" - "@babel/plugin-transform-spread" "^7.11.0" - "@babel/plugin-transform-sticky-regex" "^7.10.4" - "@babel/plugin-transform-template-literals" "^7.10.4" - "@babel/plugin-transform-typeof-symbol" "^7.10.4" - "@babel/plugin-transform-unicode-escapes" "^7.10.4" - "@babel/plugin-transform-unicode-regex" "^7.10.4" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.11.5" - browserslist "^4.12.0" - core-js-compat "^3.6.2" - invariant "^2.2.2" - levenary "^1.1.1" - semver "^5.5.0" - -"@babel/preset-modules@^0.1.3": + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.0" + "@babel/plugin-syntax-top-level-await" "^7.12.13" + "@babel/plugin-transform-arrow-functions" "^7.13.0" + "@babel/plugin-transform-async-to-generator" "^7.13.0" + "@babel/plugin-transform-block-scoped-functions" "^7.12.13" + "@babel/plugin-transform-block-scoping" "^7.14.4" + "@babel/plugin-transform-classes" "^7.14.4" + "@babel/plugin-transform-computed-properties" "^7.13.0" + "@babel/plugin-transform-destructuring" "^7.14.4" + "@babel/plugin-transform-dotall-regex" "^7.12.13" + "@babel/plugin-transform-duplicate-keys" "^7.12.13" + "@babel/plugin-transform-exponentiation-operator" "^7.12.13" + "@babel/plugin-transform-for-of" "^7.13.0" + "@babel/plugin-transform-function-name" "^7.12.13" + "@babel/plugin-transform-literals" "^7.12.13" + "@babel/plugin-transform-member-expression-literals" "^7.12.13" + "@babel/plugin-transform-modules-amd" "^7.14.2" + "@babel/plugin-transform-modules-commonjs" "^7.14.0" + "@babel/plugin-transform-modules-systemjs" "^7.13.8" + "@babel/plugin-transform-modules-umd" "^7.14.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" + "@babel/plugin-transform-new-target" "^7.12.13" + "@babel/plugin-transform-object-super" "^7.12.13" + "@babel/plugin-transform-parameters" "^7.14.2" + "@babel/plugin-transform-property-literals" "^7.12.13" + "@babel/plugin-transform-regenerator" "^7.13.15" + "@babel/plugin-transform-reserved-words" "^7.12.13" + "@babel/plugin-transform-shorthand-properties" "^7.12.13" + "@babel/plugin-transform-spread" "^7.13.0" + "@babel/plugin-transform-sticky-regex" "^7.12.13" + "@babel/plugin-transform-template-literals" "^7.13.0" + "@babel/plugin-transform-typeof-symbol" "^7.12.13" + "@babel/plugin-transform-unicode-escapes" "^7.12.13" + "@babel/plugin-transform-unicode-regex" "^7.12.13" + "@babel/preset-modules" "^0.1.4" + "@babel/types" "^7.14.4" + babel-plugin-polyfill-corejs2 "^0.2.0" + babel-plugin-polyfill-corejs3 "^0.2.0" + babel-plugin-polyfill-regenerator "^0.2.0" + core-js-compat "^3.9.0" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.4": version "0.1.4" resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== @@ -802,55 +849,53 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/register@^7.10.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.11.5.tgz#79becf89e0ddd0fba8b92bc279bc0f5d2d7ce2ea" - integrity sha512-CAml0ioKX+kOAvBQDHa/+t1fgOt3qkTIz0TrRtRAT6XY0m5qYZXR85k6/sLCNPMGhYDlCFHCYuU0ybTJbvlC6w== +"@babel/register@^7.13.16": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.13.16.tgz#ae3ab0b55c8ec28763877383c454f01521d9a53d" + integrity sha512-dh2t11ysujTwByQjXNgJ48QZ2zcXKQVdV8s0TbeMI0flmtGWCdTwK9tJiACHXPLmncm5+ktNn/diojA45JE4jg== dependencies: + clone-deep "^4.0.1" find-cache-dir "^2.0.0" - lodash "^4.17.19" make-dir "^2.1.0" pirates "^4.0.0" source-map-support "^0.5.16" -"@babel/runtime@^7.8.4": - version "7.11.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" - integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== +"@babel/runtime@^7.14.0", "@babel/runtime@^7.8.4": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" + integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" - integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.5" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.11.5" - "@babel/types" "^7.11.5" +"@babel/template@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" + integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/parser" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b" + integrity sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.14.2" + "@babel/helper-function-name" "^7.14.2" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.14.2" + "@babel/types" "^7.14.2" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.19" -"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.4": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" - integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== +"@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.2", "@babel/types@^7.14.4", "@babel/types@^7.4.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.4.tgz#bfd6980108168593b38b3eb48a24aa026b919bc0" + integrity sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw== dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.19" + "@babel/helper-validator-identifier" "^7.14.0" to-fast-properties "^2.0.0" "@balancer-labs/sor@^0.3.3": @@ -870,10 +915,10 @@ enabled "2.0.x" kuler "^2.0.0" -"@eslint/eslintrc@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.1.3.tgz#7d1a2b2358552cc04834c0979bd4275362e37085" - integrity sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA== +"@eslint/eslintrc@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14" + integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -882,347 +927,352 @@ ignore "^4.0.6" import-fresh "^3.2.1" js-yaml "^3.13.1" - lodash "^4.17.19" minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@ethersproject/abi@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.5.tgz#6e7bbf9d014791334233ba18da85331327354aa1" - integrity sha512-FNx6UMm0LnmCMFzN3urohFwZpjbUHPvc/O60h4qkF4yiJxLJ/G7QOSPjkHQ/q/QibagR4S7OKQawRy0NcvWa9w== - dependencies: - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/abstract-provider@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.4.tgz#ef12df8cb5e66d0d47b567ad6ed642d682043773" - integrity sha512-EOCHUTS8jOE3WZlA1pq9b/vQwKDyDzMy4gXeAv0wZecH1kwUkD0++x8avxeSYoWI+aJn62P1FVV9B6r9pM56kQ== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" - -"@ethersproject/abstract-signer@^5.0.4": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.5.tgz#d1cdea6b0b82fb8e4a83f6899ba84d3dc3bb6e66" - integrity sha512-nwSZKtCTKhJADlW42c+a//lWxQlnA7jYLTnabJ3YCfgGU6ic9jnT9nRDlAyT1U3kCMeqPL7fTcKbdWCVrM0xsw== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/address@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.4.tgz#8669bcbd02f4b64f4cede0a10e84df6d964ec9d3" - integrity sha512-CIjAeG6zNehbpJTi0sgwUvaH2ZICiAV9XkCBaFy5tjuEVFpQNeqd6f+B7RowcNO7Eut+QbhcQ5CVLkmP5zhL9A== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/rlp" "^5.0.3" - bn.js "^4.4.0" - -"@ethersproject/base64@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.3.tgz#d0aaa32c9ab08e2d62a6238581607ab6e929297e" - integrity sha512-sFq+/UwGCQsLxMvp7yO7yGWni87QXoV3C3IfjqUSY2BHkbZbCDm+PxZviUkiKf+edYZ2Glp0XnY7CgKSYUN9qw== - dependencies: - "@ethersproject/bytes" "^5.0.4" - -"@ethersproject/basex@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.3.tgz#f8c9bc449a089131f52cfa8698cf77bc22e27e32" - integrity sha512-EvoER+OXsMAZlvbC0M/9UTxjvbBvTccYCI+uCAhXw+eS1+SUdD4v7ekAFpVX78rPLrLZB1vChKMm6vPHIu3WRA== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/bignumber@^5.0.7": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.7.tgz#720b3e3df3e125a99669ee869478106d0afe7b76" - integrity sha512-wwKgDJ+KA7IpgJwc8Fc0AjKIRuDskKA2cque29/+SgII9/1K/38JpqVNPKIovkLwTC2DDofIyzHcxeaKpMFouQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - bn.js "^4.4.0" - -"@ethersproject/bytes@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.4.tgz#328d9d929a3e970964ecf5d62e12568a187189f1" - integrity sha512-9R6A6l9JN8x1U4s1dJCR+9h3MZTT3xQofr/Xx8wbDvj6NnY4CbBB0o8ZgHXvR74yV90pY2EzCekpkMBJnRzkSw== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/constants@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.4.tgz#9ddaa5f3c738a94e5adc4b3f71b36206fa5cdf88" - integrity sha512-Df32lcXDHPgZRPgp1dgmByNbNe4Ki1QoXR+wU61on5nggQGTqWR1Bb7pp9VtI5Go9kyE/JflFc4Te6o9MvYt8A== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - -"@ethersproject/contracts@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.0.4.tgz#27a2d7e3a7eef9bd8d006824ac2a74157b523988" - integrity sha512-gfOZNgLiO9e1D/hmQ4sEyqoolw6jDFVfqirGJv3zyFKNyX+lAXLN7YAZnnWVmp4GU1jiMtSqQKjpWp7r6ihs3Q== - dependencies: - "@ethersproject/abi" "^5.0.5" - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/hash@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.4.tgz#385642786405d236f3d2f1acdfaf250ab519cdac" - integrity sha512-VCs/bFBU8AQFhHcT1cQH6x7a4zjulR6fJmAOcPxUgrN7bxOQ7QkpBKF+YCDJhFtkLdaljIsr/r831TuWU4Ysfg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/hdnode@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.0.4.tgz#9c07a87781b24b9cae3507fe9404361c5870f1b7" - integrity sha512-eHmpNLvasfB4xbmQUvKXOsGF4ekjIKJH/eZm7fc6nIdMci9u5ERooSSRLjs9Dsa5QuJf6YD4DbqeJsT71n47iw== - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - -"@ethersproject/json-wallets@^5.0.6": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.0.6.tgz#c6c1818dcab18ecf3f37fa59ca504b9bc162d559" - integrity sha512-BPCfyGdwOUSp6+xA59IaZ/2pUWrUOL5Z9HuCh8YLsJzkuyBJQN0j+z/PmhIiZ7X8ilhuE+pRUwXb42U/R39fig== - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" +"@ethersproject/abi@5.3.0", "@ethersproject/abi@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.3.0.tgz#00f0647d906edcd32c50b16ab9c98f83e208dcf1" + integrity sha512-NaT4UacjOwca8qCG/gv8k+DgTcWu49xlrvdhr/p8PTFnoS8e3aMWqjI3znFME5Txa/QWXDrg2/heufIUue9rtw== + dependencies: + "@ethersproject/address" "^5.3.0" + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/constants" "^5.3.0" + "@ethersproject/hash" "^5.3.0" + "@ethersproject/keccak256" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/strings" "^5.3.0" + +"@ethersproject/abstract-provider@5.3.0", "@ethersproject/abstract-provider@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.3.0.tgz#f4c0ae4a4cef9f204d7781de805fd44b72756c81" + integrity sha512-1+MLhGP1GwxBDBNwMWVmhCsvKwh4gK7oIfOrmlmePNeskg1NhIrYssraJBieaFNHUYfKEd/1DjiVZMw8Qu5Cxw== + dependencies: + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/networks" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/transactions" "^5.3.0" + "@ethersproject/web" "^5.3.0" + +"@ethersproject/abstract-signer@5.3.0", "@ethersproject/abstract-signer@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.3.0.tgz#05172b653e15b535ed5854ef5f6a72f4b441052d" + integrity sha512-w8IFwOYqiPrtvosPuArZ3+QPR2nmdVTRrVY8uJYL3NNfMmQfTy3V3l2wbzX47UUlNbPJY+gKvzJAyvK1onZxJg== + dependencies: + "@ethersproject/abstract-provider" "^5.3.0" + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + +"@ethersproject/address@5.3.0", "@ethersproject/address@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.3.0.tgz#e53b69eacebf332e8175de814c5e6507d6932518" + integrity sha512-29TgjzEBK+gUEUAOfWCG7s9IxLNLCqvr+oDSk6L9TXD0VLvZJKhJV479tKQqheVA81OeGxfpdxYtUVH8hqlCvA== + dependencies: + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/keccak256" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/rlp" "^5.3.0" + +"@ethersproject/base64@5.3.0", "@ethersproject/base64@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.3.0.tgz#b831fb35418b42ad24d943c557259062b8640824" + integrity sha512-JIqgtOmgKcbc2sjGWTXyXktqUhvFUDte8fPVsAaOrcPiJf6YotNF+nsrOYGC9pbHBEGSuSBp3QR0varkO8JHEw== + dependencies: + "@ethersproject/bytes" "^5.3.0" + +"@ethersproject/basex@5.3.0", "@ethersproject/basex@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.3.0.tgz#02dea3ab8559ae625c6d548bc11773432255c916" + integrity sha512-8J4nS6t/SOnoCgr3DF5WCSRLC5YwTKYpZWJqeyYQLX+86TwPhtzvHXacODzcDII9tWKhVg6g0Bka8JCBWXsCiQ== + dependencies: + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + +"@ethersproject/bignumber@5.3.0", "@ethersproject/bignumber@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.3.0.tgz#74ab2ec9c3bda4e344920565720a6ee9c794e9db" + integrity sha512-5xguJ+Q1/zRMgHgDCaqAexx/8DwDVLRemw2i6uR8KyGjwGdXI8f32QZZ1cKGucBN6ekJvpUpHy6XAuQnTv0mPA== + dependencies: + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + bn.js "^4.11.9" + +"@ethersproject/bytes@5.3.0", "@ethersproject/bytes@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.3.0.tgz#473e0da7f831d535b2002be05e6f4ca3729a1bc9" + integrity sha512-rqLJjdVqCcn7glPer7Fxh87PRqlnRScVAoxcIP3PmOUNApMWJ6yRdOFfo2KvPAdO7Le3yEI1o0YW+Yvr7XCYvw== + dependencies: + "@ethersproject/logger" "^5.3.0" + +"@ethersproject/constants@5.3.0", "@ethersproject/constants@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.3.0.tgz#a5d6d86c0eec2c64c3024479609493b9afb3fc77" + integrity sha512-4y1feNOwEpgjAfiCFWOHznvv6qUF/H6uI0UKp8xdhftb+H+FbKflXg1pOgH5qs4Sr7EYBL+zPyPb+YD5g1aEyw== + dependencies: + "@ethersproject/bignumber" "^5.3.0" + +"@ethersproject/contracts@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.3.0.tgz#ad699a3abaae30bfb6422cf31813a663b2d4099c" + integrity sha512-eDyQ8ltykvyQqnGZxb/c1e0OnEtzqXhNNC4BX8nhYBCaoBrYYuK/1fLmyEvc5+XUMoxNhwpYkoSSwvPLci7/Zg== + dependencies: + "@ethersproject/abi" "^5.3.0" + "@ethersproject/abstract-provider" "^5.3.0" + "@ethersproject/abstract-signer" "^5.3.0" + "@ethersproject/address" "^5.3.0" + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/constants" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/transactions" "^5.3.0" + +"@ethersproject/hash@5.3.0", "@ethersproject/hash@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.3.0.tgz#f65e3bf3db3282df4da676db6cfa049535dd3643" + integrity sha512-gAFZSjUPQ32CIfoKSMtMEQ+IO0kQxqhwz9fCIFt2DtAq2u4pWt8mL9Z5P0r6KkLcQU8LE9FmuPPyd+JvBzmr1w== + dependencies: + "@ethersproject/abstract-signer" "^5.3.0" + "@ethersproject/address" "^5.3.0" + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/keccak256" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/strings" "^5.3.0" + +"@ethersproject/hdnode@5.3.0", "@ethersproject/hdnode@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.3.0.tgz#26fed65ffd5c25463fddff13f5fb4e5617553c94" + integrity sha512-zLmmtLNoDMGoYRdjOab01Zqkvp+TmZyCGDAMQF1Bs3yZyBs/kzTNi1qJjR1jVUcPP5CWGtjFwY8iNG8oNV9J8g== + dependencies: + "@ethersproject/abstract-signer" "^5.3.0" + "@ethersproject/basex" "^5.3.0" + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/pbkdf2" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/sha2" "^5.3.0" + "@ethersproject/signing-key" "^5.3.0" + "@ethersproject/strings" "^5.3.0" + "@ethersproject/transactions" "^5.3.0" + "@ethersproject/wordlists" "^5.3.0" + +"@ethersproject/json-wallets@5.3.0", "@ethersproject/json-wallets@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.3.0.tgz#7b1a5ff500c12aa8597ae82c8939837b0449376e" + integrity sha512-/xwbqaIb5grUIGNmeEaz8GdcpmDr++X8WT4Jqcclnxow8PXCUHFeDxjf3O+nSuoqOYG/Ds0+BI5xuQKbva6Xkw== + dependencies: + "@ethersproject/abstract-signer" "^5.3.0" + "@ethersproject/address" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/hdnode" "^5.3.0" + "@ethersproject/keccak256" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/pbkdf2" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/random" "^5.3.0" + "@ethersproject/strings" "^5.3.0" + "@ethersproject/transactions" "^5.3.0" aes-js "3.0.0" scrypt-js "3.0.1" -"@ethersproject/keccak256@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.3.tgz#f094a8fca3bb913c044593c4f382be424292e588" - integrity sha512-VhW3mgZMBZlETV6AyOmjNeNG+Pg68igiKkPpat8/FZl0CKnfgQ+KZQZ/ee1vT+X0IUM8/djqnei6btmtbA27Ug== +"@ethersproject/keccak256@5.3.0", "@ethersproject/keccak256@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.3.0.tgz#fb5cd36bdfd6fa02e2ea84964078a9fc6bd731be" + integrity sha512-Gv2YqgIUmRbYVNIibafT0qGaeGYLIA/EdWHJ7JcVxVSs2vyxafGxOJ5VpSBHWeOIsE6OOaCelYowhuuTicgdFQ== dependencies: - "@ethersproject/bytes" "^5.0.4" + "@ethersproject/bytes" "^5.3.0" js-sha3 "0.5.7" -"@ethersproject/logger@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.5.tgz#e3ba3d0bcf9f5be4da5f043b1e328eb98b80002f" - integrity sha512-gJj72WGzQhUtCk6kfvI8elTaPOQyMvrMghp/nbz0ivTo39fZ7IjypFh/ySDeUSdBNplAwhzWKKejQhdpyefg/w== - -"@ethersproject/networks@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.3.tgz#c4ebe56e79ca399247382627e50a022aa68ece55" - integrity sha512-Gjpejul6XFetJXyvHCd37IiCC00203kYGU9sMaRMZcAcYKszCkbOeo/Q7Mmdr/fS7YBbB5iTOahDJWiRLu/b7A== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/pbkdf2@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.0.3.tgz#f9eca284a458cd11179d407884c595412d8d2775" - integrity sha512-asc+YgJn7v7GKWYXGz3GM1d9XYI2HvdCw1cLEow2niEC9BfYA29rr1exz100zISk95GIU1YP2zV//zHsMtWE5Q== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/sha2" "^5.0.3" - -"@ethersproject/properties@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.3.tgz#991aef39a5f87d4645cee76cec4df868bfb08be6" - integrity sha512-wLCSrbywkQgTO6tIF9ZdKsH9AIxPEqAJF/z5xcPkz1DK4mMAZgAXRNw1MrKYhyb+7CqNHbj3vxenNKFavGY/IA== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/providers@^5.0.8": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.0.9.tgz#88b48596dcfb0848a89da3160d2e2a055fc899f6" - integrity sha512-UtGrlJxekFNV7lriPOxQbnYminyiwTgjHMPX83pG7N/W/t+PekQK8V9rdlvMr2bRyGgafHml0ZZMaTV4FxiBYg== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" +"@ethersproject/logger@5.3.0", "@ethersproject/logger@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.3.0.tgz#7a69fa1d4ca0d4b7138da1627eb152f763d84dd0" + integrity sha512-8bwJ2gxJGkZZnpQSq5uSiZSJjyVTWmlGft4oH8vxHdvO1Asy4TwVepAhPgxIQIMxXZFUNMych1YjIV4oQ4I7dA== + +"@ethersproject/networks@5.3.0", "@ethersproject/networks@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.3.0.tgz#d8ad06eb107c69fb8651f4c81ddd0e88944fdfea" + integrity sha512-XGbD9MMgqrR7SYz8o6xVgdG+25v7YT5vQG8ZdlcLj2I7elOBM7VNeQrnxfSN7rWQNcqu2z80OM29gGbQz+4Low== + dependencies: + "@ethersproject/logger" "^5.3.0" + +"@ethersproject/pbkdf2@5.3.0", "@ethersproject/pbkdf2@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.3.0.tgz#8adbb41489c3c9f319cc44bc7d3e6095fd468dc8" + integrity sha512-Q9ChVU6gBFiex0FSdtzo4b0SAKz3ZYcYVFLrEWHL0FnHvNk3J3WgAtRNtBQGQYn/T5wkoTdZttMbfBkFlaiWcA== + dependencies: + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/sha2" "^5.3.0" + +"@ethersproject/properties@5.3.0", "@ethersproject/properties@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.3.0.tgz#feef4c4babeb7c10a6b3449575016f4ad2c092b2" + integrity sha512-PaHxJyM5/bfusk6vr3yP//JMnm4UEojpzuWGTmtL5X4uNhNnFNvlYilZLyDr4I9cTkIbipCMsAuIcXWsmdRnEw== + dependencies: + "@ethersproject/logger" "^5.3.0" + +"@ethersproject/providers@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.3.0.tgz#bccb49f1073a7d56e24f49abb14bb281c9b08636" + integrity sha512-HtL+DEbzPcRyfrkrMay7Rk/4he+NbUpzI/wHXP4Cqtra82nQOnqqCgTQc4HbdDrl75WVxG/JRMFhyneIPIMZaA== + dependencies: + "@ethersproject/abstract-provider" "^5.3.0" + "@ethersproject/abstract-signer" "^5.3.0" + "@ethersproject/address" "^5.3.0" + "@ethersproject/basex" "^5.3.0" + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/constants" "^5.3.0" + "@ethersproject/hash" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/networks" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/random" "^5.3.0" + "@ethersproject/rlp" "^5.3.0" + "@ethersproject/sha2" "^5.3.0" + "@ethersproject/strings" "^5.3.0" + "@ethersproject/transactions" "^5.3.0" + "@ethersproject/web" "^5.3.0" bech32 "1.1.4" - ws "7.2.3" - -"@ethersproject/random@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.0.3.tgz#ec16546fffdc10b9082f1207bd3a09f54cbcf5e6" - integrity sha512-pEhWRbgNeAY1oYk4nIsEtCTh9TtLsivIDbOX11n+DLZLYM3c8qCLxThXtsHwVsMs1JHClZr5auYC4YxtVVzO/A== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/rlp@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.3.tgz#841a5edfdf725f92155fe74424f5510c9043c13a" - integrity sha512-Hz4yyA/ilGafASAqtTlLWkA/YqwhQmhbDAq2LSIp1AJNx+wtbKWFAKSckpeZ+WG/xZmT+fw5OFKK7a5IZ4DR5g== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/sha2@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.0.3.tgz#52c16edc1135d0ec7d242d88eed035dae72800c0" - integrity sha512-B1U9UkgxhUlC1J4sFUL2GwTo33bM2i/aaD3aiYdTh1FEXtGfqYA89KN1DJ83n+Em8iuvyiBRk6u30VmgqlHeHA== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - hash.js "1.1.3" - -"@ethersproject/signing-key@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.4.tgz#a5334ce8a52d4e9736dc8fb6ecc384704ecf8783" - integrity sha512-I6pJoga1IvhtjYK5yXzCjs4ZpxrVbt9ZRAlpEw0SW9UuV020YfJH5EIVEGR2evdRceS3nAQIggqbsXSkP8Y1Dg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - elliptic "6.5.3" - -"@ethersproject/solidity@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.0.4.tgz#67022cbfb50cb73b72d1739178537a9e798945bf" - integrity sha512-cUq1l8A+AgRkIItRoztC98Qx7b0bMNMzKX817fszDuGNsT2POAyP5knvuEt4Fx4IBcJREXoOjsGYFfjyK5Sa+w== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/strings@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.4.tgz#67cda604eee3ffcc004cb9f3bd03516e1c7b09a0" - integrity sha512-azXFHaNkDXzefhr4LVVzzDMFwj3kH9EOKlATu51HjxabQafuUyVLPFgmxRFmCynnAi0Bmmp7nr+qK1pVDgRDLQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/transactions@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.5.tgz#9a966f9ef4817b1752265d4efee0f1e9fd6aeaad" - integrity sha512-1Ga/QmbcB74DItggP8/DK1tggu4ErEvwTkIwIlUXUcvIAuRNXXE7kgQhlp+w1xA/SAQFhv56SqCoyqPiiLCvVA== - dependencies: - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - -"@ethersproject/units@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.0.4.tgz#e08876b54e1f6b362a841dcd986496a425875735" - integrity sha512-80d6skjDgiHLdbKOA9FVpzyMEPwbif40PbGd970JvcecVf48VjB09fUu37d6duG8DhRVyefRdX8nuVQLzcGGPw== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/wallet@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.0.4.tgz#b414ae2870fc0ea10808330f0ab3c5a1ac9e34e1" - integrity sha512-h/3mdy6HZVketHbs6ZP/WjHDz+rtTIE3qZrko2MVeafjgDcYWaHcVmhsPq4LGqxginhr191a4dkJDNeQrQZWOw== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/json-wallets" "^5.0.6" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - -"@ethersproject/web@^5.0.6": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.7.tgz#ab8ccffa9cee9469a8b49af8b8fee30e384e59d8" - integrity sha512-BM8FdGrzdcULYaOIyMXDKvxv+qOwGne8FKpPxUrifZIWAWPrq/y+oBOZlzadIKsP3wvYbAcMN2CgOLO1E3yIfw== - dependencies: - "@ethersproject/base64" "^5.0.3" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/wordlists@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.0.4.tgz#76a7e1dfd95aea645f6be2c1932b3f89b7f0c4ce" - integrity sha512-z/NsGqdYFvpeG6vPLxuD0pYNR5lLhQAy+oLVqg6G0o1c/OoL5J/a0iDOAFvnacQphc3lMP52d1LEX3YGoy2oBQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" + ws "7.4.6" + +"@ethersproject/random@5.3.0", "@ethersproject/random@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.3.0.tgz#7c46bf36e50cb0d0550bc8c666af8e1d4496dc1a" + integrity sha512-A5SL/4inutSwt3Fh2OD0x2gz+x6GHmuUnIPkR7zAiTidMD2N8F6tZdMF1hlQKWVCcVMWhEQg8mWijhEzm6BBYw== + dependencies: + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + +"@ethersproject/rlp@5.3.0", "@ethersproject/rlp@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.3.0.tgz#7cb93a7b5dfa69163894153c9d4b0d936f333188" + integrity sha512-oI0joYpsRanl9guDubaW+1NbcpK0vJ3F/6Wpcanzcnqq+oaW9O5E98liwkEDPcb16BUTLIJ+ZF8GPIHYxJ/5Pw== + dependencies: + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + +"@ethersproject/sha2@5.3.0", "@ethersproject/sha2@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.3.0.tgz#209f9a1649f7d2452dcd5e5b94af43b7f3f42366" + integrity sha512-r5ftlwKcocYEuFz2JbeKOT5SAsCV4m1RJDsTOEfQ5L67ZC7NFDK5i7maPdn1bx4nPhylF9VAwxSrQ1esmwzylg== + dependencies: + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + hash.js "1.1.7" + +"@ethersproject/signing-key@5.3.0", "@ethersproject/signing-key@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.3.0.tgz#a96c88f8173e1abedfa35de32d3e5db7c48e5259" + integrity sha512-+DX/GwHAd0ok1bgedV1cKO0zfK7P/9aEyNoaYiRsGHpCecN7mhLqcdoUiUzE7Uz86LBsxm5ssK0qA1kBB47fbQ== + dependencies: + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + bn.js "^4.11.9" + elliptic "6.5.4" + hash.js "1.1.7" + +"@ethersproject/solidity@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.3.0.tgz#2a0b00b4aaaef99a080ddea13acab1fa35cd4a93" + integrity sha512-uLRBaNUiISHbut94XKewJgQh6UmydWTBp71I7I21pkjVXfZO2dJ5EOo3jCnumJc01M4LOm79dlNNmF3oGIvweQ== + dependencies: + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/keccak256" "^5.3.0" + "@ethersproject/sha2" "^5.3.0" + "@ethersproject/strings" "^5.3.0" + +"@ethersproject/strings@5.3.0", "@ethersproject/strings@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.3.0.tgz#a6b640aab56a18e0909f657da798eef890968ff0" + integrity sha512-j/AzIGZ503cvhuF2ldRSjB0BrKzpsBMtCieDtn4TYMMZMQ9zScJn9wLzTQl/bRNvJbBE6TOspK0r8/Ngae/f2Q== + dependencies: + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/constants" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + +"@ethersproject/transactions@5.3.0", "@ethersproject/transactions@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.3.0.tgz#49b86f2bafa4d0bdf8e596578fc795ee47c50458" + integrity sha512-cdfK8VVyW2oEBCXhURG0WQ6AICL/r6Gmjh0e4Bvbv6MCn/GBd8FeBH3rtl7ho+AW50csMKeGv3m3K1HSHB2jMQ== + dependencies: + "@ethersproject/address" "^5.3.0" + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/constants" "^5.3.0" + "@ethersproject/keccak256" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/rlp" "^5.3.0" + "@ethersproject/signing-key" "^5.3.0" + +"@ethersproject/units@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.3.0.tgz#c4d1493532ad3d4ddf6e2bc4f8c94a2db933a8f5" + integrity sha512-BkfccZGwfJ6Ob+AelpIrgAzuNhrN2VLp3AILnkqTOv+yBdsc83V4AYf25XC/u0rHnWl6f4POaietPwlMqP2vUg== + dependencies: + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/constants" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + +"@ethersproject/wallet@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.3.0.tgz#91946b470bd279e39ade58866f21f92749d062af" + integrity sha512-boYBLydG6671p9QoG6EinNnNzbm7DNOjVT20eV8J6HQEq4aUaGiA2CytF2vK+2rOEWbzhZqoNDt6AlkE1LlsTg== + dependencies: + "@ethersproject/abstract-provider" "^5.3.0" + "@ethersproject/abstract-signer" "^5.3.0" + "@ethersproject/address" "^5.3.0" + "@ethersproject/bignumber" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/hash" "^5.3.0" + "@ethersproject/hdnode" "^5.3.0" + "@ethersproject/json-wallets" "^5.3.0" + "@ethersproject/keccak256" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/random" "^5.3.0" + "@ethersproject/signing-key" "^5.3.0" + "@ethersproject/transactions" "^5.3.0" + "@ethersproject/wordlists" "^5.3.0" + +"@ethersproject/web@5.3.0", "@ethersproject/web@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.3.0.tgz#7959c403f6476c61515008d8f92da51c553a8ee1" + integrity sha512-Ni6/DHnY6k/TD41LEkv0RQDx4jqWz5e/RZvrSecsxGYycF+MFy2z++T/yGc2peRunLOTIFwEksgEGGlbwfYmhQ== + dependencies: + "@ethersproject/base64" "^5.3.0" + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/strings" "^5.3.0" + +"@ethersproject/wordlists@5.3.0", "@ethersproject/wordlists@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.3.0.tgz#45a0205f5178c1de33d316cb2ab7ed5eac3c06c5" + integrity sha512-JcwumCZcsUxgWpiFU/BRy6b4KlTRdOmYvOKZcAw/3sdF93/pZyPW5Od2hFkHS8oWp4xS06YQ+qHqQhdcxdHafQ== + dependencies: + "@ethersproject/bytes" "^5.3.0" + "@ethersproject/hash" "^5.3.0" + "@ethersproject/logger" "^5.3.0" + "@ethersproject/properties" "^5.3.0" + "@ethersproject/strings" "^5.3.0" "@perp/contract@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@perp/contract/-/contract-1.0.6.tgz#b423738d095a15fccd17de7bc46a531482a45d18" - integrity sha512-5exstpCstXpXSLaxY/hTVT3BtRF8UVJ2JgGN8abiFSKBg+aaQdBZ4qvsOzr4HQ0fkZSOlURL/JnOUDV04UrD5A== + version "1.1.0" + resolved "https://registry.yarnpkg.com/@perp/contract/-/contract-1.1.0.tgz#c1f2aa73e74bdf083560258ffc16e2fbcf632003" + integrity sha512-79O3DoGYtC6Nu9TnzC6aUTwCuEfe3+CIZr9a27Uh26MQ0jHkCq2Rc4sz35k3ChuN9zL2ZmrsAR+mO785QGZFpw== "@sindresorhus/is@^0.14.0": version "0.14.0" @@ -1237,23 +1287,22 @@ defer-to-connect "^1.0.1" "@terra-money/terra.js@^0.5.8": - version "0.5.8" - resolved "https://registry.yarnpkg.com/@terra-money/terra.js/-/terra.js-0.5.8.tgz#effd51631c596e67b782819dca924241d1903597" - integrity sha512-a+WqEgnxCIz0hCW/EhqF47TublEqPX/NdL5xNwve3sNFTjK7AqHcpVUS79hubimPy9HlDDZCSCF8YAXXJ7xfCQ== + version "0.5.13" + resolved "https://registry.yarnpkg.com/@terra-money/terra.js/-/terra.js-0.5.13.tgz#fbbfb00d32b7cdad8807ea8ee40b3a71a0deca50" + integrity sha512-v2B+VqVar6gryTfpHsusmDn2WIRT23xnTKsxFn6G20WIN5XCeRQa84cnAlZHuNP9w5ejuvRmoHX0Wg6g1DJo3g== dependencies: axios "^0.20.0" bech32 "^1.1.4" bip32 "^2.0.6" bip39 "^3.0.2" + bufferutil "^4.0.1" crypto-js "3.3.0" - decimal.js "^10.2.0" + decimal.js "^10.2.1" post-message-stream "^3.0.0" secp256k1 "^4.0.2" - -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + tmp "^0.2.1" + utf-8-validate "^5.0.2" + ws "^7.3.1" "@types/json5@^0.0.29": version "0.0.29" @@ -1301,31 +1350,41 @@ accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" -acorn-jsx@^5.2.0: +acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== acorn@^7.4.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" - integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== aes-js@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4: - version "6.12.5" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" - integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.1: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b" + integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + ansi-align@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" @@ -1348,25 +1407,24 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" -ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: - "@types/color-name" "^1.1.1" color-convert "^2.0.1" anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -1391,23 +1449,20 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= -array-includes@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" - integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== +array-includes@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" + integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0" + es-abstract "^1.18.0-next.2" + get-intrinsic "^1.1.1" is-string "^1.0.5" array-uniq@1.0.2: @@ -1415,30 +1470,29 @@ array-uniq@1.0.2: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.2.tgz#5fcc373920775723cfd64d65c64bef53bf9eba6d" integrity sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0= -array.prototype.flat@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" - integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== +array.prototype.flat@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" + integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + es-abstract "^1.18.0-next.1" -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== -available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== - dependencies: - array-filter "^1.0.0" +available-typed-arrays@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" + integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== axios@^0.20.0: version "0.20.0" @@ -1461,10 +1515,34 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" +babel-plugin-polyfill-corejs2@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" + integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.2.2" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz#7424a1682ee44baec817327710b1b094e5f8f7f5" + integrity sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.2" + core-js-compat "^3.9.1" + +babel-plugin-polyfill-regenerator@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" + integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.2" + balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^3.0.2: version "3.0.8" @@ -1484,14 +1562,14 @@ big.js@^5.2.2: integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== bignumber.js@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" - integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== + version "9.0.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" + integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA== binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bindings@^1.3.0: version "1.5.0" @@ -1514,19 +1592,19 @@ bip32@^2.0.6: wif "^2.0.6" bip39@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.2.tgz#2baf42ff3071fc9ddd5103de92e8f80d9257ee32" - integrity sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.4.tgz#5b11fed966840b5e1b8539f0f54ab6392969b2a0" + integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw== dependencies: "@types/node" "11.11.6" create-hash "^1.1.0" pbkdf2 "^3.0.9" randombytes "^2.0.1" -bn.js@^4.11.8, bn.js@^4.4.0: - version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" - integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== +bn.js@^4.11.8, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== body-parser@1.19.0, body-parser@^1.19.0: version "1.19.0" @@ -1573,20 +1651,21 @@ braces@~3.0.2: dependencies: fill-range "^7.0.1" -brorand@^1.0.1: +brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= -browserslist@^4.12.0, browserslist@^4.8.5: - version "4.14.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.3.tgz#381f9e7f13794b2eb17e1761b4f118e8ae665a53" - integrity sha512-GcZPC5+YqyPO4SFnz48/B0YaCwS47Q9iPChRGi6t7HhflKBcINzFrJvRfC+jp30sRMKxF+d4EHGs27Z0XP1NaQ== +browserslist@^4.16.6: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== dependencies: - caniuse-lite "^1.0.30001131" - electron-to-chromium "^1.3.570" - escalade "^3.1.0" - node-releases "^1.1.61" + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" bs58@^4.0.0: version "4.0.1" @@ -1609,6 +1688,13 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +bufferutil@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.3.tgz#66724b756bed23cd7c28c4d306d7994f9943cc6b" + integrity sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw== + dependencies: + node-gyp-build "^4.2.0" + bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" @@ -1627,6 +1713,14 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1637,10 +1731,10 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30001131: - version "1.0.30001133" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001133.tgz#ec564c5495311299eb05245e252d589a84acd95e" - integrity sha512-s3XAUFaC/ntDb1O3lcw9K8MPeOW7KO3z9+GzAoBxfz1B0VdacXPMKgFUtG4KIsgmnbexmi013s9miVu4h+qMHw== +caniuse-lite@^1.0.30001219: + version "1.0.30001233" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001233.tgz#b7cb4a377a4b12ed240d2fa5c792951a06e5f2c4" + integrity sha512-BmkbxLfStqiPA7IEzQpIk0UFZFf3A4E6fzjPJ6OR+bFC2L8ES9J8zGA/asoi47p8XDVkev+WJo2I2Nc8c/34Yg== capture-console@^1.0.1: version "1.0.1" @@ -1669,17 +1763,17 @@ chalk@^3.0.0: supports-color "^7.1.0" chalk@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" chokidar@^3.2.2: - version "3.4.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" - integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -1687,9 +1781,9 @@ chokidar@^3.2.2: is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.4.0" + readdirp "~3.5.0" optionalDependencies: - fsevents "~2.1.2" + fsevents "~2.3.1" ci-info@^2.0.0: version "2.0.0" @@ -1709,6 +1803,15 @@ cli-boxes@^2.2.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" @@ -1741,9 +1844,9 @@ color-name@^1.0.0, color-name@~1.1.4: integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== color-string@^1.5.2: - version "1.5.4" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6" - integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw== + version "1.5.5" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" + integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -1756,6 +1859,11 @@ color@3.0.x: color-convert "^1.9.1" color-string "^1.5.2" +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + colors@^1.2.1: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -1779,10 +1887,10 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= -complex.js@^2.0.11: - version "2.0.12" - resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.12.tgz#fa4df97d8928e5f7b6a86b35bdeecc3a3eda8a22" - integrity sha512-oQX99fwL6LrTVg82gDY1dIWXy6qZRnRL35N+YhIX0N7tSwsa0KFy6IEMHTNuCW4mP7FS7MEqZ/2I/afzYwPldw== +complex.js@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.13.tgz#00cf7ba082565e164813b7bbbb0ced5d2aba172a" + integrity sha512-UEWd3G3/kd3lJmsdLsDh9qfinJlujL4hIFn3Vo4/G5eqehPsgCHf2CLhFs77tVkOp2stt/jbNit7Q1XFANFltA== concat-map@0.0.1: version "0.0.1" @@ -1801,10 +1909,10 @@ configstore@^5.0.1: write-file-atomic "^3.0.0" xdg-basedir "^4.0.0" -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= +confusing-browser-globals@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz#30d1e7f3d1b882b25ec4933d1d1adac353d20a59" + integrity sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA== content-disposition@0.5.3: version "0.5.3" @@ -1835,18 +1943,18 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== -core-js-compat@^3.6.2: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" - integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== +core-js-compat@^3.9.0, core-js-compat@^3.9.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.13.1.tgz#05444caa8f153be0c67db03cf8adb8ec0964e58e" + integrity sha512-mdrcxc0WznfRd8ZicEZh1qVeJ2mu6bwQFh8YVUK48friy/FOwFV5EJj9/dlh+nMQ74YusdVfBFDuomKgUspxWQ== dependencies: - browserslist "^4.8.5" + browserslist "^4.16.6" semver "7.0.0" core-js@^3.2.1: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" - integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== + version "3.13.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.13.1.tgz#30303fabd53638892062d8b4e802cac7599e9fb7" + integrity sha512-JqveUc4igkqwStL2RTRn/EPFGBOfEZHxJl/8ej1mXJR75V3go2mFF4bmUYkEIT1rveHKnkUlcJX/c+f1TyIovQ== core-util-is@~1.0.0: version "1.0.2" @@ -1877,9 +1985,9 @@ create-hmac@^1.1.4, create-hmac@^1.1.7: sha.js "^2.4.8" cross-fetch@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" - integrity sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ== + version "3.1.4" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" + integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== dependencies: node-fetch "2.6.1" @@ -1909,17 +2017,17 @@ debug@2.6.9, debug@^2.2.0, debug@^2.6.9: dependencies: ms "2.0.0" -debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== +debug@^3.2.6, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" @@ -1928,11 +2036,6 @@ decimal.js-light@^2.5.0: resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== -decimal.js@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231" - integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw== - decimal.js@^10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" @@ -1977,13 +2080,12 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" - isarray "^1.0.0" doctrine@^3.0.0: version "3.0.0" @@ -2000,9 +2102,9 @@ dot-prop@^5.2.0: is-obj "^2.0.0" dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + version "8.6.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" + integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== duplexer3@^0.1.4: version "0.1.4" @@ -2014,23 +2116,23 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.570: - version "1.3.570" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.570.tgz#3f5141cc39b4e3892a276b4889980dabf1d29c7f" - integrity sha512-Y6OCoVQgFQBP5py6A/06+yWxUZHDlNr/gNDGatjH8AZqXl8X0tE4LfjLJsXGz/JmWJz8a6K7bR1k+QzZ+k//fg== +electron-to-chromium@^1.3.723: + version "1.3.745" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.745.tgz#b54c2baa0e01658288d6835d9f19727fd480de63" + integrity sha512-ZZCx4CS3kYT3BREYiIXocDqlNPT56KfdTS1Ogo4yvxRriBqiEXCDTLIQZT/zNVtby91xTWMMxW2NBiXh8bpLHw== -elliptic@6.5.3, elliptic@^6.4.0, elliptic@^6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" - integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== +elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: - 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" emoji-regex@^7.0.1: version "7.0.3" @@ -2073,47 +2175,34 @@ enquirer@^2.3.5: dependencies: ansi-colors "^4.1.1" -error-ex@^1.2.0: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-abstract@^1.18.0-next.0: - version "1.18.0-next.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.0.tgz#b302834927e624d8e5837ed48224291f2c66e6fc" - integrity sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ== +es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: + version "1.18.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" + integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== dependencies: + call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" + get-intrinsic "^1.1.1" has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-negative-zero "^2.0.0" - is-regex "^1.1.1" - object-inspect "^1.8.0" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.3" + is-string "^1.0.6" + object-inspect "^1.10.3" object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" es-to-primitive@^1.2.1: version "1.2.1" @@ -2124,10 +2213,10 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -escalade@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e" - integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig== +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-goat@^2.0.0: version "2.1.1" @@ -2149,6 +2238,20 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-airbnb-base@^14.2.1: + version "14.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" + integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== + dependencies: + confusing-browser-globals "^1.0.10" + object.assign "^4.1.2" + object.entries "^1.1.2" + eslint-config-standard@^14.1.1: version "14.1.1" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" @@ -2162,12 +2265,12 @@ eslint-import-resolver-node@^0.3.4: debug "^2.6.9" resolve "^1.13.1" -eslint-module-utils@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" - integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== +eslint-module-utils@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz#b51be1e473dd0de1c5ea638e22429c2490ea8233" + integrity sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A== dependencies: - debug "^2.6.9" + debug "^3.2.7" pkg-dir "^2.0.0" eslint-plugin-es@^3.0.0: @@ -2178,23 +2281,25 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@^2.22.1: - version "2.22.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" - integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== +eslint-plugin-import@^2.23.3: + version "2.23.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz#8dceb1ed6b73e46e50ec9a5bb2411b645e7d3d97" + integrity sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ== dependencies: - array-includes "^3.1.1" - array.prototype.flat "^1.2.3" - contains-path "^0.1.0" + array-includes "^3.1.3" + array.prototype.flat "^1.2.4" debug "^2.6.9" - doctrine "1.5.0" + doctrine "^2.1.0" eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.0" + eslint-module-utils "^2.6.1" + find-up "^2.0.0" has "^1.0.3" + is-core-module "^2.4.0" minimatch "^3.0.4" - object.values "^1.1.1" - read-pkg-up "^2.0.0" - resolve "^1.17.0" + object.values "^1.1.3" + pkg-up "^2.0.0" + read-pkg-up "^3.0.0" + resolve "^1.20.0" tsconfig-paths "^3.9.0" eslint-plugin-node@^11.1.0: @@ -2210,14 +2315,14 @@ eslint-plugin-node@^11.1.0: semver "^6.1.0" eslint-plugin-promise@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" - integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== + version "4.3.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz#61485df2a359e03149fdafc0a68b0e030ad2ac45" + integrity sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ== eslint-plugin-standard@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" - integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz#0c3bf3a67e853f8bbbc580fb4945fbf16f41b7c5" + integrity sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ== eslint-scope@^5.1.1: version "5.1.1" @@ -2239,29 +2344,36 @@ eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== -eslint@^7.10.0: - version "7.10.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.10.0.tgz#494edb3e4750fb791133ca379e786a8f648c72b9" - integrity sha512-BDVffmqWl7JJXqCjAK6lWtcQThZB/aP1HXSH1JKwGwv0LQEdvpR7qzNrUT487RM39B5goWuboFad5ovMBmD8yA== +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.27.0: + version "7.27.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.27.0.tgz#665a1506d8f95655c9274d84bd78f7166b07e9c7" + integrity sha512-JZuR6La2ZF0UD384lcbnd0Cgg6QJjiCwhMD6eU4h/VGPcVGwawNNzKU41tgokGXnfjOOyI6QIffthhJTPzzuRA== dependencies: - "@babel/code-frame" "^7.0.0" - "@eslint/eslintrc" "^0.1.3" + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.1" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.0.1" doctrine "^3.0.0" enquirer "^2.3.5" + escape-string-regexp "^4.0.0" eslint-scope "^5.1.1" eslint-utils "^2.1.0" - eslint-visitor-keys "^1.3.0" - espree "^7.3.0" - esquery "^1.2.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" esutils "^2.0.2" - file-entry-cache "^5.0.1" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" - globals "^12.1.0" + globals "^13.6.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" @@ -2269,7 +2381,7 @@ eslint@^7.10.0: js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" - lodash "^4.17.19" + lodash.merge "^4.6.2" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" @@ -2278,17 +2390,17 @@ eslint@^7.10.0: semver "^7.2.1" strip-ansi "^6.0.0" strip-json-comments "^3.1.0" - table "^5.2.3" + table "^6.0.9" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348" - integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw== +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== dependencies: acorn "^7.4.0" - acorn-jsx "^5.2.0" + acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" esprima@^4.0.0: @@ -2296,10 +2408,10 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" - integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" @@ -2331,45 +2443,45 @@ etag@~1.8.1: integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= ethers@^5.0.14: - version "5.0.14" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.0.14.tgz#fc33613ff3c1eb04c481f32083f2be315079e2a2" - integrity sha512-6WkoYwAURTr/4JiSZlrMJ9mm3pBv/bWrOu7sVXdLGw9QU4cp/GDZVrKKnh5GafMTzanuNBJoaEanPCjsbe4Mig== - dependencies: - "@ethersproject/abi" "^5.0.5" - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/base64" "^5.0.3" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/contracts" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/json-wallets" "^5.0.6" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/providers" "^5.0.8" - "@ethersproject/random" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/solidity" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/units" "^5.0.4" - "@ethersproject/wallet" "^5.0.4" - "@ethersproject/web" "^5.0.6" - "@ethersproject/wordlists" "^5.0.4" + version "5.3.0" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.3.0.tgz#1ec14d09c461e8f2554b00cd080e94a3094e7e9d" + integrity sha512-myN+338S4sFQZvQ9trii7xit8Hu/LnUtjA0ROFOHpUreQc3fgLZEMNVqF3vM1u2D78DIIeG1TbuozVCVlXQWvQ== + dependencies: + "@ethersproject/abi" "5.3.0" + "@ethersproject/abstract-provider" "5.3.0" + "@ethersproject/abstract-signer" "5.3.0" + "@ethersproject/address" "5.3.0" + "@ethersproject/base64" "5.3.0" + "@ethersproject/basex" "5.3.0" + "@ethersproject/bignumber" "5.3.0" + "@ethersproject/bytes" "5.3.0" + "@ethersproject/constants" "5.3.0" + "@ethersproject/contracts" "5.3.0" + "@ethersproject/hash" "5.3.0" + "@ethersproject/hdnode" "5.3.0" + "@ethersproject/json-wallets" "5.3.0" + "@ethersproject/keccak256" "5.3.0" + "@ethersproject/logger" "5.3.0" + "@ethersproject/networks" "5.3.0" + "@ethersproject/pbkdf2" "5.3.0" + "@ethersproject/properties" "5.3.0" + "@ethersproject/providers" "5.3.0" + "@ethersproject/random" "5.3.0" + "@ethersproject/rlp" "5.3.0" + "@ethersproject/sha2" "5.3.0" + "@ethersproject/signing-key" "5.3.0" + "@ethersproject/solidity" "5.3.0" + "@ethersproject/strings" "5.3.0" + "@ethersproject/transactions" "5.3.0" + "@ethersproject/units" "5.3.0" + "@ethersproject/wallet" "5.3.0" + "@ethersproject/web" "5.3.0" + "@ethersproject/wordlists" "5.3.0" express-ipfilter@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/express-ipfilter/-/express-ipfilter-1.1.2.tgz#536e1b8922f00df45d6da8796b02a75b1033a20f" - integrity sha512-dm1G3sVxlSbcOWSxfUTCo20ySyNQXJ4hJD5fuQJFoZlhkQvpbuDGBlh8AbFm1GwX85EWvfyhekOkvcydaXkBkg== + version "1.2.0" + resolved "https://registry.yarnpkg.com/express-ipfilter/-/express-ipfilter-1.2.0.tgz#fbc1ad0be45dbd8ae929ceb5ed8e1c91b33a71a1" + integrity sha512-nPXKMuhqVjX7+Vny4XsrpdqlX4YAGcanE0gh5xzpfmNTsINGAgPnpk67kb0No3p1m4vGQQLU6hdaXRxsuGNlTA== dependencies: ip "~1.1.0" lodash "^4.17.11" @@ -2412,7 +2524,7 @@ express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -2433,16 +2545,16 @@ fast-safe-stringify@^2.0.4: integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== fecha@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.0.tgz#3ffb6395453e3f3efff850404f0a59b6747f5f41" - integrity sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg== + version "4.2.1" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" + integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: - flat-cache "^2.0.1" + flat-cache "^3.0.4" file-stream-rotator@^0.5.7: version "0.5.7" @@ -2499,19 +2611,18 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" + flatted "^3.1.0" + rimraf "^3.0.2" -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flatted@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== fn.name@1.x.x: version "1.1.0" @@ -2519,24 +2630,24 @@ fn.name@1.x.x: integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== follow-redirects@^1.10.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" - integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== foreach@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fraction.js@^4.0.13: - version "4.0.13" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe" - integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA== +fraction.js@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.1.tgz#ac4e520473dae67012d618aab91eda09bcb400ff" + integrity sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg== fresh@0.5.2: version "0.5.2" @@ -2548,10 +2659,10 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" @@ -2563,10 +2674,19 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" get-stream@^4.1.0: version "4.1.0" @@ -2583,16 +2703,16 @@ get-stream@^5.1.0: pump "^3.0.0" glob-parent@^5.0.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -2602,11 +2722,11 @@ glob@^7.1.3: path-is-absolute "^1.0.0" global-dirs@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201" - integrity sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A== + version "2.1.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" + integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ== dependencies: - ini "^1.3.5" + ini "1.3.7" globals@^11.1.0: version "11.12.0" @@ -2620,6 +2740,13 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" +globals@^13.6.0: + version "13.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" + integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== + dependencies: + type-fest "^0.20.2" + got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" @@ -2638,9 +2765,14 @@ got@^9.6.0: url-parse-lax "^3.0.0" graceful-fs@^4.1.2: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== has-flag@^3.0.0: version "3.0.0" @@ -2652,10 +2784,10 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== has-yarn@^2.1.0: version "2.1.0" @@ -2678,15 +2810,7 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -hash.js@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.0" - -hash.js@^1.0.0, hash.js@^1.0.3: +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== @@ -2695,11 +2819,11 @@ hash.js@^1.0.0, hash.js@^1.0.3: minimalistic-assert "^1.0.1" helmet@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/helmet/-/helmet-4.1.1.tgz#751f0e273d809ace9c172073e0003bed27d27a4a" - integrity sha512-Avg4XxSBrehD94mkRwEljnO+6RZx7AGfk8Wa6K1nxaU+hbXlFOhlOIMgPfFqOYQB/dBCsTpootTGuiOG+CHiQA== + version "4.6.0" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-4.6.0.tgz#579971196ba93c5978eb019e4e8ec0e50076b4df" + integrity sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg== -hmac-drbg@^1.0.0: +hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= @@ -2716,9 +2840,9 @@ homedir-polyfill@^1.0.1: parse-passwd "^1.0.0" hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== http-cache-semantics@^4.0.0: version "4.1.0" @@ -2760,9 +2884,9 @@ iconv-lite@0.4.24: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" - integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" @@ -2782,9 +2906,9 @@ ignore@^5.1.1: integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -2817,17 +2941,15 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.5, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== +ini@1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" + integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== -invariant@^2.2.2, invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== ip6@0.0.4: version "0.0.4" @@ -2850,9 +2972,11 @@ ipaddr.js@1.9.1: integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + dependencies: + call-bind "^1.0.0" is-arrayish@^0.2.1: version "0.2.1" @@ -2864,6 +2988,11 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-bigint@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -2871,10 +3000,17 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-callable@^1.1.4, is-callable@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" - integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== +is-boolean-object@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== + dependencies: + call-bind "^1.0.2" + +is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== is-ci@^2.0.0: version "2.0.0" @@ -2883,10 +3019,17 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" +is-core-module@^2.2.0, is-core-module@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== + dependencies: + has "^1.0.3" + is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== is-extglob@^2.1.1: version "2.1.1" @@ -2904,9 +3047,9 @@ is-fullwidth-code-point@^3.0.0: integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-generator-function@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" - integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== + version "1.0.9" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.9.tgz#e5f82c2323673e7fcad3d12858c83c4039f6399c" + integrity sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A== is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" @@ -2923,16 +3066,21 @@ is-installed-globally@^0.3.1: global-dirs "^2.0.1" is-path-inside "^3.0.1" -is-negative-zero@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" - integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== is-npm@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== +is-number-object@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -2944,16 +3092,24 @@ is-obj@^2.0.0: integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== is-path-inside@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" - integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-regex@^1.1.0, is-regex@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: - has-symbols "^1.0.1" + isobject "^3.0.1" + +is-regex@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.2" is-stream@^1.0.1: version "1.1.0" @@ -2965,25 +3121,26 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== +is-string@^1.0.5, is-string@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: - has-symbols "^1.0.1" + has-symbols "^1.0.2" is-typed-array@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.3.tgz#a4ff5a5e672e1a55f99c7f54e59597af5c1df04d" - integrity sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ== + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" + integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== dependencies: - available-typed-arrays "^1.0.0" - es-abstract "^1.17.4" + available-typed-arrays "^1.0.2" + call-bind "^1.0.2" + es-abstract "^1.18.0-next.2" foreach "^2.0.5" has-symbols "^1.0.1" @@ -2997,7 +3154,7 @@ is-yarn-global@^0.3.0: resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== -isarray@^1.0.0, isarray@~1.0.0: +isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -3007,6 +3164,11 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + isomorphic-fetch@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" @@ -3025,15 +3187,15 @@ js-sha3@0.5.7: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: +js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -3058,11 +3220,21 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" @@ -3076,9 +3248,9 @@ json5@^1.0.1: minimist "^1.2.0" json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== dependencies: minimist "^1.2.5" @@ -3089,6 +3261,11 @@ keyv@^3.0.0: dependencies: json-buffer "3.0.0" +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + kuler@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" @@ -3101,18 +3278,6 @@ latest-version@^5.0.0: dependencies: package-json "^6.3.0" -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levenary@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" - integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== - dependencies: - leven "^3.1.0" - levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -3121,14 +3286,14 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= dependencies: graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" + parse-json "^4.0.0" + pify "^3.0.0" strip-bom "^3.0.0" locate-path@^2.0.0: @@ -3147,6 +3312,16 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + lodash.isfunction@^3.0.8, lodash.isfunction@~3.0.8: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" @@ -3157,10 +3332,20 @@ lodash.isnumber@^3.0.3: resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + +lodash@^4.17.11, lodash@^4.17.20: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== logform@^2.2.0: version "2.2.0" @@ -3173,13 +3358,6 @@ logform@^2.2.0: ms "^2.1.1" triple-beam "^1.3.0" -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -3190,6 +3368,13 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -3206,14 +3391,15 @@ make-dir@^3.0.0: semver "^6.0.0" mathjs@^9.3.0: - version "9.3.0" - resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-9.3.0.tgz#59cc43b536b22616197e56da303604b430daa6ac" - integrity sha512-0kYW+TXgB8lCqUj5wHR2hqAO2twSbPRelSFgRJXiwAx4nM6FrIb43Jd6XhW7sVbwYB+9HCNiyg5Kn8VYeB7ilg== + version "9.4.1" + resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-9.4.1.tgz#df86a7996513e270b55f58082d42fac4aefba68b" + integrity sha512-zAepVEfVyv4C7PM8gZ5jDzC7bZscdIcqTKsNqiqmFP+0SFHFffWT84l2v3z2zT41n9Rmdn3aWR8/bpFlnNjC6g== dependencies: - complex.js "^2.0.11" + "@babel/runtime" "^7.14.0" + complex.js "^2.0.13" decimal.js "^10.2.1" escape-latex "^1.2.0" - fraction.js "^4.0.13" + fraction.js "^4.1.1" javascript-natural-sort "^0.7.1" seedrandom "^3.0.5" tiny-emitter "^2.1.0" @@ -3243,17 +3429,17 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== +mime-db@1.48.0: + version "1.48.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + version "2.1.31" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== dependencies: - mime-db "1.44.0" + mime-db "1.48.0" mime@1.6.0: version "1.6.0" @@ -3270,7 +3456,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: +minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= @@ -3287,13 +3473,6 @@ minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - moment@^2.11.2, moment@^2.29.1: version "2.29.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" @@ -3309,15 +3488,20 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@2.1.2, ms@^2.1.1: +ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + nan@^2.13.2: - version "2.14.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" - integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== natural-compare@^1.4.0: version "1.4.0" @@ -3365,15 +3549,15 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-releases@^1.1.61: - version "1.1.61" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e" - integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g== +node-releases@^1.1.71: + version "1.1.72" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" + integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== nodemon@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.4.tgz#55b09319eb488d6394aa9818148c0c2d1c04c416" - integrity sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ== + version "2.0.7" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.7.tgz#6f030a0a0ebe3ea1ba2a38f71bf9bab4841ced32" + integrity sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA== dependencies: chokidar "^3.2.2" debug "^3.2.6" @@ -3383,8 +3567,8 @@ nodemon@^2.0.4: semver "^5.7.1" supports-color "^5.5.0" touch "^3.1.0" - undefsafe "^2.0.2" - update-notifier "^4.0.0" + undefsafe "^2.0.3" + update-notifier "^4.1.0" nopt@~1.0.10: version "1.0.10" @@ -3409,52 +3593,61 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== object-hash@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09" - integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" + integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== -object-inspect@^1.7.0, object-inspect@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== +object-inspect@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" + integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" - integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== +object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.18.0-next.0" has-symbols "^1.0.1" object-keys "^1.1.1" +object.entries@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd" + integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.2" + object.getownpropertydescriptors@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + version "2.1.2" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" + integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + es-abstract "^1.18.0-next.2" -object.values@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== +object.values@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" + integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" + es-abstract "^1.18.2" on-finished@~2.3.0: version "2.3.0" @@ -3549,12 +3742,13 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= dependencies: - error-ex "^1.2.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" parse-passwd@^1.0.0: version "1.0.0" @@ -3582,26 +3776,26 @@ path-key@^3.1.0: integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== dependencies: - pify "^2.0.0" + pify "^3.0.0" pbkdf2@^3.0.9: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -3610,14 +3804,14 @@ pbkdf2@^3.0.9: sha.js "^2.4.8" picomatch@^2.0.4, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== - -pify@^2.0.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pify@^4.0.1: version "4.0.1" @@ -3645,6 +3839,13 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + post-message-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/post-message-stream/-/post-message-stream-3.0.0.tgz#90d9f54bd209e6b6f5d74795b87588205b547048" @@ -3673,11 +3874,11 @@ progress@^2.0.0: integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== proxy-addr@^2.0.4, proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: - forwarded "~0.1.2" + forwarded "0.2.0" ipaddr.js "1.9.1" pstree.remy@^1.1.7: @@ -3699,9 +3900,9 @@ punycode@^2.1.0: integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== pupa@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726" - integrity sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA== + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== dependencies: escape-goat "^2.0.0" @@ -3757,22 +3958,22 @@ rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= dependencies: find-up "^2.0.0" - read-pkg "^2.0.0" + read-pkg "^3.0.0" -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= dependencies: - load-json-file "^2.0.0" + load-json-file "^4.0.0" normalize-package-data "^2.3.2" - path-type "^2.0.0" + path-type "^3.0.0" readable-stream@^2.1.4, readable-stream@^2.3.7: version "2.3.7" @@ -3796,10 +3997,10 @@ readable-stream@^3.4.0, readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdirp@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" - integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== dependencies: picomatch "^2.2.1" @@ -3811,9 +4012,9 @@ regenerate-unicode-properties@^8.2.0: regenerate "^1.4.0" regenerate@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" - integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.13.4: version "0.13.7" @@ -3832,7 +4033,7 @@ regexpp@^3.0.0, regexpp@^3.1.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== -regexpu-core@^4.7.0: +regexpu-core@^4.7.1: version "4.7.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== @@ -3845,9 +4046,9 @@ regexpu-core@^4.7.0: unicode-match-property-value-ecmascript "^1.2.0" registry-auth-token@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.0.tgz#1d37dffda72bbecd0f581e4715540213a65eb7da" - integrity sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w== + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== dependencies: rc "^1.2.8" @@ -3864,22 +4065,28 @@ regjsgen@^0.5.1: integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" - integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + version "0.6.9" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" + integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== dependencies: jsesc "~0.5.0" +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: + is-core-module "^2.2.0" path-parse "^1.0.6" responselike@^1.0.2: @@ -3889,10 +4096,10 @@ responselike@^1.0.2: dependencies: lowercase-keys "^1.0.0" -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" @@ -3945,7 +4152,7 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: +"semver@2 || 3 || 4 || 5", semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -3955,15 +4162,17 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^6.0.0, semver@^6.1.0, semver@^6.2.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.2.1: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" send@0.17.1: version "0.17.1" @@ -4007,6 +4216,13 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -4031,14 +4247,14 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" source-map-support@^0.5.16: version "0.5.19" @@ -4080,9 +4296,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.6" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz#c80757383c28abf7296744998cbc106ae8b854ce" - integrity sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw== + version "3.0.9" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" + integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== sprintf-js@~1.0.2: version "1.0.3" @@ -4108,30 +4324,30 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.0.0, string-width@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.5" -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.5" string_decoder@^1.1.1: version "1.3.0" @@ -4190,20 +4406,22 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== +table@^6.0.9: + version "6.7.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.0" term-size@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.0.tgz#1f16adedfe9bdc18800e1776821734086fcc6753" - integrity sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw== + version "2.2.1" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" + integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== text-hex@1.0.x: version "1.0.0" @@ -4226,9 +4444,9 @@ tiny-invariant@^1.1.0: integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== tiny-secp256k1@^1.1.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.5.tgz#3dc37b9bf0fa5b4390b9fa29e953228810cebc18" - integrity sha512-duE2hSLSQIpHGzmK48OgRrGTi+4OTkXLC6aa86uOYQ6LLCYZSarVKIAvEtY7MoXjoL6bOXMSerEGMzrvW4SkDw== + version "1.1.6" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz#7e224d2bee8ab8283f284e40e6b4acb74ffe047c" + integrity sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA== dependencies: bindings "^1.3.0" bn.js "^4.11.8" @@ -4241,6 +4459,13 @@ tiny-warning@^1.0.3: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -4297,6 +4522,11 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" @@ -4327,7 +4557,17 @@ typeforce@^1.11.5: resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== -undefsafe@^2.0.2: +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +undefsafe@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== @@ -4369,10 +4609,10 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= -update-notifier@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.1.tgz#895fc8562bbe666179500f9f2cebac4f26323746" - integrity sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg== +update-notifier@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" + integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A== dependencies: boxen "^4.2.0" chalk "^3.0.0" @@ -4389,9 +4629,9 @@ update-notifier@^4.0.0: xdg-basedir "^4.0.0" uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -4402,15 +4642,22 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" +utf-8-validate@^5.0.2: + version "5.0.5" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.5.tgz#dd32c2e82c72002dc9f02eb67ba6761f43456ca1" + integrity sha512-+pnxRYsS/axEpkrrEpzYfNZGXp0IjC/9RIxwM5gntY4Koi8SHmUGSfxfWqxZdRxrtaoVstuOzUp/rbs3JSPELQ== + dependencies: + node-gyp-build "^4.2.0" + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= util@^0.12.3: - version "0.12.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" - integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== dependencies: inherits "^2.0.3" is-arguments "^1.0.4" @@ -4425,9 +4672,9 @@ utils-merge@1.0.1: integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= v8-compile-cache@^2.0.3: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" - integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== v8flags@^3.1.1: version "3.2.0" @@ -4450,17 +4697,29 @@ vary@~1.1.2: integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= whatwg-fetch@>=0.10.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3" - integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ== + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" which-typed-array@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2" - integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ== + version "1.1.4" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" + integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== dependencies: available-typed-arrays "^1.0.2" - es-abstract "^1.17.5" + call-bind "^1.0.0" + es-abstract "^1.18.0-next.1" foreach "^2.0.5" function-bind "^1.1.1" has-symbols "^1.0.1" @@ -4488,16 +4747,16 @@ wif@^2.0.6: bs58check "<3.0.0" winston-daily-rotate-file@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.0.tgz#3914ac57c4bdae1138170bec85af0c2217b253b1" - integrity sha512-/HqeWiU48dzGqcrABRlxYWVMdL6l3uKCtFSJyrqK+E2rLnSFNsgYpvwx15EgTitBLNzH69lQd/+z2ASryV2aqw== + version "4.5.5" + resolved "https://registry.yarnpkg.com/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.5.tgz#cfa3a89f4eb0e4126917592b375759b772bcd972" + integrity sha512-ds0WahIjiDhKCiMXmY799pDBW+58ByqIBtUcsqr4oDoXrAI3Zn+hbgFdUxzMfqA93OG0mPLYVMiotqTgE/WeWQ== dependencies: file-stream-rotator "^0.5.7" object-hash "^2.0.1" triple-beam "^1.3.0" - winston-transport "^4.2.0" + winston-transport "^4.4.0" -winston-transport@^4.2.0, winston-transport@^4.4.0: +winston-transport@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== @@ -4540,19 +4799,17 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -ws@7.2.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" - integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== +ws@7.4.6, ws@^7.3.1: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== From fa6fad0efb7c8ab2ba9948f1ae6b0ff9e8b143a8 Mon Sep 17 00:00:00 2001 From: james-hummingbot Date: Thu, 3 Jun 2021 13:20:05 +0200 Subject: [PATCH 25/31] Ignore node_modules --- .eslintignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintignore b/.eslintignore index 0980665..3950c73 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,2 @@ # turn off specific file for eslint -/*.js \ No newline at end of file +/node_modules \ No newline at end of file From 5696dc6e6cb4ceee2988e86c61a5348dfcd95803 Mon Sep 17 00:00:00 2001 From: james-hummingbot Date: Thu, 3 Jun 2021 14:46:43 +0200 Subject: [PATCH 26/31] Apply prettier --- .babelrc | 6 +- .editorconfig | 13 + .eslintrc.js | 12 +- .prettierignore | 4 + .prettierrc | 6 + package.json | 5 +- src/app.js | 80 +-- src/index.js | 92 ++-- src/routes/balancer.route.js | 358 +++++++------ src/routes/celo.route.js | 247 ++++----- src/routes/eth.route.js | 409 ++++++++------- src/routes/index.route.js | 14 +- src/routes/perpetual_finance.route.js | 478 +++++++++-------- src/routes/terra.route.js | 257 +++++----- src/routes/uniswap.route.js | 351 +++++++------ src/routes/uniswap_v3.route.js | 500 ++++++++++-------- src/services/access.js | 28 +- src/services/balancer.js | 246 +++++---- src/services/eth.js | 207 ++++---- src/services/fees.js | 80 +-- src/services/logger.js | 44 +- src/services/perpetual_finance.js | 452 ++++++++++------ src/services/terra.js | 439 ++++++++-------- src/services/uniswap.js | 302 ++++++----- src/services/uniswap_v3.js | 477 ++++++++++------- src/services/utils.js | 146 +++--- src/static/abi.js | 594 ++++++++++++++-------- src/static/uniswap-v3/helper_functions.js | 204 +++++--- src/static/uniswap_route_tokens.json | 87 +++- yarn.lock | 29 ++ 30 files changed, 3581 insertions(+), 2586 deletions(-) create mode 100644 .editorconfig create mode 100644 .prettierignore create mode 100644 .prettierrc diff --git a/.babelrc b/.babelrc index cedf24f..1320b9a 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,3 @@ { - "presets": [ - "@babel/preset-env" - ] -} \ No newline at end of file + "presets": ["@babel/preset-env"] +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b4e3016 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 08ab3f8..7d65f3a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,7 +1,8 @@ module.exports = { - extends: 'airbnb-base', + extends: ['airbnb-base', 'eslint:recommended', 'prettier'], + plugins: ['prettier'], env: { - node: true, + node: true }, rules: { camelcase: 'off', @@ -25,6 +26,7 @@ module.exports = { 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], 'no-underscore-dangle': 'off', 'prefer-destructuring': 'off', - radix: 'off', - }, -}; + 'prettier/prettier': 'error', + radix: 'off' + } +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..b4d36e3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +test +certs +*.md +*.yml \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..0d1aa74 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "trailingComma": "none", + "semi": false, + "singleQuote": true, + "tabWidth": 2 +} diff --git a/package.json b/package.json index 357e1aa..02f1555 100644 --- a/package.json +++ b/package.json @@ -49,12 +49,15 @@ "@babel/preset-env": "^7.14.1", "eslint": "^7.25.0", "eslint-config-airbnb-base": "^14.2.1", + "eslint-config-prettier": "^8.3.0", "eslint-config-standard": "^14.1.1", "eslint-plugin-import": "^2.23.3", "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.4.0", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", - "nodemon": "^2.0.4" + "nodemon": "^2.0.4", + "prettier": "^2.3.0" }, "engines": { "node": "10.x" diff --git a/src/app.js b/src/app.js index 218e669..811c3f8 100644 --- a/src/app.js +++ b/src/app.js @@ -1,69 +1,69 @@ -import dotenv from 'dotenv'; -import bodyParser from 'body-parser'; -import express from 'express'; -import helmet from 'helmet'; -import { IpFilter } from 'express-ipfilter'; -import { statusMessages } from './services/utils'; -import { validateAccess } from './services/access'; -import { logger } from './services/logger'; +import dotenv from 'dotenv' +import bodyParser from 'body-parser' +import express from 'express' +import helmet from 'helmet' +import { IpFilter } from 'express-ipfilter' +import { statusMessages } from './services/utils' +import { validateAccess } from './services/access' +import { logger } from './services/logger' // Routes -import apiRoutes from './routes/index.route'; -import balancerRoutes from './routes/balancer.route'; -import ethRoutes from './routes/eth.route'; -import terraRoutes from './routes/terra.route'; -import uniswapRoutes from './routes/uniswap.route'; -import uniswapV3Routes from './routes/uniswap_v3.route'; -import perpFiRoutes from './routes/perpetual_finance.route'; +import apiRoutes from './routes/index.route' +import balancerRoutes from './routes/balancer.route' +import ethRoutes from './routes/eth.route' +import terraRoutes from './routes/terra.route' +import uniswapRoutes from './routes/uniswap.route' +import uniswapV3Routes from './routes/uniswap_v3.route' +import perpFiRoutes from './routes/perpetual_finance.route' // terminate if environment not found -const result = dotenv.config(); +const result = dotenv.config() if (result.error) { - logger.error(result.error); - process.exit(1); + logger.error(result.error) + process.exit(1) } // create app -const app = express(); +const app = express() // middleware // #security: remove response headers from middleware // https://www.npmjs.com/package/helmet -app.use(helmet()); +app.use(helmet()) -const ipWhitelist = process.env.IP_WHITELIST; +const ipWhitelist = process.env.IP_WHITELIST if (ipWhitelist) { - app.use(IpFilter(JSON.parse(ipWhitelist), { mode: 'allow' })); + app.use(IpFilter(JSON.parse(ipWhitelist), { mode: 'allow' })) } -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: true })); +app.use(bodyParser.json()) +app.use(bodyParser.urlencoded({ extended: true })) -app.use(validateAccess); +app.use(validateAccess) // mount routes to specific path -app.use('/api', apiRoutes); -app.use('/eth', ethRoutes); -app.use('/eth/uniswap', uniswapRoutes); -app.use('/eth/uniswap/v3', uniswapV3Routes); -app.use('/eth/balancer', balancerRoutes); -app.use('/terra', terraRoutes); -app.use('/perpfi', perpFiRoutes); +app.use('/api', apiRoutes) +app.use('/eth', ethRoutes) +app.use('/eth/uniswap', uniswapRoutes) +app.use('/eth/uniswap/v3', uniswapV3Routes) +app.use('/eth/balancer', balancerRoutes) +app.use('/terra', terraRoutes) +app.use('/perpfi', perpFiRoutes) // app.use('/celo', celoRoutes); app.get('/', (req, res, _next) => { - res.send('ok'); -}); + res.send('ok') +}) /** * Catch all 404 response when routes are not found */ app.use((req, res, _next) => { - const message = `${statusMessages.page_not_found} at ${req.originalUrl}`; - logger.error(message); + const message = `${statusMessages.page_not_found} at ${req.originalUrl}` + logger.error(message) res.status(404).send({ error: 'Page not found', - message, - }); -}); + message + }) +}) -export default app; +export default app diff --git a/src/index.js b/src/index.js index 4e977dd..f7480db 100644 --- a/src/index.js +++ b/src/index.js @@ -1,93 +1,97 @@ #!/usr/bin/env node // absolute imports -import https from 'https'; -import dotenv from 'dotenv'; -import fs from 'fs'; +import https from 'https' +import dotenv from 'dotenv' +import fs from 'fs' // relative imports -import app from './app'; -import { logger } from './services/logger'; +import app from './app' +import { logger } from './services/logger' // terminate if environment not found -const result = dotenv.config(); +const result = dotenv.config() if (result.error) { - logger.info(result.error); - process.exit(1); + logger.info(result.error) + process.exit(1) } -const env = process.env.NODE_ENV; -const port = process.env.PORT; -const certPassphrase = process.env.CERT_PASSPHRASE; -const ethereumChain = process.env.ETHEREUM_CHAIN; -const terraChain = process.env.TERRA_CHAIN; -let certPath = process.env.CERT_PATH; +const env = process.env.NODE_ENV +const port = process.env.PORT +const certPassphrase = process.env.CERT_PASSPHRASE +const ethereumChain = process.env.ETHEREUM_CHAIN +const terraChain = process.env.TERRA_CHAIN +let certPath = process.env.CERT_PATH if ((typeof certPath === 'undefined' && certPath == null) || certPath === '') { // assuming it is local development using test script to generate certs - certPath = './certs'; + certPath = './certs' } else { - certPath = certPath.replace(/\/$/, ''); + certPath = certPath.replace(/\/$/, '') } // set app environment -app.set('env', env); +app.set('env', env) const options = { - key: fs.readFileSync(certPath.concat('/server_key.pem'), { encoding: 'utf-8' }), - cert: fs.readFileSync(certPath.concat('/server_cert.pem'), { encoding: 'utf-8' }), + key: fs.readFileSync(certPath.concat('/server_key.pem'), { + encoding: 'utf-8' + }), + cert: fs.readFileSync(certPath.concat('/server_cert.pem'), { + encoding: 'utf-8' + }), // request client certificate from user requestCert: true, // reject requests with no valid certificate rejectUnauthorized: true, // use ca cert created with own key for self-signed ca: [fs.readFileSync(certPath.concat('/ca_cert.pem'), { encoding: 'utf-8' })], - passphrase: certPassphrase, -}; + passphrase: certPassphrase +} -const server = https.createServer(options, app); +const server = https.createServer(options, app) // event listener for "error" event const onError = (error) => { if (error.syscall !== 'listen') { - throw error; + throw error } - const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`; + const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}` // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': - console.error(`${bind} requires elevated privileges`); - process.exit(1); - break; + console.error(`${bind} requires elevated privileges`) + process.exit(1) + break case 'EADDRINUSE': - console.error(`${bind} is already in use`); - process.exit(1); - break; + console.error(`${bind} is already in use`) + process.exit(1) + break default: - throw error; + throw error } -}; +} // event listener for "listening" event. const onListening = () => { - const addr = server.address(); - const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`; - console.log(`listening on ${bind}`); - logger.debug(`listening on ${bind}`); -}; + const addr = server.address() + const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}` + console.log(`listening on ${bind}`) + logger.debug(`listening on ${bind}`) +} // listen on provided port, on all network interfaces. -server.listen(port); -server.on('error', onError); -server.on('listening', onListening); +server.listen(port) +server.on('error', onError) +server.on('listening', onListening) const serverConfig = { app: 'gateway-api', port, ethereumChain, - terraChain, -}; + terraChain +} -logger.info(JSON.stringify(serverConfig)); -console.log(serverConfig); +logger.info(JSON.stringify(serverConfig)) +console.log(serverConfig) diff --git a/src/routes/balancer.route.js b/src/routes/balancer.route.js index 358bd9d..ddc17e6 100644 --- a/src/routes/balancer.route.js +++ b/src/routes/balancer.route.js @@ -1,30 +1,28 @@ -import BigNumber from 'bignumber.js'; -import { ethers } from 'ethers'; -import express from 'express'; +import BigNumber from 'bignumber.js' +import { ethers } from 'ethers' +import express from 'express' -import { - getParamData, latency, statusMessages, -} from '../services/utils'; +import { getParamData, latency, statusMessages } from '../services/utils' -import Ethereum from '../services/eth'; -import Balancer from '../services/balancer'; -import Fees from '../services/fees'; -import { logger } from '../services/logger'; +import Ethereum from '../services/eth' +import Balancer from '../services/balancer' +import Fees from '../services/fees' +import { logger } from '../services/logger' -const debug = require('debug')('router'); +const debug = require('debug')('router') -const router = express.Router(); -const eth = new Ethereum(process.env.ETHEREUM_CHAIN); -const balancer = new Balancer(process.env.ETHEREUM_CHAIN); -const fees = new Fees(); +const router = express.Router() +const eth = new Ethereum(process.env.ETHEREUM_CHAIN) +const balancer = new Balancer(process.env.ETHEREUM_CHAIN) +const fees = new Fees() -const swapMoreThanMaxPriceError = 'Price too high'; -const swapLessThanMaxPriceError = 'Price too low'; +const swapMoreThanMaxPriceError = 'Price too high' +const swapLessThanMaxPriceError = 'Price too low' const estimateGasLimit = (maxswaps) => { - const gasLimit = balancer.gasBase + maxswaps * balancer.gasPerSwap; - return gasLimit; -}; + const gasLimit = balancer.gasBase + maxswaps * balancer.gasPerSwap + return gasLimit +} router.post('/', async (req, res) => { /* @@ -36,9 +34,9 @@ router.post('/', async (req, res) => { exchangeProxy: balancer.exchangeProxy, subgraphUrl: balancer.subgraphUrl, connection: true, - timestamp: Date.now(), - }); -}); + timestamp: Date.now() + }) +}) router.post('/gas-limit', async (req, res) => { /* @@ -47,28 +45,33 @@ router.post('/gas-limit', async (req, res) => { "maxSwaps":4 } */ - const paramData = getParamData(req.body); + const paramData = getParamData(req.body) try { - const swaps = paramData.maxSwaps; - const maxSwaps = typeof swaps === 'undefined' || parseInt(swaps) === 0 ? balancer.maxSwaps : parseInt(swaps); - const gasLimit = estimateGasLimit(maxSwaps); + const swaps = paramData.maxSwaps + const maxSwaps = + typeof swaps === 'undefined' || parseInt(swaps) === 0 + ? balancer.maxSwaps + : parseInt(swaps) + const gasLimit = estimateGasLimit(maxSwaps) res.status(200).json({ network: balancer.network, gasLimit, - timestamp: Date.now(), - }); + timestamp: Date.now() + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.get('/start', async (req, res) => { /* @@ -78,39 +81,51 @@ router.get('/start', async (req, res) => { "gasPrice":30 } */ - const initTime = Date.now(); - const paramData = getParamData(req.query); - const pairs = JSON.parse(paramData.pairs); - let gasPrice; + const initTime = Date.now() + const paramData = getParamData(req.query) + const pairs = JSON.parse(paramData.pairs) + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } // get token contract address and cache pools for (let pair of pairs) { - pair = pair.split('-'); - const baseTokenSymbol = pair[0]; - const quoteTokenSymbol = pair[1]; - const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol); + pair = pair.split('-') + const baseTokenSymbol = pair[0] + const quoteTokenSymbol = pair[1] + const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) // check for valid token symbols - if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { - const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol; + if ( + baseTokenContractInfo === undefined || + quoteTokenContractInfo === undefined + ) { + const undefinedToken = + baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol res.status(500).json({ error: `Token ${undefinedToken} contract address not found`, - message: `Token contract address not found for ${undefinedToken}. Check token list source`, - }); - return; + message: `Token contract address not found for ${undefinedToken}. Check token list source` + }) + return } - await Promise.allSettled([balancer.fetchPool(baseTokenContractInfo.address, quoteTokenContractInfo.address), - balancer.fetchPool(quoteTokenContractInfo.address, baseTokenContractInfo.address)]); + await Promise.allSettled([ + balancer.fetchPool( + baseTokenContractInfo.address, + quoteTokenContractInfo.address + ), + balancer.fetchPool( + quoteTokenContractInfo.address, + baseTokenContractInfo.address + ) + ]) } - const gasLimit = estimateGasLimit(balancer.maxSwaps); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit(balancer.maxSwaps) + const gasCost = await fees.getGasCost(gasPrice, gasLimit) const result = { network: eth.network, @@ -120,11 +135,11 @@ router.get('/start', async (req, res) => { pairs, gasPrice, gasLimit, - gasCost, - }; - console.log('Initializing balancer'); - res.status(200).json(result); -}); + gasCost + } + console.log('Initializing balancer') + res.status(200).json(result) +}) router.post('/price', async (req, res) => { /* @@ -136,48 +151,51 @@ router.post('/price', async (req, res) => { "side":buy } */ - const initTime = Date.now(); + const initTime = Date.now() // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body); - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); - const baseTokenAddress = baseTokenContractInfo.address; - const quoteTokenAddress = quoteTokenContractInfo.address; - const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals; - const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals; - const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)); - const maxSwaps = balancer.maxSwaps; - const side = paramData.side.toUpperCase(); - let gasPrice; + const paramData = getParamData(req.body) + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals + const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals + const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) + const maxSwaps = balancer.maxSwaps + const side = paramData.side.toUpperCase() + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } try { // fetch the optimal pool mix from balancer-sor - const { swaps, expectedAmount } = side === 'BUY' - ? await balancer.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount, - maxSwaps, - ) - : await balancer.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount, - maxSwaps, - ); + const { swaps, expectedAmount } = + side === 'BUY' + ? await balancer.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount, + maxSwaps + ) + : await balancer.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount, + maxSwaps + ) if (swaps != null && expectedAmount != null) { - const gasLimit = estimateGasLimit(swaps.length); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit(swaps.length) + const gasCost = await fees.getGasCost(gasPrice, gasLimit) - const tradeAmount = parseFloat(amount); - const expectedTradeAmount = parseInt(expectedAmount) / quoteDenomMultiplier; - const tradePrice = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier; + const tradeAmount = parseFloat(amount) + const expectedTradeAmount = + parseInt(expectedAmount) / quoteDenomMultiplier + const tradePrice = + ((expectedAmount / amount) * baseDenomMultiplier) / quoteDenomMultiplier const result = { network: balancer.network, @@ -192,26 +210,31 @@ router.post('/price', async (req, res) => { gasPrice, gasLimit, gasCost, - swaps, - }; - debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`); - res.status(200).json(result); - } else { // no pool available + swaps + } + debug( + `Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH` + ) + res.status(200).json(result) + } else { + // no pool available res.status(200).json({ info: statusMessages.no_pool_available, - message: statusMessages.no_pool_available, - }); + message: statusMessages.no_pool_available + }) } } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/trade', async (req, res) => { /* @@ -226,55 +249,57 @@ router.post('/trade', async (req, res) => { "privateKey":{{privateKey}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const wallet = new ethers.Wallet(privateKey, balancer.provider); + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, balancer.provider) - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); - const baseTokenAddress = baseTokenContractInfo.address; - const quoteTokenAddress = quoteTokenContractInfo.address; - const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals; - const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals; - const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)); + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals + const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals + const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) - const maxSwaps = balancer.maxSwaps; - const side = paramData.side.toUpperCase(); + const maxSwaps = balancer.maxSwaps + const side = paramData.side.toUpperCase() - let limitPrice; + let limitPrice if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice); + limitPrice = parseFloat(paramData.limitPrice) } - let gasPrice; + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } try { // fetch the optimal pool mix from balancer-sor - const { swaps, expectedAmount } = side === 'BUY' - ? await balancer.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount, - maxSwaps, - ) - : await balancer.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount, - maxSwaps, - ); + const { swaps, expectedAmount } = + side === 'BUY' + ? await balancer.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount, + maxSwaps + ) + : await balancer.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount, + maxSwaps + ) - const gasLimit = estimateGasLimit(swaps.length); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit(swaps.length) + const gasCost = await fees.getGasCost(gasPrice, gasLimit) if (side === 'BUY') { - const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier; - logger.info(`Price: ${price.toString()}`); + const price = + ((expectedAmount / amount) * baseDenomMultiplier) / quoteDenomMultiplier + logger.info(`Price: ${price.toString()}`) if (!limitPrice || price <= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await balancer.swapExactOut( @@ -283,8 +308,8 @@ router.post('/trade', async (req, res) => { quoteTokenAddress, // tokenIn is quote asset baseTokenAddress, // tokenOut is base asset expectedAmount.toString(), - gasPrice, - ); + gasPrice + ) // submit response res.status(200).json({ @@ -299,21 +324,22 @@ router.post('/trade', async (req, res) => { gasPrice, gasLimit, gasCost, - txHash: tx.hash, - }); + txHash: tx.hash + }) } else { res.status(200).json({ error: swapMoreThanMaxPriceError, - message: `Swap price ${price} exceeds limitPrice ${limitPrice}`, - }); - debug(`Swap price ${price} exceeds limitPrice ${limitPrice}`); + message: `Swap price ${price} exceeds limitPrice ${limitPrice}` + }) + debug(`Swap price ${price} exceeds limitPrice ${limitPrice}`) } } else { // sell - const minAmountOut = limitPrice / amount * baseDenomMultiplier; - debug('minAmountOut', minAmountOut); - const price = expectedAmount / amount * baseDenomMultiplier / quoteDenomMultiplier; - logger.info(`Price: ${price.toString()}`); + const minAmountOut = (limitPrice / amount) * baseDenomMultiplier + debug('minAmountOut', minAmountOut) + const price = + ((expectedAmount / amount) * baseDenomMultiplier) / quoteDenomMultiplier + logger.info(`Price: ${price.toString()}`) if (!limitPrice || price >= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await balancer.swapExactIn( @@ -323,8 +349,8 @@ router.post('/trade', async (req, res) => { quoteTokenAddress, // tokenOut is quote asset amount.toString(), parseInt(expectedAmount) / quoteDenomMultiplier, - gasPrice, - ); + gasPrice + ) // submit response res.status(200).json({ network: balancer.network, @@ -338,25 +364,27 @@ router.post('/trade', async (req, res) => { gasPrice, gasLimit, gasCost, - txHash: tx.hash, - }); + txHash: tx.hash + }) } else { res.status(200).json({ error: swapLessThanMaxPriceError, - message: `Swap price ${price} lower than limitPrice ${limitPrice}`, - }); - debug(`Swap price ${price} lower than limitPrice ${limitPrice}`); + message: `Swap price ${price} lower than limitPrice ${limitPrice}` + }) + debug(`Swap price ${price} lower than limitPrice ${limitPrice}`) } } } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) -export default router; +export default router diff --git a/src/routes/celo.route.js b/src/routes/celo.route.js index f305edc..0581c4c 100644 --- a/src/routes/celo.route.js +++ b/src/routes/celo.route.js @@ -1,171 +1,177 @@ -const express = require('express'); +const express = require('express') -const router = express.Router(); -const BigNumber = require('bignumber.js'); -const debug = require('debug')('router'); -const spawn = require('child_process').spawn; +const router = express.Router() +const BigNumber = require('bignumber.js') +const debug = require('debug')('router') +const spawn = require('child_process').spawn -const network = 'celo'; -const celocli = 'celocli'; -const DENOM_UNIT_MULTIPLIER = BigNumber('1e+18'); +const network = 'celo' +const celocli = 'celocli' +const DENOM_UNIT_MULTIPLIER = BigNumber('1e+18') -const hbUtils = require('../services/utils'); +const hbUtils = require('../services/utils') -const separator = '=>'; +const separator = '=>' router.use((req, res, next) => { - debug('celo route:', Date.now()); - next(); -}); + debug('celo route:', Date.now()) + next() +}) router.get('/', (req, res) => { - res.status(200).send(network); -}); + res.status(200).send(network) +}) router.get('/status', (req, res) => { /* return if the celocli ultralight node is synced */ - const nodeSync = spawn(celocli, ['node:synced']); + const nodeSync = spawn(celocli, ['node:synced']) - const err_message = []; const - out_message = []; + const err_message = [] + const out_message = [] nodeSync.stdout.on('data', (out) => { - out_message.push(out.toString().trim()); - debug('out_message', out_message); - }); + out_message.push(out.toString().trim()) + debug('out_message', out_message) + }) nodeSync.stderr.on('data', (err) => { - err_message.push(err.toString().trim()); - debug('err_message', err_message); - }); + err_message.push(err.toString().trim()) + debug('err_message', err_message) + }) nodeSync.on('close', (code) => { if (code === 0) { res.status(200).json({ synced: out_message[0].toLowerCase() === 'true', - message: err_message.join(''), - }); + message: err_message.join('') + }) } else { res.status(401).json({ - error: err_message.join(''), - }); + error: err_message.join('') + }) } - }); -}); + }) +}) router.get('/price', (req, res) => { /* api request format: /price?trading_pair=CELO-CUSD&trade_type=sell&amount=1.2345 */ - const keyFormat = ['trading_pair', 'trade_type', 'amount']; + const keyFormat = ['trading_pair', 'trade_type', 'amount'] - const initTime = Date.now(); + const initTime = Date.now() - const paramData = hbUtils.getParamData(req.query, keyFormat); - const tradingPair = paramData.trading_pair; - const requestAmount = paramData.amount; - const amount = parseFloat(requestAmount) * DENOM_UNIT_MULTIPLIER; - debug('params', req.params); - debug('paramData', paramData); + const paramData = hbUtils.getParamData(req.query, keyFormat) + const tradingPair = paramData.trading_pair + const requestAmount = paramData.amount + const amount = parseFloat(requestAmount) * DENOM_UNIT_MULTIPLIER + debug('params', req.params) + debug('paramData', paramData) - const nodeSync = spawn(celocli, ['exchange:show', '--amount', amount]); + const nodeSync = spawn(celocli, ['exchange:show', '--amount', amount]) - const err_message = []; const - out_message = []; + const err_message = [] + const out_message = [] nodeSync.stdout.on('data', (out) => { - out_message.push(out.toString().trim()); - }); + out_message.push(out.toString().trim()) + }) nodeSync.stderr.on('data', (err) => { - err_message.push(err.toString().trim()); - }); + err_message.push(err.toString().trim()) + }) nodeSync.on('close', (code) => { - const exchange_rates = {}; - let price; + const exchange_rates = {} + let price if (code === 0) { // extract exchange rate from cli output out_message.forEach((item, _index) => { if (item.includes(separator)) { - const exchangeInfo = item.split(separator); - const base = exchangeInfo[0].trim().split(' '); - const quote = exchangeInfo[1].trim().split(' '); - const market = [base[1].toUpperCase(), quote[1].toUpperCase()].join('-'); - exchange_rates[market] = quote[0] / DENOM_UNIT_MULTIPLIER; - debug(exchangeInfo, exchange_rates); + const exchangeInfo = item.split(separator) + const base = exchangeInfo[0].trim().split(' ') + const quote = exchangeInfo[1].trim().split(' ') + const market = [base[1].toUpperCase(), quote[1].toUpperCase()].join( + '-' + ) + exchange_rates[market] = quote[0] / DENOM_UNIT_MULTIPLIER + debug(exchangeInfo, exchange_rates) } - }); + }) - price = exchange_rates[tradingPair]; + price = exchange_rates[tradingPair] const result = Object.assign(paramData, { price, timestamp: initTime, - latency: hbUtils.latency(initTime, Date.now()), - }); - res.status(200).json(result); + latency: hbUtils.latency(initTime, Date.now()) + }) + res.status(200).json(result) } - }); -}); + }) +}) router.get('/balance', (req, res) => { /* api request format: /balance?address=0x87A4...b120 */ - const keyFormat = ['address']; - const paramData = hbUtils.getParamData(req.query, keyFormat); - const address = paramData.address; - debug(paramData); + const keyFormat = ['address'] + const paramData = hbUtils.getParamData(req.query, keyFormat) + const address = paramData.address + debug(paramData) - const balance = spawn(celocli, ['account:balance', address]); + const balance = spawn(celocli, ['account:balance', address]) - const err_message = []; const - out_message = []; - const walletBalances = {}; + const err_message = [] + const out_message = [] + const walletBalances = {} balance.stdout.on('data', (out) => { - out_message.push(out.toString().trim()); - debug(out_message); - }); + out_message.push(out.toString().trim()) + debug(out_message) + }) balance.stderr.on('data', (err) => { - err_message.push(err.toString().trim()); - debug(err_message); - }); + err_message.push(err.toString().trim()) + debug(err_message) + }) balance.on('close', (code) => { if (code === 0) { out_message.forEach((item, _index) => { // key indicator in balance result: "celo", "gold", "lockedcelo", "lockedgold", "usd", "pending" - if (item.toLowerCase().includes('lockedcelo') || item.toLowerCase().includes('lockedgold')) { - const balanceArray = item.split('\n'); + if ( + item.toLowerCase().includes('lockedcelo') || + item.toLowerCase().includes('lockedgold') + ) { + const balanceArray = item.split('\n') balanceArray.forEach((x) => { - const keyValue = x.split(':'); - walletBalances[keyValue[0].trim()] = keyValue[1].trim() / DENOM_UNIT_MULTIPLIER; - }); - debug('walletBalances', walletBalances); + const keyValue = x.split(':') + walletBalances[keyValue[0].trim()] = + keyValue[1].trim() / DENOM_UNIT_MULTIPLIER + }) + debug('walletBalances', walletBalances) } - }); + }) res.status(200).json({ address, balance: walletBalances, - timestamp: Date.now(), - }); + timestamp: Date.now() + }) } else { res.status(401).json({ - error: err_message, - }); + error: err_message + }) } - }); -}); + }) +}) router.post('/unlock', (req, res) => { /* @@ -176,53 +182,58 @@ router.post('/unlock', (req, res) => { "secret": "mysupersecret" } */ - const keyFormat = ['address', 'secret']; - const paramData = hbUtils.getParamData(req.body, keyFormat); - const address = paramData.address; - const secret = paramData.secret; + const keyFormat = ['address', 'secret'] + const paramData = hbUtils.getParamData(req.body, keyFormat) + const address = paramData.address + const secret = paramData.secret - debug(paramData); - debug(req.body); + debug(paramData) + debug(req.body) - const lockStatus = spawn(celocli, ['account:unlock', address, '--password', secret]); + const lockStatus = spawn(celocli, [ + 'account:unlock', + address, + '--password', + secret + ]) - const err_message = []; const - out_message = []; + const err_message = [] + const out_message = [] lockStatus.stdout.on('data', (out) => { - out_message.push(out.toString().trim()); - debug(out_message); - }); + out_message.push(out.toString().trim()) + debug(out_message) + }) lockStatus.stderr.on('data', (err) => { - err_message.push(err.toString().trim()); - debug(err_message); - }); + err_message.push(err.toString().trim()) + debug(err_message) + }) lockStatus.on('close', (code) => { - let unlocked = false; + let unlocked = false if (code === 0) { if (out_message.length > 0) { out_message.forEach((item, _index) => { if (item.includes(separator)) { - debug('item', item); + debug('item', item) } - }); + }) } else { - unlocked = true; + unlocked = true } res.status(200).json({ unlocked, message: out_message.join(), - timestamp: Date.now(), - }); + timestamp: Date.now() + }) } else { res.status(401).json({ - error: err_message.join(), - }); + error: err_message.join() + }) } - }); -}); + }) +}) router.post('/trade', (req, res) => { /* @@ -235,14 +246,14 @@ router.post('/trade', (req, res) => { "price": 3.512 } */ - const keyFormat = ['trading_pair', 'trade_type', 'amount', 'price']; - const paramData = hbUtils.getParamData(req.body, keyFormat); - debug(paramData); + const keyFormat = ['trading_pair', 'trade_type', 'amount', 'price'] + const paramData = hbUtils.getParamData(req.body, keyFormat) + debug(paramData) // const result = Object.assign(paramData, { // message: 'WIP', // timestamp: Date.now() // }) - res.status(200).json({ status: 'WIP' }); -}); + res.status(200).json({ status: 'WIP' }) +}) -module.exports = router; +module.exports = router diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index c6b057a..09dac12 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -1,22 +1,22 @@ -import { ethers, BigNumber } from 'ethers'; -import express from 'express'; +import { ethers, BigNumber } from 'ethers' +import express from 'express' -import { getParamData, latency, statusMessages } from '../services/utils'; -import Ethereum from '../services/eth'; -import Fees from '../services/fees'; -import { logger } from '../services/logger'; +import { getParamData, latency, statusMessages } from '../services/utils' +import Ethereum from '../services/eth' +import Fees from '../services/fees' +import { logger } from '../services/logger' -const debug = require('debug')('router'); +const debug = require('debug')('router') -const router = express.Router(); -const eth = new Ethereum(process.env.ETHEREUM_CHAIN); +const router = express.Router() +const eth = new Ethereum(process.env.ETHEREUM_CHAIN) const spenders = { balancer: process.env.EXCHANGE_PROXY, uniswap: process.env.UNISWAP_ROUTER, uniswapV3Router: process.env.UNISWAP_V3_ROUTER, - uniswapV3NFTManager: process.env.UNISWAP_V3_NFT_MANAGER, -}; -const fees = new Fees(); + uniswapV3NFTManager: process.env.UNISWAP_V3_NFT_MANAGER +} +const fees = new Fees() router.post('/', async (req, res) => { /* @@ -26,9 +26,9 @@ router.post('/', async (req, res) => { network: eth.network, rpcUrl: eth.provider.connection.url, connection: true, - timestamp: Date.now(), - }); -}); + timestamp: Date.now() + }) +}) router.post('/balances', async (req, res) => { /* @@ -38,65 +38,73 @@ router.post('/balances', async (req, res) => { tokenList:{{tokenList}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet try { - wallet = new ethers.Wallet(privateKey, eth.provider); + wallet = new ethers.Wallet(privateKey, eth.provider) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } // populate token contract info using token symbol list - const tokenContractList = []; - const tokenList = JSON.parse(paramData.tokenList); + const tokenContractList = [] + const tokenList = JSON.parse(paramData.tokenList) tokenList.forEach((symbol) => { - const tokenContractInfo = eth.getERC20TokenAddresses(symbol); - tokenContractList[symbol] = tokenContractInfo; - }); + const tokenContractInfo = eth.getERC20TokenAddresses(symbol) + tokenContractList[symbol] = tokenContractInfo + }) - const balances = {}; - balances.ETH = await eth.getETHBalance(wallet, privateKey); + const balances = {} + balances.ETH = await eth.getETHBalance(wallet, privateKey) try { Promise.all( Object.keys(tokenContractList).map(async (symbol, _index) => { if (tokenContractList[symbol] !== undefined) { - const address = tokenContractList[symbol].address; - const decimals = tokenContractList[symbol].decimals; - balances[symbol] = await eth.getERC20Balance(wallet, address, decimals); + const address = tokenContractList[symbol].address + const decimals = tokenContractList[symbol].decimals + balances[symbol] = await eth.getERC20Balance( + wallet, + address, + decimals + ) } else { - const err = `Token contract info for ${symbol} not found`; - logger.error('Token info not found', { message: err }); - debug(err); + const err = `Token contract info for ${symbol} not found` + logger.error('Token info not found', { message: err }) + debug(err) } - }), + }) ).then(() => { - debug('eth.route - Get Account Balance', { message: JSON.stringify(tokenList) }); + debug('eth.route - Get Account Balance', { + message: JSON.stringify(tokenList) + }) res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances, - }); - }); + balances + }) + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/allowances', async (req, res) => { /* @@ -107,60 +115,69 @@ router.post('/allowances', async (req, res) => { connector:{{connector_name}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const spender = spenders[paramData.connector]; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const spender = spenders[paramData.connector] + let wallet try { - wallet = new ethers.Wallet(privateKey, eth.provider); + wallet = new ethers.Wallet(privateKey, eth.provider) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } // populate token contract info using token symbol list - const tokenContractList = []; - const tokenList = JSON.parse(paramData.tokenList); + const tokenContractList = [] + const tokenList = JSON.parse(paramData.tokenList) tokenList.forEach((symbol) => { - const tokenContractInfo = eth.getERC20TokenAddresses(symbol); - tokenContractList[symbol] = tokenContractInfo; - }); + const tokenContractInfo = eth.getERC20TokenAddresses(symbol) + tokenContractList[symbol] = tokenContractInfo + }) - const approvals = {}; + const approvals = {} try { Promise.all( Object.keys(tokenContractList).map(async (symbol, _index) => { - const address = tokenContractList[symbol].address; - const decimals = tokenContractList[symbol].decimals; - approvals[symbol] = await eth.getERC20Allowance(wallet, spender, address, decimals); - }), + const address = tokenContractList[symbol].address + const decimals = tokenContractList[symbol].decimals + approvals[symbol] = await eth.getERC20Allowance( + wallet, + spender, + address, + decimals + ) + }) ).then(() => { - logger.info('eth.route - Getting allowances', { message: JSON.stringify(tokenList) }); + logger.info('eth.route - Getting allowances', { + message: JSON.stringify(tokenList) + }) res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), spender, - approvals, - }); - }); + approvals + }) + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/balances-2', async (req, res) => { /* @@ -171,52 +188,61 @@ router.post('/balances-2', async (req, res) => { tokenDecimalList:{{tokenDecimalList}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet try { - wallet = new ethers.Wallet(privateKey, eth.provider); + wallet = new ethers.Wallet(privateKey, eth.provider) } catch (err) { - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } - let tokenAddressList; + let tokenAddressList if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(','); + tokenAddressList = paramData.tokenAddressList.split(',') } - let tokenDecimalList; + let tokenDecimalList if (paramData.tokenDecimalList) { - tokenDecimalList = paramData.tokenDecimalList.split(','); + tokenDecimalList = paramData.tokenDecimalList.split(',') } - const balances = {}; - balances.ETH = await eth.getETHBalance(wallet, privateKey); + const balances = {} + balances.ETH = await eth.getETHBalance(wallet, privateKey) try { Promise.all( - tokenAddressList.map(async (value, index) => balances[value] = await eth.getERC20Balance(wallet, value, tokenDecimalList[index])), + tokenAddressList.map( + async (value, index) => + (balances[value] = await eth.getERC20Balance( + wallet, + value, + tokenDecimalList[index] + )) + ) ).then(() => { res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances, - }); - }); + balances + }) + }) } catch (err) { - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/allowances-2', async (req, res) => { /* @@ -228,53 +254,63 @@ router.post('/allowances-2', async (req, res) => { connector:{{connector_name}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const spender = spenders[paramData.connector]; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const spender = spenders[paramData.connector] + let wallet try { - wallet = new ethers.Wallet(privateKey, eth.provider); + wallet = new ethers.Wallet(privateKey, eth.provider) } catch (err) { - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } - let tokenAddressList; + let tokenAddressList if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(','); + tokenAddressList = paramData.tokenAddressList.split(',') } - let tokenDecimalList; + let tokenDecimalList if (paramData.tokenDecimalList) { - tokenDecimalList = paramData.tokenDecimalList.split(','); + tokenDecimalList = paramData.tokenDecimalList.split(',') } - const approvals = {}; + const approvals = {} try { Promise.all( - tokenAddressList.map(async (value, index) => approvals[value] = await eth.getERC20Allowance(wallet, spender, value, tokenDecimalList[index])), + tokenAddressList.map( + async (value, index) => + (approvals[value] = await eth.getERC20Allowance( + wallet, + spender, + value, + tokenDecimalList[index] + )) + ) ).then(() => { res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), spender, - approvals, - }); - }); + approvals + }) + }) } catch (err) { - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/approve', async (req, res) => { /* @@ -287,41 +323,48 @@ router.post('/approve', async (req, res) => { amount:{{amount}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const spender = spenders[paramData.connector]; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const spender = spenders[paramData.connector] + let wallet try { - wallet = new ethers.Wallet(privateKey, eth.provider); + wallet = new ethers.Wallet(privateKey, eth.provider) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } - const token = paramData.token; - const tokenContractInfo = eth.getERC20TokenAddresses(token); - const tokenAddress = tokenContractInfo.address; - const decimals = tokenContractInfo.decimals; + const token = paramData.token + const tokenContractInfo = eth.getERC20TokenAddresses(token) + const tokenAddress = tokenContractInfo.address + const decimals = tokenContractInfo.decimals - let amount; - paramData.amount ? amount = ethers.utils.parseUnits(paramData.amount, decimals) - : amount = ethers.constants.MaxUint256; // approve max possible units if no amount specified - let gasPrice; + let amount + paramData.amount + ? (amount = ethers.utils.parseUnits(paramData.amount, decimals)) + : (amount = ethers.constants.MaxUint256) // approve max possible units if no amount specified + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } try { // call approve function - const approval = await eth.approveERC20(wallet, spender, tokenAddress, amount, gasPrice); + const approval = await eth.approveERC20( + wallet, + spender, + tokenAddress, + amount, + gasPrice + ) // console.log('eth.route - Approving allowance', { message: approval }) // submit response res.status(200).json({ @@ -330,45 +373,49 @@ router.post('/approve', async (req, res) => { latency: latency(initTime, Date.now()), tokenAddress, spender, - amount: amount / 1e18.toString(), - approval, - }); + amount: amount / (1e18).toString(), + approval + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/poll', async (req, res) => { - const initTime = Date.now(); - const paramData = getParamData(req.body); - const txHash = paramData.txHash; - const txReceipt = await eth.provider.getTransactionReceipt(txHash); - const receipt = {}; - const confirmed = !!(txReceipt && txReceipt.blockNumber); + const initTime = Date.now() + const paramData = getParamData(req.body) + const txHash = paramData.txHash + const txReceipt = await eth.provider.getTransactionReceipt(txHash) + const receipt = {} + const confirmed = !!(txReceipt && txReceipt.blockNumber) if (confirmed) { - receipt.gasUsed = BigNumber.from(txReceipt.gasUsed).toNumber(); - receipt.blockNumber = txReceipt.blockNumber; - receipt.confirmations = txReceipt.confirmations; - receipt.status = txReceipt.status; - receipt.logs = txReceipt.logs; + receipt.gasUsed = BigNumber.from(txReceipt.gasUsed).toNumber() + receipt.blockNumber = txReceipt.blockNumber + receipt.confirmations = txReceipt.confirmations + receipt.status = txReceipt.status + receipt.logs = txReceipt.logs } - logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }); + logger.info(`eth.route - Get TX Receipt: ${txHash}`, { + message: JSON.stringify(receipt) + }) res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), txHash, confirmed, - receipt, - }); - return txReceipt; -}); + receipt + }) + return txReceipt +}) // Kovan faucet to get test tokens (wip) & weth conversion // router.post('/get-weth', async (req, res) => { @@ -425,4 +472,4 @@ router.post('/poll', async (req, res) => { // } // }) -module.exports = router; +module.exports = router diff --git a/src/routes/index.route.js b/src/routes/index.route.js index fbe93c6..1116b5c 100644 --- a/src/routes/index.route.js +++ b/src/routes/index.route.js @@ -1,16 +1,16 @@ -import { loadConfig } from '../services/utils'; +import { loadConfig } from '../services/utils' -const express = require('express'); +const express = require('express') -const router = express.Router(); +const router = express.Router() router.get('/', (req, res) => { res.status(200).json({ app: process.env.APPNAME, image: process.env.IMAGE, config: loadConfig(), - status: 'ok', - }); -}); + status: 'ok' + }) +}) -module.exports = router; +module.exports = router diff --git a/src/routes/perpetual_finance.route.js b/src/routes/perpetual_finance.route.js index 46eb82a..0441a39 100644 --- a/src/routes/perpetual_finance.route.js +++ b/src/routes/perpetual_finance.route.js @@ -1,15 +1,15 @@ -import { ethers } from 'ethers'; -import express from 'express'; +import { ethers } from 'ethers' +import express from 'express' -import { getParamData, latency, statusMessages } from '../services/utils'; -import { logger } from '../services/logger'; -import PerpetualFinance from '../services/perpetual_finance'; +import { getParamData, latency, statusMessages } from '../services/utils' +import { logger } from '../services/logger' +import PerpetualFinance from '../services/perpetual_finance' -require('dotenv').config(); +require('dotenv').config() -const router = express.Router(); -const perpFi = new PerpetualFinance(process.env.ETHEREUM_CHAIN); -setTimeout(perpFi.update_price_loop.bind(perpFi), 2000); +const router = express.Router() +const perpFi = new PerpetualFinance(process.env.ETHEREUM_CHAIN) +setTimeout(perpFi.update_price_loop.bind(perpFi), 2000) router.get('/', async (req, res) => { /* @@ -20,23 +20,23 @@ router.get('/', async (req, res) => { provider: perpFi.provider.connection.url, loadedMetadata: perpFi.loadedMetadata, connection: true, - timestamp: Date.now(), - }); -}); + timestamp: Date.now() + }) +}) router.get('/load-metadata', async (req, res) => { /* GET / */ - const loadedMetadata = await perpFi.load_metadata(); + const loadedMetadata = await perpFi.load_metadata() res.status(200).json({ network: perpFi.network, provider: perpFi.provider.connection.url, loadedMetadata, connection: true, - timestamp: Date.now(), - }); -}); + timestamp: Date.now() + }) +}) router.post('/balances', async (req, res) => { /* @@ -45,41 +45,43 @@ router.post('/balances', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet try { - wallet = new ethers.Wallet(privateKey, perpFi.provider); + wallet = new ethers.Wallet(privateKey, perpFi.provider) } catch (err) { - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } - const balances = {}; - balances.XDAI = await perpFi.getXdaiBalance(wallet); - balances.USDC = await perpFi.getUSDCBalance(wallet); + const balances = {} + balances.XDAI = await perpFi.getXdaiBalance(wallet) + balances.USDC = await perpFi.getUSDCBalance(wallet) try { res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances, - }); + balances + }) } catch (err) { - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/allowances', async (req, res) => { /* @@ -88,40 +90,42 @@ router.post('/allowances', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet try { - wallet = new ethers.Wallet(privateKey, perpFi.provider); + wallet = new ethers.Wallet(privateKey, perpFi.provider) } catch (err) { - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } - const approvals = {}; - approvals.USDC = await perpFi.getAllowance(wallet); + const approvals = {} + approvals.USDC = await perpFi.getAllowance(wallet) try { res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - approvals, - }); + approvals + }) } catch (err) { - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/approve', async (req, res) => { /* @@ -131,48 +135,49 @@ router.post('/approve', async (req, res) => { amount:{{amount}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - let amount; - paramData.amount ? amount = paramData.amount - : amount = '1000000000'; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let amount + paramData.amount ? (amount = paramData.amount) : (amount = '1000000000') + let wallet try { - wallet = new ethers.Wallet(privateKey, perpFi.provider); + wallet = new ethers.Wallet(privateKey, perpFi.provider) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } try { // call approve function - const approval = await perpFi.approve(wallet, amount); - logger.info('perpFi.route - Approving allowance'); + const approval = await perpFi.approve(wallet, amount) + logger.info('perpFi.route - Approving allowance') // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), amount, - approval, - }); + approval + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/open', async (req, res) => { /* @@ -186,33 +191,40 @@ router.post('/open', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const side = paramData.side; - const pair = paramData.pair; - const margin = paramData.margin; - const leverage = paramData.leverage; - const minBaseAssetAmount = paramData.minBaseAssetAmount; - console.log(minBaseAssetAmount); - const privateKey = paramData.privateKey; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const side = paramData.side + const pair = paramData.pair + const margin = paramData.margin + const leverage = paramData.leverage + const minBaseAssetAmount = paramData.minBaseAssetAmount + console.log(minBaseAssetAmount) + const privateKey = paramData.privateKey + let wallet try { - wallet = new ethers.Wallet(privateKey, perpFi.provider); + wallet = new ethers.Wallet(privateKey, perpFi.provider) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } try { // call openPosition function - const tx = await perpFi.openPosition(side, margin, leverage, pair, minBaseAssetAmount, wallet); - logger.info('perpFi.route - Opening position'); + const tx = await perpFi.openPosition( + side, + margin, + leverage, + pair, + minBaseAssetAmount, + wallet + ) + logger.info('perpFi.route - Opening position') // submit response res.status(200).json({ network: perpFi.network, @@ -222,18 +234,20 @@ router.post('/open', async (req, res) => { side, leverage, minBaseAssetAmount, - txHash: tx.hash, - }); + txHash: tx.hash + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/close', async (req, res) => { /* @@ -244,47 +258,49 @@ router.post('/close', async (req, res) => { pair:{{pair}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const minimalQuoteAsset = paramData.minimalQuoteAsset; - const privateKey = paramData.privateKey; - const pair = paramData.pair; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const minimalQuoteAsset = paramData.minimalQuoteAsset + const privateKey = paramData.privateKey + const pair = paramData.pair + let wallet try { - wallet = new ethers.Wallet(privateKey, perpFi.provider); + wallet = new ethers.Wallet(privateKey, perpFi.provider) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } try { // call closePosition function - const tx = await perpFi.closePosition(wallet, pair, minimalQuoteAsset); - logger.info('perpFi.route - Closing position'); + const tx = await perpFi.closePosition(wallet, pair, minimalQuoteAsset) + logger.info('perpFi.route - Closing position') // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), minimalQuoteAsset, - txHash: tx.hash, - }); + txHash: tx.hash + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/position', async (req, res) => { /* @@ -294,45 +310,47 @@ router.post('/position', async (req, res) => { pair:{{pair}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const pair = paramData.pair; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const pair = paramData.pair + let wallet try { - wallet = new ethers.Wallet(privateKey, perpFi.provider); + wallet = new ethers.Wallet(privateKey, perpFi.provider) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } try { // call getPosition function - const position = await perpFi.getPosition(wallet, pair); - logger.info('perpFi.route - getting active position'); + const position = await perpFi.getPosition(wallet, pair) + logger.info('perpFi.route - getting active position') // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - position, - }); + position + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/margin', async (req, res) => { /* @@ -341,44 +359,46 @@ router.post('/margin', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - let wallet; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + let wallet try { - wallet = new ethers.Wallet(privateKey, perpFi.provider); + wallet = new ethers.Wallet(privateKey, perpFi.provider) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = 'Error getting wallet'; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') res.status(500).json({ error: reason, - message: err, - }); - return; + message: err + }) + return } try { // call getAllBalances function - const allBalances = await perpFi.getActiveMargin(wallet); - logger.info('perpFi.route - Getting all balances'); + const allBalances = await perpFi.getActiveMargin(wallet) + logger.info('perpFi.route - Getting all balances') // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - margin: allBalances, - }); + margin: allBalances + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/receipt', async (req, res) => { /* @@ -387,29 +407,31 @@ router.post('/receipt', async (req, res) => { txHash:{{txHash}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const txHash = paramData.txHash; - const txReceipt = await perpFi.provider.getTransactionReceipt(txHash); - const receipt = {}; - const confirmed = !!(txReceipt && txReceipt.blockNumber); + const initTime = Date.now() + const paramData = getParamData(req.body) + const txHash = paramData.txHash + const txReceipt = await perpFi.provider.getTransactionReceipt(txHash) + const receipt = {} + const confirmed = !!(txReceipt && txReceipt.blockNumber) if (txReceipt !== null) { - receipt.gasUsed = ethers.utils.formatEther(txReceipt.gasUsed); - receipt.blockNumber = txReceipt.blockNumber; - receipt.confirmations = txReceipt.confirmations; - receipt.status = txReceipt.status; + receipt.gasUsed = ethers.utils.formatEther(txReceipt.gasUsed) + receipt.blockNumber = txReceipt.blockNumber + receipt.confirmations = txReceipt.confirmations + receipt.status = txReceipt.status } - logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) }); + logger.info(`eth.route - Get TX Receipt: ${txHash}`, { + message: JSON.stringify(receipt) + }) res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), txHash, confirmed, - receipt, - }); - return txReceipt; -}); + receipt + }) + return txReceipt +}) router.post('/price', async (req, res) => { /* @@ -420,58 +442,62 @@ router.post('/price', async (req, res) => { amount:{{amount}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const side = paramData.side; - const pair = paramData.pair; - const amount = paramData.amount; + const initTime = Date.now() + const paramData = getParamData(req.body) + const side = paramData.side + const pair = paramData.pair + const amount = paramData.amount try { // call getPrice function - const price = await perpFi.getPrice(side, amount, pair); - logger.info('perpFi.route - Getting price'); + const price = await perpFi.getPrice(side, amount, pair) + logger.info('perpFi.route - Getting price') // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), side, - price, - }); + price + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.get('/pairs', async (req, res) => { /* GET */ - const initTime = Date.now(); + const initTime = Date.now() try { res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - pairs: Object.keys(perpFi.amm), - }); + pairs: Object.keys(perpFi.amm) + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/funding', async (req, res) => { /* @@ -480,30 +506,32 @@ router.post('/funding', async (req, res) => { pair:{{pair}} } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const pair = paramData.pair; + const initTime = Date.now() + const paramData = getParamData(req.body) + const pair = paramData.pair try { // call getFundingRate function - const fr = await perpFi.getFundingRate(pair); - logger.info('perpFi.route - Getting funding info'); + const fr = await perpFi.getFundingRate(pair) + logger.info('perpFi.route - Getting funding info') // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - fr, - }); + fr + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) -export default router; +export default router diff --git a/src/routes/terra.route.js b/src/routes/terra.route.js index 506935f..6f9058f 100644 --- a/src/routes/terra.route.js +++ b/src/routes/terra.route.js @@ -1,17 +1,20 @@ -import express from 'express'; +import express from 'express' import { - getParamData, latency, reportConnectionError, statusMessages, -} from '../services/utils'; -import { logger } from '../services/logger'; + getParamData, + latency, + reportConnectionError, + statusMessages +} from '../services/utils' +import { logger } from '../services/logger' -import Terra from '../services/terra'; +import Terra from '../services/terra' -const router = express.Router(); -const terra = new Terra(); +const router = express.Router() +const terra = new Terra() // constants -const network = terra.lcd.config.chainID; -const denomUnitMultiplier = terra.denomUnitMultiplier; +const network = terra.lcd.config.chainID +const denomUnitMultiplier = terra.denomUnitMultiplier router.post('/', async (req, res) => { /* @@ -23,57 +26,59 @@ router.post('/', async (req, res) => { gasPrices: terra.lcd.config.gasPrices, gasAdjustment: terra.lcd.config.gasAdjustment, connection: true, - timestamp: Date.now(), - }); -}); + timestamp: Date.now() + }) +}) router.post('/balances', async (req, res) => { /* POST: address:{{address}} */ - const initTime = Date.now(); + const initTime = Date.now() - const paramData = getParamData(req.body); - const address = paramData.address; + const paramData = getParamData(req.body) + const address = paramData.address - const balances = {}; + const balances = {} try { await terra.lcd.bank.balance(address).then((bal) => { bal.toArray().forEach(async (x) => { - const item = x.toData(); - const denom = item.denom; - const amount = item.amount / denomUnitMultiplier; - const symbol = terra.tokens[denom].symbol; - balances[symbol] = amount; - }); - }); - logger.info('terra.route - Get Account Balance'); + const item = x.toData() + const denom = item.denom + const amount = item.amount / denomUnitMultiplier + const symbol = terra.tokens[denom].symbol + balances[symbol] = amount + }) + }) + logger.info('terra.route - Get Account Balance') res.status(200).json({ network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances, - }); + balances + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let message; - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; - const isAxiosError = err.isAxiosError; + logger.error(req.originalUrl, { message: err }) + let message + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) + const isAxiosError = err.isAxiosError if (isAxiosError) { - reason = err.response.status; - message = err.response.statusText; + reason = err.response.status + message = err.response.statusText } else { - message = err; + message = err } res.status(500).json({ error: reason, - message, - }); + message + }) } -}); +}) router.post('/start', async (req, res) => { /* @@ -84,10 +89,10 @@ router.post('/start', async (req, res) => { "amount":1 } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const baseTokenSymbol = paramData.base; - const quoteTokenSymbol = paramData.quote; + const initTime = Date.now() + const paramData = getParamData(req.body) + const baseTokenSymbol = paramData.base + const quoteTokenSymbol = paramData.quote const result = { network, @@ -95,10 +100,10 @@ router.post('/start', async (req, res) => { latency: latency(initTime, Date.now()), success: true, base: baseTokenSymbol, - quote: quoteTokenSymbol, - }; - res.status(200).json(result); -}); + quote: quoteTokenSymbol + } + res.status(200).json(result) +}) router.post('/price', async (req, res) => { /* @@ -110,55 +115,58 @@ router.post('/price', async (req, res) => { "amount":1 } */ - const initTime = Date.now(); + const initTime = Date.now() - const paramData = getParamData(req.body); - const baseToken = paramData.base; - const quoteToken = paramData.quote; - const tradeType = paramData.side.toUpperCase(); - const amount = parseFloat(paramData.amount); + const paramData = getParamData(req.body) + const baseToken = paramData.base + const quoteToken = paramData.quote + const tradeType = paramData.side.toUpperCase() + const amount = parseFloat(paramData.amount) - let exchangeRate; + let exchangeRate try { - await terra.getSwapRate(baseToken, quoteToken, amount, tradeType).then((rate) => { - exchangeRate = rate; - }).catch((err) => { - reportConnectionError(res, err); - }); - - res.status(200).json( - { - network, - timestamp: initTime, - latency: latency(initTime, Date.now()), - base: baseToken, - quote: quoteToken, - amount, - tradeType, - price: exchangeRate.price.amount, - cost: exchangeRate.cost.amount, - txFee: exchangeRate.txFee.amount, - }, - ); + await terra + .getSwapRate(baseToken, quoteToken, amount, tradeType) + .then((rate) => { + exchangeRate = rate + }) + .catch((err) => { + reportConnectionError(res, err) + }) + + res.status(200).json({ + network, + timestamp: initTime, + latency: latency(initTime, Date.now()), + base: baseToken, + quote: quoteToken, + amount, + tradeType, + price: exchangeRate.price.amount, + cost: exchangeRate.cost.amount, + txFee: exchangeRate.txFee.amount + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let message; - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; - const isAxiosError = err.isAxiosError; + logger.error(req.originalUrl, { message: err }) + let message + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) + const isAxiosError = err.isAxiosError if (isAxiosError) { - reason = err.response.status; - message = err.response.statusText; + reason = err.response.status + message = err.response.statusText } else { - message = err; + message = err } res.status(500).json({ error: reason, - message, - }); + message + }) } -}); +}) router.post('/trade', async (req, res) => { /* @@ -171,25 +179,38 @@ router.post('/trade', async (req, res) => { "secret": "mysupersecret" } */ - const initTime = Date.now(); + const initTime = Date.now() - const paramData = getParamData(req.body); - const baseToken = paramData.base; - const quoteToken = paramData.quote; - const tradeType = paramData.side.toUpperCase(); - const amount = parseFloat(paramData.amount); - const gasPrice = parseFloat(paramData.gas_price) || terra.lcd.config.gasPrices.uluna; - const gasAdjustment = paramData.gas_adjustment || terra.lcd.config.gasAdjustment; - const secret = paramData.privateKey; + const paramData = getParamData(req.body) + const baseToken = paramData.base + const quoteToken = paramData.quote + const tradeType = paramData.side.toUpperCase() + const amount = parseFloat(paramData.amount) + const gasPrice = + parseFloat(paramData.gas_price) || terra.lcd.config.gasPrices.uluna + const gasAdjustment = + paramData.gas_adjustment || terra.lcd.config.gasAdjustment + const secret = paramData.privateKey - let tokenSwaps; + let tokenSwaps try { - await terra.swapTokens(baseToken, quoteToken, amount, tradeType, gasPrice, gasAdjustment, secret).then((swap) => { - tokenSwaps = swap; - }).catch((err) => { - reportConnectionError(res, err); - }); + await terra + .swapTokens( + baseToken, + quoteToken, + amount, + tradeType, + gasPrice, + gasAdjustment, + secret + ) + .then((swap) => { + tokenSwaps = swap + }) + .catch((err) => { + reportConnectionError(res, err) + }) const swapResult = { network, @@ -198,30 +219,32 @@ router.post('/trade', async (req, res) => { base: baseToken, tradeType, quote: quoteToken, - amount, - }; - Object.assign(swapResult, tokenSwaps); - logger.info(`terra.route - ${tradeType}: ${baseToken}-${quoteToken} - Amount: ${amount}`); - res.status(200).json( - swapResult, - ); + amount + } + Object.assign(swapResult, tokenSwaps) + logger.info( + `terra.route - ${tradeType}: ${baseToken}-${quoteToken} - Amount: ${amount}` + ) + res.status(200).json(swapResult) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let message; - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; - const isAxiosError = err.isAxiosError; + logger.error(req.originalUrl, { message: err }) + let message + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) + const isAxiosError = err.isAxiosError if (isAxiosError) { - reason = err.response.status; - message = err.response.statusText; + reason = err.response.status + message = err.response.statusText } else { - message = err; + message = err } res.status(500).json({ error: reason, - message, - }); + message + }) } -}); +}) -module.exports = router; +module.exports = router diff --git a/src/routes/uniswap.route.js b/src/routes/uniswap.route.js index 825bfb8..6201ae0 100644 --- a/src/routes/uniswap.route.js +++ b/src/routes/uniswap.route.js @@ -1,44 +1,44 @@ -import { ethers } from 'ethers'; -import express from 'express'; +import { ethers } from 'ethers' +import express from 'express' -import { getParamData, latency, statusMessages } from '../services/utils'; -import { logger } from '../services/logger'; -import Ethereum from '../services/eth'; -import Uniswap from '../services/uniswap'; -import Fees from '../services/fees'; +import { getParamData, latency, statusMessages } from '../services/utils' +import { logger } from '../services/logger' +import Ethereum from '../services/eth' +import Uniswap from '../services/uniswap' +import Fees from '../services/fees' -require('dotenv').config(); +require('dotenv').config() -const debug = require('debug')('router'); +const debug = require('debug')('router') -const router = express.Router(); -const eth = new Ethereum(process.env.ETHEREUM_CHAIN); -const uniswap = new Uniswap(process.env.ETHEREUM_CHAIN); -uniswap.generate_tokens(); -setTimeout(uniswap.update_pairs.bind(uniswap), 2000); -const fees = new Fees(); +const router = express.Router() +const eth = new Ethereum(process.env.ETHEREUM_CHAIN) +const uniswap = new Uniswap(process.env.ETHEREUM_CHAIN) +uniswap.generate_tokens() +setTimeout(uniswap.update_pairs.bind(uniswap), 2000) +const fees = new Fees() -const swapMoreThanMaxPriceError = 'Price too high'; -const swapLessThanMaxPriceError = 'Price too low'; +const swapMoreThanMaxPriceError = 'Price too high' +const swapLessThanMaxPriceError = 'Price too low' -const estimateGasLimit = () => uniswap.gasLimit; +const estimateGasLimit = () => uniswap.gasLimit const getErrorMessage = (err) => { /* [WIP] Custom error message based-on string match */ - let message = err; + let message = err if (err.includes('failed to meet quorum')) { - message = 'Failed to meet quorum in Uniswap'; + message = 'Failed to meet quorum in Uniswap' } else if (err.includes('Invariant failed: ADDRESSES')) { - message = 'Invariant failed: ADDRESSES'; + message = 'Invariant failed: ADDRESSES' } else if (err.includes('"call revert exception')) { - message = statusMessages.no_pool_available; + message = statusMessages.no_pool_available } else if (err.includes('"trade" is read-only')) { - message = statusMessages.no_pool_available; + message = statusMessages.no_pool_available } - return message; -}; + return message +} router.post('/', async (req, res) => { /* @@ -49,32 +49,34 @@ router.post('/', async (req, res) => { provider: uniswap.provider.connection.url, uniswap_router: uniswap.router, connection: true, - timestamp: Date.now(), - }); -}); + timestamp: Date.now() + }) +}) router.post('/gas-limit', async (req, res) => { /* POST: /buy-price */ - const gasLimit = estimateGasLimit(); + const gasLimit = estimateGasLimit() try { res.status(200).json({ network: uniswap.network, gasLimit, - timestamp: Date.now(), - }); + timestamp: Date.now() + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.get('/start', async (req, res) => { /* @@ -84,38 +86,47 @@ router.get('/start', async (req, res) => { "gasPrice":30 } */ - const initTime = Date.now(); - const paramData = getParamData(req.query); - const pairs = JSON.parse(paramData.pairs); - let gasPrice; + const initTime = Date.now() + const paramData = getParamData(req.query) + const pairs = JSON.parse(paramData.pairs) + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } // get token contract address and cache paths for (let pair of pairs) { - pair = pair.split('-'); - const baseTokenSymbol = pair[0]; - const quoteTokenSymbol = pair[1]; - const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol); + pair = pair.split('-') + const baseTokenSymbol = pair[0] + const quoteTokenSymbol = pair[1] + const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) // check for valid token symbols - if (baseTokenContractInfo === undefined || quoteTokenContractInfo === undefined) { - const undefinedToken = baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol; + if ( + baseTokenContractInfo === undefined || + quoteTokenContractInfo === undefined + ) { + const undefinedToken = + baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol res.status(500).json({ error: `Token ${undefinedToken} contract address not found`, - message: `Token contract address not found for ${undefinedToken}. Check token list source`, - }); - return; + message: `Token contract address not found for ${undefinedToken}. Check token list source` + }) + return } - await Promise.allSettled([uniswap.extend_update_pairs([baseTokenContractInfo.address, quoteTokenContractInfo.address])]); + await Promise.allSettled([ + uniswap.extend_update_pairs([ + baseTokenContractInfo.address, + quoteTokenContractInfo.address + ]) + ]) } - const gasLimit = estimateGasLimit(); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) const result = { network: eth.network, @@ -125,10 +136,10 @@ router.get('/start', async (req, res) => { pairs, gasPrice, gasLimit, - gasCost, - }; - res.status(200).json(result); -}); + gasCost + } + res.status(200).json(result) +}) router.post('/trade', async (req, res) => { /* @@ -143,57 +154,58 @@ router.post('/trade', async (req, res) => { "side":{buy|sell} } */ - const initTime = Date.now(); + const initTime = Date.now() // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const wallet = new ethers.Wallet(privateKey, uniswap.provider); - const amount = paramData.amount; + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = new ethers.Wallet(privateKey, uniswap.provider) + const amount = paramData.amount - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); - const baseTokenAddress = baseTokenContractInfo.address; - const quoteTokenAddress = quoteTokenContractInfo.address; - const side = paramData.side.toUpperCase(); + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const side = paramData.side.toUpperCase() - let limitPrice; + let limitPrice if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice); + limitPrice = parseFloat(paramData.limitPrice) } - let gasPrice; + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } - const gasLimit = estimateGasLimit(); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) try { // fetch the optimal pool mix from uniswap - const { trade, expectedAmount } = side === 'BUY' - ? await uniswap.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount, - ) - : await uniswap.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount, - ); + const { trade, expectedAmount } = + side === 'BUY' + ? await uniswap.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount + ) + : await uniswap.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount + ) if (side === 'BUY') { - const price = trade.executionPrice.invert().toSignificant(8); - logger.info(`uniswap.route - Price: ${price.toString()}`); + const price = trade.executionPrice.invert().toSignificant(8) + logger.info(`uniswap.route - Price: ${price.toString()}`) if (!limitPrice || price <= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await uniswap.swapExactOut( wallet, trade, baseTokenAddress, - gasPrice, - ); + gasPrice + ) // submit response res.status(200).json({ network: uniswap.network, @@ -207,27 +219,29 @@ router.post('/trade', async (req, res) => { gasPrice, gasLimit, gasCost, - txHash: tx.hash, - }); + txHash: tx.hash + }) } else { res.status(200).json({ error: swapMoreThanMaxPriceError, - message: `Swap price ${price} exceeds limitPrice ${limitPrice}`, - }); - logger.info(`uniswap.route - Swap price ${price} exceeds limitPrice ${limitPrice}`); + message: `Swap price ${price} exceeds limitPrice ${limitPrice}` + }) + logger.info( + `uniswap.route - Swap price ${price} exceeds limitPrice ${limitPrice}` + ) } } else { // sell - const price = trade.executionPrice.toSignificant(8); - logger.info(`Price: ${price.toString()}`); + const price = trade.executionPrice.toSignificant(8) + logger.info(`Price: ${price.toString()}`) if (!limitPrice || price >= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await uniswap.swapExactIn( wallet, trade, baseTokenAddress, - gasPrice, - ); + gasPrice + ) // submit response res.status(200).json({ network: uniswap.network, @@ -241,26 +255,30 @@ router.post('/trade', async (req, res) => { gasPrice, gasLimit, gasCost, - txHash: tx.hash, - }); + txHash: tx.hash + }) } else { res.status(200).json({ error: swapLessThanMaxPriceError, - message: `Swap price ${price} lower than limitPrice ${limitPrice}`, - }); - logger.info(`uniswap.route - Swap price ${price} lower than limitPrice ${limitPrice}`); + message: `Swap price ${price} lower than limitPrice ${limitPrice}` + }) + logger.info( + `uniswap.route - Swap price ${price} lower than limitPrice ${limitPrice}` + ) } } } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/price', async (req, res) => { /* @@ -271,47 +289,49 @@ router.post('/price', async (req, res) => { "amount":1 } */ - const initTime = Date.now(); + const initTime = Date.now() // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body); - const amount = paramData.amount; + const paramData = getParamData(req.body) + const amount = paramData.amount - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); - const baseTokenAddress = baseTokenContractInfo.address; - const quoteTokenAddress = quoteTokenContractInfo.address; - const side = paramData.side.toUpperCase(); - let gasPrice; + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const side = paramData.side.toUpperCase() + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } - const gasLimit = estimateGasLimit(); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) try { // fetch the optimal pool mix from uniswap - const { trade, expectedAmount } = side === 'BUY' - ? await uniswap.priceSwapOut( - quoteTokenAddress, // tokenIn is quote asset - baseTokenAddress, // tokenOut is base asset - amount, - ) - : await uniswap.priceSwapIn( - baseTokenAddress, // tokenIn is base asset - quoteTokenAddress, // tokenOut is quote asset - amount, - ); + const { trade, expectedAmount } = + side === 'BUY' + ? await uniswap.priceSwapOut( + quoteTokenAddress, // tokenIn is quote asset + baseTokenAddress, // tokenOut is base asset + amount + ) + : await uniswap.priceSwapIn( + baseTokenAddress, // tokenIn is base asset + quoteTokenAddress, // tokenOut is quote asset + amount + ) if (trade !== null && expectedAmount !== null) { - const price = side === 'BUY' - ? trade.executionPrice.invert().toSignificant(8) - : trade.executionPrice.toSignificant(8); + const price = + side === 'BUY' + ? trade.executionPrice.invert().toSignificant(8) + : trade.executionPrice.toSignificant(8) - const tradeAmount = parseFloat(amount); - const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)); - const tradePrice = parseFloat(price); + const tradeAmount = parseFloat(amount) + const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)) + const tradePrice = parseFloat(price) const result = { network: uniswap.network, @@ -325,40 +345,45 @@ router.post('/price', async (req, res) => { gasPrice, gasLimit, gasCost, - trade, - }; - debug(`Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`); - res.status(200).json(result); - } else { // no pool available + trade + } + debug( + `Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH` + ) + res.status(200).json(result) + } else { + // no pool available res.status(200).json({ info: statusMessages.no_pool_available, - message: '', - }); + message: '' + }) } } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - let errCode = 500; + logger.error(req.originalUrl, { message: err }) + let reason + let errCode = 500 if (Object.keys(err).includes('isInsufficientReservesError')) { - errCode = 200; - reason = `${statusMessages.insufficient_reserves} in ${side} at Uniswap`; + errCode = 200 + reason = `${statusMessages.insufficient_reserves} in ${side} at Uniswap` } else if (Object.getOwnPropertyNames(err).includes('message')) { - reason = getErrorMessage(err.message); + reason = getErrorMessage(err.message) if (reason === statusMessages.no_pool_available) { - errCode = 200; + errCode = 200 res.status(errCode).json({ info: reason, - message: err, - }); + message: err + }) } } else { - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) } res.status(errCode).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) -export default router; +export default router diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js index 7be8d43..c184f40 100644 --- a/src/routes/uniswap_v3.route.js +++ b/src/routes/uniswap_v3.route.js @@ -1,45 +1,48 @@ -import { ethers } from 'ethers'; -import express from 'express'; +import { ethers } from 'ethers' +import express from 'express' import { - getNonceManager, getParamData, latency, statusMessages, -} from '../services/utils'; + getNonceManager, + getParamData, + latency, + statusMessages +} from '../services/utils' -import { logger } from '../services/logger'; -import Ethereum from '../services/eth'; -import UniswapV3 from '../services/uniswap_v3'; -import Fees from '../services/fees'; +import { logger } from '../services/logger' +import Ethereum from '../services/eth' +import UniswapV3 from '../services/uniswap_v3' +import Fees from '../services/fees' -require('dotenv').config(); +require('dotenv').config() -const debug = require('debug')('router'); +const debug = require('debug')('router') -const router = express.Router(); -const eth = new Ethereum(process.env.ETHEREUM_CHAIN); -const uniswap = new UniswapV3(process.env.ETHEREUM_CHAIN); +const router = express.Router() +const eth = new Ethereum(process.env.ETHEREUM_CHAIN) +const uniswap = new UniswapV3(process.env.ETHEREUM_CHAIN) -const fees = new Fees(); +const fees = new Fees() // const swapMoreThanMaxPriceError = 'Price too high' // const swapLessThanMaxPriceError = 'Price too low' -const estimateGasLimit = () => uniswap.gasLimit; +const estimateGasLimit = () => uniswap.gasLimit const getErrorMessage = (err) => { /* [WIP] Custom error message based-on string match */ - let message = err; + let message = err if (err.includes('failed to meet quorum')) { - message = 'Failed to meet quorum in Uniswap'; + message = 'Failed to meet quorum in Uniswap' } else if (err.includes('Invariant failed: ADDRESSES')) { - message = 'Invariant failed: ADDRESSES'; + message = 'Invariant failed: ADDRESSES' } else if (err.includes('"call revert exception')) { - message = statusMessages.no_pool_available; + message = statusMessages.no_pool_available } else if (err.includes('"trade" is read-only')) { - message = statusMessages.no_pool_available; + message = statusMessages.no_pool_available } - return message; -}; + return message +} router.post('/', async (req, res) => { /* @@ -50,32 +53,34 @@ router.post('/', async (req, res) => { provider: uniswap.provider.connection.url, uniswap_router: uniswap.router, connection: true, - timestamp: Date.now(), - }); -}); + timestamp: Date.now() + }) +}) router.post('/gas-limit', async (req, res) => { /* POST: /gas-limit */ - const gasLimit = estimateGasLimit(); + const gasLimit = estimateGasLimit() try { res.status(200).json({ network: uniswap.network, gasLimit, - timestamp: Date.now(), - }); + timestamp: Date.now() + }) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/result', async (req, res) => { /* @@ -84,21 +89,21 @@ router.post('/result', async (req, res) => { "logs":"[...]" } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const logs = JSON.parse(paramData.logs); + const initTime = Date.now() + const paramData = getParamData(req.body) + const logs = JSON.parse(paramData.logs) const result = { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - info: uniswap.abiDecoder.decodeLogs(logs), - }; - res.status(200).json(result); -}); + info: uniswap.abiDecoder.decodeLogs(logs) + } + res.status(200).json(result) +}) router.post('/trade', async (req, res) => { -/* + /* POST: /trade x-www-form-urlencoded: { "quote":"BAT" @@ -111,32 +116,36 @@ router.post('/trade', async (req, res) => { "side":{buy|sell} } */ - const initTime = Date.now(); + const initTime = Date.now() // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); - const amount = paramData.amount; - - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); - const baseTokenAddress = baseTokenContractInfo.address; - const quoteTokenAddress = quoteTokenContractInfo.address; - const side = paramData.side.toUpperCase(); - const tier = paramData.tier.toUpperCase(); - - let limitPrice; + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = await getNonceManager( + new ethers.Wallet(privateKey, uniswap.provider) + ) + const amount = paramData.amount + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + const side = paramData.side.toUpperCase() + const tier = paramData.tier.toUpperCase() + + let limitPrice if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice); - } else { limitPrice = 0; } - let gasPrice; + limitPrice = parseFloat(paramData.limitPrice) + } else { + limitPrice = 0 + } + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } - const gasLimit = estimateGasLimit(); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) try { if (side === 'BUY') { @@ -147,8 +156,8 @@ router.post('/trade', async (req, res) => { amount, limitPrice, tier, - gasPrice, - ); + gasPrice + ) // submit response res.status(200).json({ network: uniswap.network, @@ -162,8 +171,8 @@ router.post('/trade', async (req, res) => { gasPrice, gasLimit, gasCost, - txHash: tx.hash, - }); + txHash: tx.hash + }) } else { // sell const tx = await uniswap.swapExactIn( @@ -173,8 +182,8 @@ router.post('/trade', async (req, res) => { amount, limitPrice, tier, - gasPrice, - ); + gasPrice + ) // submit response res.status(200).json({ @@ -189,19 +198,21 @@ router.post('/trade', async (req, res) => { gasPrice, gasLimit, gasCost, - txHash: tx.hash, - }); + txHash: tx.hash + }) } } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(500).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/price', async (req, res) => { /* @@ -211,29 +222,35 @@ router.post('/price', async (req, res) => { "base":"DAI" } */ - const initTime = Date.now(); + const initTime = Date.now() // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); - - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); - const baseTokenAddress = baseTokenContractInfo.address; - const quoteTokenAddress = quoteTokenContractInfo.address; - - let gasPrice; + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = await getNonceManager( + new ethers.Wallet(privateKey, uniswap.provider) + ) + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) + const baseTokenAddress = baseTokenContractInfo.address + const quoteTokenAddress = quoteTokenContractInfo.address + + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } - const gasLimit = estimateGasLimit(); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) try { // fetch pools for all tiers - const prices = await uniswap.currentPrice(wallet, baseTokenAddress, quoteTokenAddress); + const prices = await uniswap.currentPrice( + wallet, + baseTokenAddress, + quoteTokenAddress + ) const result = { network: uniswap.network, @@ -244,35 +261,43 @@ router.post('/price', async (req, res) => { prices, gasPrice, gasLimit, - gasCost, - }; - debug(`Mid Price ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | (rate:${JSON.stringify(prices)}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH`); - res.status(200).json(result); + gasCost + } + debug( + `Mid Price ${baseTokenContractInfo.symbol}-${ + quoteTokenContractInfo.symbol + } | (rate:${JSON.stringify( + prices + )}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH` + ) + res.status(200).json(result) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - let errCode = 500; + logger.error(req.originalUrl, { message: err }) + let reason + let errCode = 500 if (Object.keys(err).includes('isInsufficientReservesError')) { - errCode = 200; - reason = `${statusMessages.insufficient_reserves} at Uniswap`; + errCode = 200 + reason = `${statusMessages.insufficient_reserves} at Uniswap` } else if (Object.getOwnPropertyNames(err).includes('message')) { - reason = getErrorMessage(err.message); + reason = getErrorMessage(err.message) if (reason === statusMessages.no_pool_available) { - errCode = 200; + errCode = 200 res.status(errCode).json({ info: reason, - message: err, - }); + message: err + }) } } else { - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) } res.status(errCode).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) // LP section @@ -283,32 +308,34 @@ router.post('/position', async (req, res) => { "tokenId":"tokenId" } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); - const tokenId = paramData.tokenId; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = await getNonceManager( + new ethers.Wallet(privateKey, uniswap.provider) + ) + const tokenId = paramData.tokenId try { // fetch position data - const positionData = await uniswap.getPosition(wallet, tokenId); + const positionData = await uniswap.getPosition(wallet, tokenId) const result = { network: uniswap.network, timestamp: initTime, latency: latency(initTime, Date.now()), - position: positionData, - }; - debug(`Position data: ${positionData} `); - res.status(200).json(result); + position: positionData + } + debug(`Position data: ${positionData} `) + res.status(200).json(result) } catch (err) { - logger.error(req.originalUrl, { message: err }); + logger.error(req.originalUrl, { message: err }) res.status(500).json({ info: statusMessages.operation_error, - position: {}, - }); + position: {} + }) } -}); +}) router.post('/add-position', async (req, res) => { /* @@ -323,31 +350,42 @@ router.post('/add-position', async (req, res) => { "amount1": amount1 } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); - - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1); - const fee = paramData.fee; - const lowerPrice = parseFloat(paramData.lowerPrice); - const upperPrice = parseFloat(paramData.upperPrice); - const amount0 = paramData.amount0; - const amount1 = paramData.amount1; - - let gasPrice; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = await getNonceManager( + new ethers.Wallet(privateKey, uniswap.provider) + ) + + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1) + const fee = paramData.fee + const lowerPrice = parseFloat(paramData.lowerPrice) + const upperPrice = parseFloat(paramData.upperPrice) + const amount0 = paramData.amount0 + const amount1 = paramData.amount1 + + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } - const gasLimit = estimateGasLimit(); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) try { // add position to pool - const newPosition = await uniswap.addPosition(wallet, baseTokenContractInfo, quoteTokenContractInfo, amount0, amount1, fee, lowerPrice, upperPrice); + const newPosition = await uniswap.addPosition( + wallet, + baseTokenContractInfo, + quoteTokenContractInfo, + amount0, + amount1, + fee, + lowerPrice, + upperPrice + ) const result = { network: uniswap.network, @@ -363,18 +401,18 @@ router.post('/add-position', async (req, res) => { hash: newPosition.hash, gasPrice, gasLimit, - gasCost, - }; - debug(`New Position: ${newPosition.hash}`); - res.status(200).json(result); + gasCost + } + debug(`New Position: ${newPosition.hash}`) + res.status(200).json(result) } catch (err) { - logger.error(req.originalUrl, { message: err }); + logger.error(req.originalUrl, { message: err }) res.status(200).json({ info: statusMessages.operation_error, - message: err, - }); + message: err + }) } -}); +}) router.post('/remove-position', async (req, res) => { /* @@ -383,23 +421,25 @@ router.post('/remove-position', async (req, res) => { "tokenId":"12" } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); - const tokenId = paramData.tokenId; - - let gasPrice; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = await getNonceManager( + new ethers.Wallet(privateKey, uniswap.provider) + ) + const tokenId = paramData.tokenId + + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } - const gasLimit = estimateGasLimit(); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) try { - const removelp = await uniswap.removePosition(wallet, tokenId); + const removelp = await uniswap.removePosition(wallet, tokenId) const result = { network: uniswap.network, @@ -408,21 +448,23 @@ router.post('/remove-position', async (req, res) => { hash: removelp.hash, gasPrice, gasLimit, - gasCost, - }; - debug(`Remove lp: ${removelp.hash}`); - res.status(200).json(result); + gasCost + } + debug(`Remove lp: ${removelp.hash}`) + res.status(200).json(result) } catch (err) { - logger.error(req.originalUrl, { message: err }); - let reason; - const errCode = 500; - err.reason ? reason = err.reason : reason = statusMessages.operation_error; + logger.error(req.originalUrl, { message: err }) + let reason + const errCode = 500 + err.reason + ? (reason = err.reason) + : (reason = statusMessages.operation_error) res.status(errCode).json({ error: reason, - message: err, - }); + message: err + }) } -}); +}) router.post('/replace-position', async (req, res) => { /* @@ -438,33 +480,45 @@ router.post('/replace-position', async (req, res) => { "amount1": amount1 } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); - const tokenId = paramData.tokenId; - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0); - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1); - const fee = paramData.fee; - const lowerPrice = parseFloat(paramData.lowerPrice); - const upperPrice = parseFloat(paramData.upperPrice); - const amount0 = paramData.amount0; - const amount1 = paramData.amount1; - - let gasPrice; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = await getNonceManager( + new ethers.Wallet(privateKey, uniswap.provider) + ) + const tokenId = paramData.tokenId + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0) + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1) + const fee = paramData.fee + const lowerPrice = parseFloat(paramData.lowerPrice) + const upperPrice = parseFloat(paramData.upperPrice) + const amount0 = paramData.amount0 + const amount1 = paramData.amount1 + + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } - const gasLimit = estimateGasLimit(); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) try { // const position = await uniswap.getPosition(wallet, tokenId) // const token0 = eth.getERC20TokenByAddress(position.token0) // const token1 = eth.getERC20TokenByAddress(position.token1) - const positionChange = await uniswap.replacePosition(wallet, tokenId, baseTokenContractInfo, quoteTokenContractInfo, amount0, amount1, fee, lowerPrice, upperPrice); + const positionChange = await uniswap.replacePosition( + wallet, + tokenId, + baseTokenContractInfo, + quoteTokenContractInfo, + amount0, + amount1, + fee, + lowerPrice, + upperPrice + ) const result = { network: uniswap.network, @@ -476,18 +530,18 @@ router.post('/replace-position', async (req, res) => { hash: positionChange.hash, gasPrice, gasLimit, - gasCost, - }; - debug(`Position change ${positionChange.hash}`); - res.status(200).json(result); + gasCost + } + debug(`Position change ${positionChange.hash}`) + res.status(200).json(result) } catch (err) { - logger.error(req.originalUrl, { message: err }); + logger.error(req.originalUrl, { message: err }) res.status(200).json({ info: statusMessages.operation_error, - message: err, - }); + message: err + }) } -}); +}) router.post('/collect-fees', async (req, res) => { /* @@ -498,24 +552,26 @@ router.post('/collect-fees', async (req, res) => { "amount1": amount1 } */ - const initTime = Date.now(); - const paramData = getParamData(req.body); - const privateKey = paramData.privateKey; - const wallet = await getNonceManager(new ethers.Wallet(privateKey, uniswap.provider)); - const tokenId = paramData.tokenId; - - let gasPrice; + const initTime = Date.now() + const paramData = getParamData(req.body) + const privateKey = paramData.privateKey + const wallet = await getNonceManager( + new ethers.Wallet(privateKey, uniswap.provider) + ) + const tokenId = paramData.tokenId + + let gasPrice if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice); + gasPrice = parseFloat(paramData.gasPrice) } else { - gasPrice = fees.ethGasPrice; + gasPrice = fees.ethGasPrice } - const gasLimit = estimateGasLimit(); - const gasCost = await fees.getGasCost(gasPrice, gasLimit); + const gasLimit = estimateGasLimit() + const gasCost = await fees.getGasCost(gasPrice, gasLimit) try { // withdraw fees - const collect = await uniswap.collectFees(wallet, tokenId); + const collect = await uniswap.collectFees(wallet, tokenId) const result = { network: uniswap.network, @@ -525,17 +581,17 @@ router.post('/collect-fees', async (req, res) => { hash: collect.hash, gasPrice, gasLimit, - gasCost, - }; - debug(`Fees: ${collect.hash}`); - res.status(200).json(result); + gasCost + } + debug(`Fees: ${collect.hash}`) + res.status(200).json(result) } catch (err) { - logger.error(req.originalUrl, { message: err }); + logger.error(req.originalUrl, { message: err }) res.status(200).json({ info: statusMessages.operation_error, - message: err, - }); + message: err + }) } -}); +}) -export default router; +export default router diff --git a/src/services/access.js b/src/services/access.js index cf374b9..d917e80 100644 --- a/src/services/access.js +++ b/src/services/access.js @@ -2,23 +2,23 @@ middleware for validating mutual authentication access */ -import { logger } from './logger'; -import { statusMessages } from './utils'; +import { logger } from './logger' +import { statusMessages } from './utils' export const validateAccess = (req, res, next) => { - const cert = req.connection.getPeerCertificate(); + const cert = req.connection.getPeerCertificate() if (req.client.authorized) { - const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; - const method = req.method; - const url = req.url; - const requestInfo = `Request from IP: ${ip} ${method} ${url}`; - console.log(requestInfo); - next(); + const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress + const method = req.method + const url = req.url + const requestInfo = `Request from IP: ${ip} ${method} ${url}` + console.log(requestInfo) + next() } else if (cert.subject) { - logger.error(statusMessages.ssl_cert_invalid); - res.status(403).send({ error: statusMessages.ssl_cert_invalid }); + logger.error(statusMessages.ssl_cert_invalid) + res.status(403).send({ error: statusMessages.ssl_cert_invalid }) } else { - logger.error(statusMessages.ssl_cert_required); - res.status(401).send({ error: statusMessages.ssl_cert_required }); + logger.error(statusMessages.ssl_cert_required) + res.status(401).send({ error: statusMessages.ssl_cert_required }) } -}; +} diff --git a/src/services/balancer.js b/src/services/balancer.js index a954f21..aa3715c 100644 --- a/src/services/balancer.js +++ b/src/services/balancer.js @@ -1,75 +1,92 @@ -import { logger } from './logger'; +import { logger } from './logger' -const debug = require('debug')('router'); -require('dotenv').config(); // DO NOT REMOVE. needed to configure REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor -const sor = require('@balancer-labs/sor'); -const BigNumber = require('bignumber.js'); -const ethers = require('ethers'); -const proxyArtifact = require('../static/ExchangeProxy.json'); +const debug = require('debug')('router') +require('dotenv').config() // DO NOT REMOVE. needed to configure REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor +const sor = require('@balancer-labs/sor') +const BigNumber = require('bignumber.js') +const ethers = require('ethers') +const proxyArtifact = require('../static/ExchangeProxy.json') // constants -const MULTI = '0xeefba1e63905ef1d7acba5a8513c70307c1ce441'; -const MULTI_KOVAN = ' 0x2cc8688C5f75E365aaEEb4ea8D6a480405A48D2A'; -const MAX_UINT = ethers.constants.MaxUint256; -const GAS_BASE = process.env.BALANCER_GAS_BASE || 200688; -const GAS_PER_SWAP = process.env.BALANCER_GAS_PER_SWAP || 100000; +const MULTI = '0xeefba1e63905ef1d7acba5a8513c70307c1ce441' +const MULTI_KOVAN = ' 0x2cc8688C5f75E365aaEEb4ea8D6a480405A48D2A' +const MAX_UINT = ethers.constants.MaxUint256 +const GAS_BASE = process.env.BALANCER_GAS_BASE || 200688 +const GAS_PER_SWAP = process.env.BALANCER_GAS_PER_SWAP || 100000 export default class Balancer { constructor(network = 'kovan') { - const providerUrl = process.env.ETHEREUM_RPC_URL; - this.network = process.env.ETHEREUM_CHAIN; - this.provider = new ethers.providers.JsonRpcProvider(providerUrl); - this.subgraphUrl = process.env.REACT_APP_SUBGRAPH_URL; - this.gasBase = GAS_BASE; - this.gasPerSwap = GAS_PER_SWAP; - this.maxSwaps = process.env.BALANCER_MAX_SWAPS || 4; - this.exchangeProxy = process.env.EXCHANGE_PROXY; - this.cachedPools = []; + const providerUrl = process.env.ETHEREUM_RPC_URL + this.network = process.env.ETHEREUM_CHAIN + this.provider = new ethers.providers.JsonRpcProvider(providerUrl) + this.subgraphUrl = process.env.REACT_APP_SUBGRAPH_URL + this.gasBase = GAS_BASE + this.gasPerSwap = GAS_PER_SWAP + this.maxSwaps = process.env.BALANCER_MAX_SWAPS || 4 + this.exchangeProxy = process.env.EXCHANGE_PROXY + this.cachedPools = [] switch (network) { case 'mainnet': - this.multiCall = MULTI; - break; + this.multiCall = MULTI + break case 'kovan': - this.multiCall = MULTI_KOVAN; - break; + this.multiCall = MULTI_KOVAN + break default: - const err = `Invalid network ${network}`; - logger.error(err); - throw Error(err); + const err = `Invalid network ${network}` + logger.error(err) + throw Error(err) } } async fetchPool(tokenIn, tokenOut) { - const pools = await sor.getPoolsWithTokens(tokenIn, tokenOut); - this.cachedPools[tokenIn + tokenOut] = pools; + const pools = await sor.getPoolsWithTokens(tokenIn, tokenOut) + this.cachedPools[tokenIn + tokenOut] = pools if (pools.pools.length === 0) { - debug('>>> No pools contain the tokens provided.', { message: this.network }); - return {}; + debug('>>> No pools contain the tokens provided.', { + message: this.network + }) + return {} } - debug(`>>> ${pools.pools.length} Pools Retrieved.`, { message: this.network }); + debug(`>>> ${pools.pools.length} Pools Retrieved.`, { + message: this.network + }) } async getCachedPools(tokenIn, tokenOut) { - const cachePools = this.cachedPools[tokenIn + tokenOut].pools; - debug(`>>> get cached Pools. ${tokenIn + tokenOut}`, { message: `total pools: ${cachePools.length}` }); - return cachePools; + const cachePools = this.cachedPools[tokenIn + tokenOut].pools + debug(`>>> get cached Pools. ${tokenIn + tokenOut}`, { + message: `total pools: ${cachePools.length}` + }) + return cachePools } - async priceSwapIn(tokenIn, tokenOut, tokenInAmount, maxSwaps = this.maxSwaps) { + async priceSwapIn( + tokenIn, + tokenOut, + tokenInAmount, + maxSwaps = this.maxSwaps + ) { // Fetch all the pools that contain the tokens provided try { // Get current on-chain data about the fetched pools - await this.fetchPool(tokenIn, tokenOut); + await this.fetchPool(tokenIn, tokenOut) - let poolData; - const cachedPools = await this.getCachedPools(tokenIn, tokenOut); + let poolData + const cachedPools = await this.getCachedPools(tokenIn, tokenOut) if (this.network === 'mainnet') { - poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider); + poolData = await sor.parsePoolDataOnChain( + cachedPools, + tokenIn, + tokenOut, + this.multiCall, + this.provider + ) } else { // Kovan multicall throws an ENS error - poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut); + poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) } // Parse the pools and pass them to smart order outer to get the swaps needed @@ -78,15 +95,15 @@ export default class Balancer { 'swapExactIn', // swapType: string tokenInAmount, // targetInputAmount: BigNumber new BigNumber(maxSwaps.toString()), // maxBalancers: number - 0, // costOutputToken: BigNumber - ); + 0 // costOutputToken: BigNumber + ) - const swapsFormatted = sor.formatSwapsExactAmountIn(sorSwaps, MAX_UINT, 0); - const expectedAmount = sor.calcTotalOutput(swapsFormatted, poolData); - debug(`Expected Out: ${expectedAmount.toString()} (${tokenOut})`); + const swapsFormatted = sor.formatSwapsExactAmountIn(sorSwaps, MAX_UINT, 0) + const expectedAmount = sor.calcTotalOutput(swapsFormatted, poolData) + debug(`Expected Out: ${expectedAmount.toString()} (${tokenOut})`) // Create correct swap format for new proxy - const swaps = []; + const swaps = [] for (let i = 0; i < swapsFormatted.length; i++) { const swap = { pool: swapsFormatted[i].pool, @@ -94,32 +111,43 @@ export default class Balancer { tokenOut, swapAmount: swapsFormatted[i].tokenInParam, limitReturnAmount: swapsFormatted[i].tokenOutParam, - maxPrice: swapsFormatted[i].maxPrice.toString(), - }; - swaps.push(swap); + maxPrice: swapsFormatted[i].maxPrice.toString() + } + swaps.push(swap) } - return { swaps, expectedAmount }; + return { swaps, expectedAmount } } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error in swapExactOut'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error in swapExactOut') + return reason } } - async priceSwapOut(tokenIn, tokenOut, tokenOutAmount, maxSwaps = this.maxSwaps) { + async priceSwapOut( + tokenIn, + tokenOut, + tokenOutAmount, + maxSwaps = this.maxSwaps + ) { // Fetch all the pools that contain the tokens provided try { // Get current on-chain data about the fetched pools - await this.fetchPool(tokenIn, tokenOut); + await this.fetchPool(tokenIn, tokenOut) - let poolData; - const cachedPools = await this.getCachedPools(tokenIn, tokenOut); + let poolData + const cachedPools = await this.getCachedPools(tokenIn, tokenOut) if (this.network === 'mainnet') { - poolData = await sor.parsePoolDataOnChain(cachedPools, tokenIn, tokenOut, this.multiCall, this.provider); + poolData = await sor.parsePoolDataOnChain( + cachedPools, + tokenIn, + tokenOut, + this.multiCall, + this.provider + ) } else { // Kovan multicall throws an ENS error - poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut); + poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) } // Parse the pools and pass them to smart order outer to get the swaps needed @@ -128,14 +156,18 @@ export default class Balancer { 'swapExactOut', // swapType: string tokenOutAmount, // targetInputAmount: BigNumber new BigNumber(maxSwaps.toString()), // maxBalancers: number - 0, // costOutputToken: BigNumber - ); - const swapsFormatted = sor.formatSwapsExactAmountOut(sorSwaps, MAX_UINT, MAX_UINT); - const expectedAmount = sor.calcTotalInput(swapsFormatted, poolData); - debug(`Expected In: ${expectedAmount.toString()} (${tokenIn})`); + 0 // costOutputToken: BigNumber + ) + const swapsFormatted = sor.formatSwapsExactAmountOut( + sorSwaps, + MAX_UINT, + MAX_UINT + ) + const expectedAmount = sor.calcTotalInput(swapsFormatted, poolData) + debug(`Expected In: ${expectedAmount.toString()} (${tokenIn})`) // Create correct swap format for new proxy - const swaps = []; + const swaps = [] for (let i = 0; i < swapsFormatted.length; i++) { const swap = { pool: swapsFormatted[i].pool, @@ -143,23 +175,35 @@ export default class Balancer { tokenOut, swapAmount: swapsFormatted[i].tokenOutParam, limitReturnAmount: swapsFormatted[i].tokenInParam, - maxPrice: swapsFormatted[i].maxPrice.toString(), - }; - swaps.push(swap); + maxPrice: swapsFormatted[i].maxPrice.toString() + } + swaps.push(swap) } - return { swaps, expectedAmount }; + return { swaps, expectedAmount } } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error in swapExactOut'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error in swapExactOut') + return reason } } - async swapExactIn(wallet, swaps, tokenIn, tokenOut, amountIn, minAmountOut, gasPrice) { - debug(`Number of swaps: ${swaps.length}`); + async swapExactIn( + wallet, + swaps, + tokenIn, + tokenOut, + amountIn, + minAmountOut, + gasPrice + ) { + debug(`Number of swaps: ${swaps.length}`) try { - const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet); + const contract = new ethers.Contract( + this.exchangeProxy, + proxyArtifact.abi, + wallet + ) const tx = await contract.batchSwapExactIn( swaps, tokenIn, @@ -168,23 +212,27 @@ export default class Balancer { 0, { gasPrice: gasPrice * 1e9, - gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP, - }, - ); - debug(`Tx Hash: ${tx.hash}`); - return tx; + gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP + } + ) + debug(`Tx Hash: ${tx.hash}`) + return tx } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error in swapExactIn'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error in swapExactIn') + return reason } } async swapExactOut(wallet, swaps, tokenIn, tokenOut, expectedIn, gasPrice) { - debug(`Number of swaps: ${swaps.length}`); + debug(`Number of swaps: ${swaps.length}`) try { - const contract = new ethers.Contract(this.exchangeProxy, proxyArtifact.abi, wallet); + const contract = new ethers.Contract( + this.exchangeProxy, + proxyArtifact.abi, + wallet + ) const tx = await contract.batchSwapExactOut( swaps, tokenIn, @@ -192,16 +240,16 @@ export default class Balancer { expectedIn, { gasPrice: gasPrice * 1e9, - gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP, - }, - ); - debug(`Tx Hash: ${tx.hash}`); - return tx; + gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP + } + ) + debug(`Tx Hash: ${tx.hash}`) + return tx } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error in swapExactOut'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error in swapExactOut') + return reason } } } diff --git a/src/services/eth.js b/src/services/eth.js index 16bf93a..68d2ae9 100644 --- a/src/services/eth.js +++ b/src/services/eth.js @@ -1,87 +1,99 @@ -import axios from 'axios'; -import { logger } from './logger'; +import axios from 'axios' +import { logger } from './logger' -require('dotenv').config(); -const fs = require('fs'); -const ethers = require('ethers'); -const abi = require('../static/abi'); +require('dotenv').config() +const fs = require('fs') +const ethers = require('ethers') +const abi = require('../static/abi') // constants -const APPROVAL_GAS_LIMIT = process.env.ETH_APPROVAL_GAS_LIMIT || 50000; +const APPROVAL_GAS_LIMIT = process.env.ETH_APPROVAL_GAS_LIMIT || 50000 export default class Ethereum { constructor(network = 'mainnet') { // network defaults to kovan - const providerUrl = process.env.ETHEREUM_RPC_URL; - this.provider = new ethers.providers.JsonRpcProvider(providerUrl); - this.erc20TokenListURL = process.env.ETHEREUM_TOKEN_LIST_URL; - this.network = network; + const providerUrl = process.env.ETHEREUM_RPC_URL + this.provider = new ethers.providers.JsonRpcProvider(providerUrl) + this.erc20TokenListURL = process.env.ETHEREUM_TOKEN_LIST_URL + this.network = network // update token list - this.getERC20TokenList(); // erc20TokenList + this.getERC20TokenList() // erc20TokenList } // get ETH balance async getETHBalance(wallet) { try { - const balance = await wallet.getBalance(); - return balance / 1e18.toString(); + const balance = await wallet.getBalance() + return balance / (1e18).toString() } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error ETH balance lookup'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error ETH balance lookup') + return reason } } // get ERC-20 token balance async getERC20Balance(wallet, tokenAddress, decimals = 18) { // instantiate a contract and pass in provider for read-only access - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider); + const contract = new ethers.Contract( + tokenAddress, + abi.ERC20Abi, + this.provider + ) try { - const balance = await contract.balanceOf(wallet.address); - return balance / (10 ** decimals).toString(); + const balance = await contract.balanceOf(wallet.address) + return balance / (10 ** decimals).toString() } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error balance lookup'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error balance lookup') + return reason } } // get ERC-20 token allowance async getERC20Allowance(wallet, spender, tokenAddress, decimals = 18) { // instantiate a contract and pass in provider for read-only access - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, this.provider); + const contract = new ethers.Contract( + tokenAddress, + abi.ERC20Abi, + this.provider + ) try { - const allowance = await contract.allowance(wallet.address, spender); - return allowance / (10 ** decimals).toString(); + const allowance = await contract.allowance(wallet.address, spender) + return allowance / (10 ** decimals).toString() } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error allowance lookup'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error allowance lookup') + return reason } } // approve a spender to transfer tokens from a wallet address - async approveERC20(wallet, spender, tokenAddress, amount, gasPrice = this.gasPrice, _gasLimit) { + async approveERC20( + wallet, + spender, + tokenAddress, + amount, + gasPrice = this.gasPrice, + _gasLimit + ) { try { // fixate gas limit to prevent overwriting - const approvalGasLimit = APPROVAL_GAS_LIMIT; + const approvalGasLimit = APPROVAL_GAS_LIMIT // instantiate a contract and pass in wallet, which act on behalf of that signer - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, wallet); - return await contract.approve( - spender, - amount, { - gasPrice: gasPrice * 1e9, - gasLimit: approvalGasLimit, - }, - ); + const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, wallet) + return await contract.approve(spender, amount, { + gasPrice: gasPrice * 1e9, + gasLimit: approvalGasLimit + }) } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error approval'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error approval') + return reason } } @@ -90,77 +102,98 @@ export default class Ethereum { try { this.provider.getGasPrice().then((gas) => { // gasPrice is a BigNumber; convert it to a decimal string - const gasPrice = gas.toString(); - return gasPrice; - }); + const gasPrice = gas.toString() + return gasPrice + }) } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error gas lookup'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error gas lookup') + return reason } } - async deposit(wallet, tokenAddress, amount, gasPrice = this.gasPrice, gasLimit = this.approvalGasLimit) { + async deposit( + wallet, + tokenAddress, + amount, + gasPrice = this.gasPrice, + gasLimit = this.approvalGasLimit + ) { // deposit ETH to a contract address try { - const contract = new ethers.Contract(tokenAddress, abi.KovanWETHAbi, wallet); - return await contract.deposit( - { - value: amount, - gasPrice: gasPrice * 1e9, - gasLimit, - }, - ); + const contract = new ethers.Contract( + tokenAddress, + abi.KovanWETHAbi, + wallet + ) + return await contract.deposit({ + value: amount, + gasPrice: gasPrice * 1e9, + gasLimit + }) } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error deposit'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error deposit') + return reason } } // get ERC20 Token List async getERC20TokenList() { - let tokenListSource; + let tokenListSource try { if (this.network === 'kovan') { - tokenListSource = 'src/static/erc20_tokens_kovan.json'; - this.erc20TokenList = JSON.parse(fs.readFileSync(tokenListSource)); + tokenListSource = 'src/static/erc20_tokens_kovan.json' + this.erc20TokenList = JSON.parse(fs.readFileSync(tokenListSource)) } else if (this.network === 'mainnet') { - tokenListSource = this.erc20TokenListURL; + tokenListSource = this.erc20TokenListURL if (tokenListSource === undefined || tokenListSource === null) { - const errMessage = 'Token List source not found'; - logger.error('ERC20 Token List Error', { message: errMessage }); - console.log('eth - Error: ', errMessage); + const errMessage = 'Token List source not found' + logger.error('ERC20 Token List Error', { message: errMessage }) + console.log('eth - Error: ', errMessage) } - if (this.erc20TokenList === undefined || this.erc20TokenList === null || this.erc20TokenList === {}) { - const response = await axios.get(tokenListSource); + if ( + this.erc20TokenList === undefined || + this.erc20TokenList === null || + this.erc20TokenList === {} + ) { + const response = await axios.get(tokenListSource) if (response.status === 200 && response.data) { - this.erc20TokenList = response.data; + this.erc20TokenList = response.data } } } else { - throw Error(`Invalid network ${this.network}`); + throw Error(`Invalid network ${this.network}`) } - console.log('get ERC20 Token List', this.network, 'source', tokenListSource); + console.log( + 'get ERC20 Token List', + this.network, + 'source', + tokenListSource + ) } catch (err) { - console.log(err); - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error ERC 20 Token List'; - return reason; + console.log(err) + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error ERC 20 Token List') + return reason } } // Refactor name to getERC20TokenByName getERC20TokenAddresses(tokenSymbol) { - const tokenContractAddress = this.erc20TokenList.tokens.filter((obj) => obj.symbol === tokenSymbol.toUpperCase()); - return tokenContractAddress[0]; + const tokenContractAddress = this.erc20TokenList.tokens.filter( + (obj) => obj.symbol === tokenSymbol.toUpperCase() + ) + return tokenContractAddress[0] } getERC20TokenByAddress(tokenAddress) { - const tokenContract = this.erc20TokenList.tokens.filter((obj) => obj.address.toUpperCase() === tokenAddress.toUpperCase()); - return tokenContract[0]; + const tokenContract = this.erc20TokenList.tokens.filter( + (obj) => obj.address.toUpperCase() === tokenAddress.toUpperCase() + ) + return tokenContract[0] } } diff --git a/src/services/fees.js b/src/services/fees.js index faa5805..4a3ab6e 100644 --- a/src/services/fees.js +++ b/src/services/fees.js @@ -1,52 +1,72 @@ -import axios from 'axios'; -import BigNumber from 'bignumber.js'; -import { logger } from './logger'; +import axios from 'axios' +import BigNumber from 'bignumber.js' +import { logger } from './logger' -require('dotenv').config(); +require('dotenv').config() // constants -const ethGasStationHost = 'https://ethgasstation.info'; -const ethGasStationEnabled = process.env.ENABLE_ETH_GAS_STATION || false; -const ethGasStationApiKey = process.env.ETH_GAS_STATION_API_KEY; -const ethManualGasPrice = parseInt(process.env.MANUAL_GAS_PRICE); -const ethGasStationURL = `${ethGasStationHost}/api/ethgasAPI.json?api-key=${ethGasStationApiKey}`; -const defaultRefreshInterval = 120; -const denom = BigNumber('1e+9'); +const ethGasStationHost = 'https://ethgasstation.info' +const ethGasStationEnabled = process.env.ENABLE_ETH_GAS_STATION || false +const ethGasStationApiKey = process.env.ETH_GAS_STATION_API_KEY +const ethManualGasPrice = parseInt(process.env.MANUAL_GAS_PRICE) +const ethGasStationURL = `${ethGasStationHost}/api/ethgasAPI.json?api-key=${ethGasStationApiKey}` +const defaultRefreshInterval = 120 +const denom = BigNumber('1e+9') export default class Fees { constructor() { - this.ethGasStationGasLevel = process.env.ETH_GAS_STATION_GAS_LEVEL; - this.ethGasStationRefreshTime = (process.env.ETH_GAS_STATION_REFRESH_TIME || defaultRefreshInterval) * 1000; - this.getETHGasStationFee(this.ethGasStationGasLevel, 0); + this.ethGasStationGasLevel = process.env.ETH_GAS_STATION_GAS_LEVEL + this.ethGasStationRefreshTime = + (process.env.ETH_GAS_STATION_REFRESH_TIME || defaultRefreshInterval) * + 1000 + this.getETHGasStationFee(this.ethGasStationGasLevel, 0) } // get ETH Gas Station - async getETHGasStationFee(gasLevel = this.ethGasStationGasLevel, interval = defaultRefreshInterval) { + async getETHGasStationFee( + gasLevel = this.ethGasStationGasLevel, + interval = defaultRefreshInterval + ) { try { - if (ethGasStationEnabled === true || ethGasStationEnabled.toLowerCase() === 'true') { - const response = await axios.get(ethGasStationURL); + if ( + ethGasStationEnabled === true || + ethGasStationEnabled.toLowerCase() === 'true' + ) { + const response = await axios.get(ethGasStationURL) // divite by 10 to convert it to Gwei) - this.ethGasPrice = response.data[gasLevel] / 10; - console.log(`get ETHGasStation gas price (${gasLevel}): ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`); + this.ethGasPrice = response.data[gasLevel] / 10 + console.log( + `get ETHGasStation gas price (${gasLevel}): ${ + this.ethGasPrice + } / interval: ${this.ethGasStationRefreshTime / 1000} sec` + ) } else { - this.ethGasPrice = ethManualGasPrice; - console.log(`get manual fixed gas price: ${this.ethGasPrice} / interval: ${this.ethGasStationRefreshTime / 1000} sec`); + this.ethGasPrice = ethManualGasPrice + console.log( + `get manual fixed gas price: ${this.ethGasPrice} / interval: ${ + this.ethGasStationRefreshTime / 1000 + } sec` + ) } } catch (err) { - console.log(err); - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error ETH gas fee lookup'; - return reason; + console.log(err) + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error ETH gas fee lookup') + return reason } - if (interval > 0) { // set to '0' for one-time retrieval - setTimeout(this.getETHGasStationFee.bind(this), this.ethGasStationRefreshTime); // update every x seconds + if (interval > 0) { + // set to '0' for one-time retrieval + setTimeout( + this.getETHGasStationFee.bind(this), + this.ethGasStationRefreshTime + ) // update every x seconds } } // get gas cost async getGasCost(gasPrice, gasLimit, inGwei = false) { - const cost = gasPrice * gasLimit; - return inGwei ? cost : cost / denom; + const cost = gasPrice * gasLimit + return inGwei ? cost : cost / denom } } diff --git a/src/services/logger.js b/src/services/logger.js index d12da4c..774e0af 100644 --- a/src/services/logger.js +++ b/src/services/logger.js @@ -1,28 +1,26 @@ -import { getLocalDate } from './utils'; +import { getLocalDate } from './utils' -require('dotenv').config(); -const appRoot = require('app-root-path'); -const winston = require('winston'); -require('winston-daily-rotate-file'); +require('dotenv').config() +const appRoot = require('app-root-path') +const winston = require('winston') +require('winston-daily-rotate-file') const logFormat = winston.format.combine( winston.format.timestamp(), winston.format.align(), - winston.format.printf( - (info) => { - const localDate = getLocalDate(); - return `${localDate} | ${info.level} | ${info.message}`; - }, - ), -); + winston.format.printf((info) => { + const localDate = getLocalDate() + return `${localDate} | ${info.level} | ${info.message}` + }) +) const getLogPath = () => { - let logPath = process.env.LOG_PATH; + let logPath = process.env.LOG_PATH if (typeof logPath === 'undefined' || logPath == null || logPath === '') { - logPath = [appRoot.path, 'logs'].join('/'); + logPath = [appRoot.path, 'logs'].join('/') } - return logPath; -}; + return logPath +} const config = { file: { @@ -30,16 +28,16 @@ const config = { filename: `${getLogPath()}/logs_gateway_app.log.%DATE%`, datePattern: 'YYYY-MM-DD', handleExceptions: true, - handleRejections: true, - }, -}; + handleRejections: true + } +} -const allLogsFileTransport = new winston.transports.DailyRotateFile(config.file); +const allLogsFileTransport = new winston.transports.DailyRotateFile(config.file) const options = { format: logFormat, transports: [allLogsFileTransport], - exitOnError: false, -}; + exitOnError: false +} -export const logger = winston.createLogger(options); +export const logger = winston.createLogger(options) diff --git a/src/services/perpetual_finance.js b/src/services/perpetual_finance.js index 9113ad0..98d0afc 100644 --- a/src/services/perpetual_finance.js +++ b/src/services/perpetual_finance.js @@ -1,67 +1,70 @@ -import { logger } from './logger'; +import { logger } from './logger' -const fetch = require('cross-fetch'); +const fetch = require('cross-fetch') -const Ethers = require('ethers'); -const AmmArtifact = require('@perp/contract/build/contracts/Amm.json'); -const ClearingHouseArtifact = require('@perp/contract/build/contracts/ClearingHouse.json'); -const ClearingHouseViewerArtifact = require('@perp/contract/build/contracts/ClearingHouseViewer.json'); -const TetherTokenArtifact = require('@perp/contract/build/contracts/TetherToken.json'); +const Ethers = require('ethers') +const AmmArtifact = require('@perp/contract/build/contracts/Amm.json') +const ClearingHouseArtifact = require('@perp/contract/build/contracts/ClearingHouse.json') +const ClearingHouseViewerArtifact = require('@perp/contract/build/contracts/ClearingHouseViewer.json') +const TetherTokenArtifact = require('@perp/contract/build/contracts/TetherToken.json') -const GAS_LIMIT = 2123456; -const DEFAULT_DECIMALS = 18; -const CONTRACT_ADDRESSES = 'https://metadata.perp.exchange/'; -const XDAI_PROVIDER = process.env.XDAI_PROVIDER || 'https://dai.poa.network'; -const PNL_OPTION_SPOT_PRICE = 0; -const UPDATE_PERIOD = 60000; // stop updating prices after 30 secs from last request +const GAS_LIMIT = 2123456 +const DEFAULT_DECIMALS = 18 +const CONTRACT_ADDRESSES = 'https://metadata.perp.exchange/' +const XDAI_PROVIDER = process.env.XDAI_PROVIDER || 'https://dai.poa.network' +const PNL_OPTION_SPOT_PRICE = 0 +const UPDATE_PERIOD = 60000 // stop updating prices after 30 secs from last request export default class PerpetualFinance { constructor(network = 'mainnet') { - this.providerUrl = XDAI_PROVIDER; - this.network = network; - this.provider = new Ethers.providers.JsonRpcProvider(this.providerUrl); - this.gasLimit = GAS_LIMIT; - this.contractAddressesUrl = CONTRACT_ADDRESSES; - this.amm = {}; - this.priceCache = {}; - this.cacheExpirary = {}; - this.pairAmountCache = {}; + this.providerUrl = XDAI_PROVIDER + this.network = network + this.provider = new Ethers.providers.JsonRpcProvider(this.providerUrl) + this.gasLimit = GAS_LIMIT + this.contractAddressesUrl = CONTRACT_ADDRESSES + this.amm = {} + this.priceCache = {} + this.cacheExpirary = {} + this.pairAmountCache = {} switch (network) { case 'mainnet': - this.contractAddressesUrl += 'production.json'; - break; + this.contractAddressesUrl += 'production.json' + break case 'kovan': - this.contractAddressesUrl += 'staging.json'; - break; + this.contractAddressesUrl += 'staging.json' + break default: - const err = `Invalid network ${network}`; - logger.error(err); - throw Error(err); + const err = `Invalid network ${network}` + logger.error(err) + throw Error(err) } - this.loadedMetadata = this.load_metadata(); + this.loadedMetadata = this.load_metadata() } async load_metadata() { try { - const metadata = await fetch(this.contractAddressesUrl).then((res) => res.json()); - const layer2 = Object.keys(metadata.layers.layer2.contracts); + const metadata = await fetch(this.contractAddressesUrl).then((res) => + res.json() + ) + const layer2 = Object.keys(metadata.layers.layer2.contracts) for (const key of layer2) { if (metadata.layers.layer2.contracts[key].name === 'Amm') { - this.amm[key] = metadata.layers.layer2.contracts[key].address; + this.amm[key] = metadata.layers.layer2.contracts[key].address } else { - this[key] = metadata.layers.layer2.contracts[key].address; + this[key] = metadata.layers.layer2.contracts[key].address } } - this.layer2AmbAddr = metadata.layers.layer2.externalContracts.ambBridgeOnXDai; - this.xUsdcAddr = metadata.layers.layer2.externalContracts.usdc; - this.loadedMetadata = true; - return true; + this.layer2AmbAddr = + metadata.layers.layer2.externalContracts.ambBridgeOnXDai + this.xUsdcAddr = metadata.layers.layer2.externalContracts.usdc + this.loadedMetadata = true + return true } catch (err) { - return false; + return false } } @@ -69,70 +72,104 @@ export default class PerpetualFinance { if (Object.keys(this.cacheExpirary).length > 0) { for (const pair in this.cacheExpirary) { if (this.cacheExpirary[pair] <= Date.now()) { - delete this.cacheExpirary[pair]; - delete this.priceCache[pair]; + delete this.cacheExpirary[pair] + delete this.priceCache[pair] } } for (const pair in this.cacheExpirary) { - const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider); - await Promise.allSettled([amm.getInputPrice(0, { d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) }), - amm.getOutputPrice(0, { d: Ethers.utils.parseUnits(this.pairAmountCache[pair], DEFAULT_DECIMALS) })]) - .then((values) => { - if (!this.priceCache.hasOwnProperty(pair)) { this.priceCache[pair] = []; } - this.priceCache[pair][0] = this.pairAmountCache[pair] / Ethers.utils.formatUnits(values[0].value.d); - this.priceCache[pair][1] = Ethers.utils.formatUnits(values[1].value.d) / this.pairAmountCache[pair]; - }); + const amm = new Ethers.Contract( + this.amm[pair], + AmmArtifact.abi, + this.provider + ) + await Promise.allSettled([ + amm.getInputPrice(0, { + d: Ethers.utils.parseUnits( + this.pairAmountCache[pair], + DEFAULT_DECIMALS + ) + }), + amm.getOutputPrice(0, { + d: Ethers.utils.parseUnits( + this.pairAmountCache[pair], + DEFAULT_DECIMALS + ) + }) + ]).then((values) => { + if (!this.priceCache.hasOwnProperty(pair)) { + this.priceCache[pair] = [] + } + this.priceCache[pair][0] = + this.pairAmountCache[pair] / + Ethers.utils.formatUnits(values[0].value.d) + this.priceCache[pair][1] = + Ethers.utils.formatUnits(values[1].value.d) / + this.pairAmountCache[pair] + }) } } - setTimeout(this.update_price_loop.bind(this), 10000); // update every 10 seconds + setTimeout(this.update_price_loop.bind(this), 10000) // update every 10 seconds } // get XDai balance async getXdaiBalance(wallet) { try { - const xDaiBalance = await wallet.getBalance(); - return Ethers.utils.formatEther(xDaiBalance); + const xDaiBalance = await wallet.getBalance() + return Ethers.utils.formatEther(xDaiBalance) } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error xDai balance lookup'; - return reason; + logger.error(err) + let reason + err.reason + ? (reason = err.reason) + : (reason = 'error xDai balance lookup') + return reason } } // get XDai USDC balance async getUSDCBalance(wallet) { try { - const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet); - const layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address); - const layer2UsdcDecimals = await layer2Usdc.decimals(); - return Ethers.utils.formatUnits(layer2UsdcBalance, layer2UsdcDecimals); + const layer2Usdc = new Ethers.Contract( + this.xUsdcAddr, + TetherTokenArtifact.abi, + wallet + ) + const layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address) + const layer2UsdcDecimals = await layer2Usdc.decimals() + return Ethers.utils.formatUnits(layer2UsdcBalance, layer2UsdcDecimals) } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error balance lookup'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error balance lookup') + return reason } } // get allowance async getAllowance(wallet) { // instantiate a contract and pass in provider for read-only access - const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet); + const layer2Usdc = new Ethers.Contract( + this.xUsdcAddr, + TetherTokenArtifact.abi, + wallet + ) try { const allowanceForClearingHouse = await layer2Usdc.allowance( wallet.address, - this.ClearingHouse, - ); + this.ClearingHouse + ) - return Ethers.utils.formatUnits(allowanceForClearingHouse, DEFAULT_DECIMALS); + return Ethers.utils.formatUnits( + allowanceForClearingHouse, + DEFAULT_DECIMALS + ) } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error allowance lookup'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error allowance lookup') + return reason } } @@ -140,157 +177,242 @@ export default class PerpetualFinance { async approve(wallet, amount) { try { // instantiate a contract and pass in wallet - const layer2Usdc = new Ethers.Contract(this.xUsdcAddr, TetherTokenArtifact.abi, wallet); - const tx = await layer2Usdc.approve(this.ClearingHouse, Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS)); + const layer2Usdc = new Ethers.Contract( + this.xUsdcAddr, + TetherTokenArtifact.abi, + wallet + ) + const tx = await layer2Usdc.approve( + this.ClearingHouse, + Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) + ) // TO-DO: We may want to supply custom gasLimit value above - return tx.hash; + return tx.hash } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error approval'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error approval') + return reason } } // open Position async openPosition(side, margin, levrg, pair, minBaseAmount, wallet) { try { - const quoteAssetAmount = { d: Ethers.utils.parseUnits(margin, DEFAULT_DECIMALS) }; - const leverage = { d: Ethers.utils.parseUnits(levrg, DEFAULT_DECIMALS) }; - const minBaseAssetAmount = { d: Ethers.utils.parseUnits(minBaseAmount, DEFAULT_DECIMALS) }; - const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet); + const quoteAssetAmount = { + d: Ethers.utils.parseUnits(margin, DEFAULT_DECIMALS) + } + const leverage = { d: Ethers.utils.parseUnits(levrg, DEFAULT_DECIMALS) } + const minBaseAssetAmount = { + d: Ethers.utils.parseUnits(minBaseAmount, DEFAULT_DECIMALS) + } + const clearingHouse = new Ethers.Contract( + this.ClearingHouse, + ClearingHouseArtifact.abi, + wallet + ) const tx = await clearingHouse.openPosition( this.amm[pair], side, quoteAssetAmount, leverage, minBaseAssetAmount, - { gasLimit: this.gasLimit }, - ); - return tx; + { gasLimit: this.gasLimit } + ) + return tx } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error opening position'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error opening position') + return reason } } // close Position async closePosition(wallet, pair, minimalQuote) { try { - const minimalQuoteAsset = { d: Ethers.utils.parseUnits(minimalQuote, DEFAULT_DECIMALS) }; - const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet); - const tx = await clearingHouse.closePosition(this.amm[pair], minimalQuoteAsset, { gasLimit: this.gasLimit }); - return tx; + const minimalQuoteAsset = { + d: Ethers.utils.parseUnits(minimalQuote, DEFAULT_DECIMALS) + } + const clearingHouse = new Ethers.Contract( + this.ClearingHouse, + ClearingHouseArtifact.abi, + wallet + ) + const tx = await clearingHouse.closePosition( + this.amm[pair], + minimalQuoteAsset, + { gasLimit: this.gasLimit } + ) + return tx } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error closing position'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error closing position') + return reason } } // get active position async getPosition(wallet, pair) { try { - const positionValues = {}; - const clearingHouse = new Ethers.Contract(this.ClearingHouse, ClearingHouseArtifact.abi, wallet); - let premIndex = 0; - await Promise.allSettled([clearingHouse.getPosition(this.amm[pair], - wallet.address), - clearingHouse.getLatestCumulativePremiumFraction(this.amm[pair]), - clearingHouse.getPositionNotionalAndUnrealizedPnl(this.amm[pair], - wallet.address, - Ethers.BigNumber.from(PNL_OPTION_SPOT_PRICE))]) - .then((values) => { - positionValues.openNotional = Ethers.utils.formatUnits(values[0].value.openNotional.d, DEFAULT_DECIMALS); - positionValues.size = Ethers.utils.formatUnits(values[0].value.size.d, DEFAULT_DECIMALS); - positionValues.margin = Ethers.utils.formatUnits(values[0].value.margin.d, DEFAULT_DECIMALS); - positionValues.cumulativePremiumFraction = Ethers.utils.formatUnits(values[0].value.lastUpdatedCumulativePremiumFraction.d, DEFAULT_DECIMALS); - premIndex = Ethers.utils.formatUnits(values[1].value.d, DEFAULT_DECIMALS); - positionValues.pnl = Ethers.utils.formatUnits(values[2].value.unrealizedPnl.d, DEFAULT_DECIMALS); - positionValues.positionNotional = Ethers.utils.formatUnits(values[2].value.positionNotional.d, DEFAULT_DECIMALS); - }); + const positionValues = {} + const clearingHouse = new Ethers.Contract( + this.ClearingHouse, + ClearingHouseArtifact.abi, + wallet + ) + let premIndex = 0 + await Promise.allSettled([ + clearingHouse.getPosition(this.amm[pair], wallet.address), + clearingHouse.getLatestCumulativePremiumFraction(this.amm[pair]), + clearingHouse.getPositionNotionalAndUnrealizedPnl( + this.amm[pair], + wallet.address, + Ethers.BigNumber.from(PNL_OPTION_SPOT_PRICE) + ) + ]).then((values) => { + positionValues.openNotional = Ethers.utils.formatUnits( + values[0].value.openNotional.d, + DEFAULT_DECIMALS + ) + positionValues.size = Ethers.utils.formatUnits( + values[0].value.size.d, + DEFAULT_DECIMALS + ) + positionValues.margin = Ethers.utils.formatUnits( + values[0].value.margin.d, + DEFAULT_DECIMALS + ) + positionValues.cumulativePremiumFraction = Ethers.utils.formatUnits( + values[0].value.lastUpdatedCumulativePremiumFraction.d, + DEFAULT_DECIMALS + ) + premIndex = Ethers.utils.formatUnits( + values[1].value.d, + DEFAULT_DECIMALS + ) + positionValues.pnl = Ethers.utils.formatUnits( + values[2].value.unrealizedPnl.d, + DEFAULT_DECIMALS + ) + positionValues.positionNotional = Ethers.utils.formatUnits( + values[2].value.positionNotional.d, + DEFAULT_DECIMALS + ) + }) - positionValues.entryPrice = Math.abs(positionValues.openNotional / positionValues.size); - positionValues.fundingPayment = (premIndex - positionValues.cumulativePremiumFraction) * positionValues.size; // * -1 - return positionValues; + positionValues.entryPrice = Math.abs( + positionValues.openNotional / positionValues.size + ) + positionValues.fundingPayment = + (premIndex - positionValues.cumulativePremiumFraction) * + positionValues.size // * -1 + return positionValues } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error getting active position'; - return reason; + logger.error(err) + let reason + err.reason + ? (reason = err.reason) + : (reason = 'error getting active position') + return reason } } // get active margin async getActiveMargin(wallet) { try { - const clearingHouseViewer = new Ethers.Contract(this.ClearingHouseViewer, ClearingHouseViewerArtifact.abi, wallet); - const activeMargin = await clearingHouseViewer.getPersonalBalanceWithFundingPayment( - this.xUsdcAddr, - wallet.address, - ); - return activeMargin / 1e18.toString(); + const clearingHouseViewer = new Ethers.Contract( + this.ClearingHouseViewer, + ClearingHouseViewerArtifact.abi, + wallet + ) + const activeMargin = + await clearingHouseViewer.getPersonalBalanceWithFundingPayment( + this.xUsdcAddr, + wallet.address + ) + return activeMargin / (1e18).toString() } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error getting active position'; - return reason; + logger.error(err) + let reason + err.reason + ? (reason = err.reason) + : (reason = 'error getting active position') + return reason } } // get Price async getPrice(side, amount, pair) { try { - let price; - this.cacheExpirary[pair] = Date.now() + UPDATE_PERIOD; - this.pairAmountCache[pair] = amount; + let price + this.cacheExpirary[pair] = Date.now() + UPDATE_PERIOD + this.pairAmountCache[pair] = amount if (!this.priceCache.hasOwnProperty(pair)) { - const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider); + const amm = new Ethers.Contract( + this.amm[pair], + AmmArtifact.abi, + this.provider + ) if (side === 'buy') { - price = await amm.getInputPrice(0, { d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }); - price = amount / Ethers.utils.formatUnits(price.d); + price = await amm.getInputPrice(0, { + d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) + }) + price = amount / Ethers.utils.formatUnits(price.d) } else { - price = await amm.getOutputPrice(0, { d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) }); - price = Ethers.utils.formatUnits(price.d) / amount; + price = await amm.getOutputPrice(0, { + d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) + }) + price = Ethers.utils.formatUnits(price.d) / amount } } else if (side === 'buy') { - price = this.priceCache[pair][0]; - } else { price = this.priceCache[pair][1]; } - return price; + price = this.priceCache[pair][0] + } else { + price = this.priceCache[pair][1] + } + return price } catch (err) { - console.log(err); - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error getting Price'; - return reason; + console.log(err) + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error getting Price') + return reason } } // get getFundingRate async getFundingRate(pair) { try { - const funding = {}; - const amm = new Ethers.Contract(this.amm[pair], AmmArtifact.abi, this.provider); - await Promise.allSettled([amm.getUnderlyingTwapPrice(3600), + const funding = {} + const amm = new Ethers.Contract( + this.amm[pair], + AmmArtifact.abi, + this.provider + ) + await Promise.allSettled([ + amm.getUnderlyingTwapPrice(3600), amm.getTwapPrice(3600), - amm.nextFundingTime()]) - .then((values) => { - funding.indexPrice = parseFloat(Ethers.utils.formatUnits(values[0].value.d)); - funding.markPrice = parseFloat(Ethers.utils.formatUnits(values[1].value.d)); - funding.nextFundingTime = parseInt(values[2].value.toString()); - }); + amm.nextFundingTime() + ]).then((values) => { + funding.indexPrice = parseFloat( + Ethers.utils.formatUnits(values[0].value.d) + ) + funding.markPrice = parseFloat( + Ethers.utils.formatUnits(values[1].value.d) + ) + funding.nextFundingTime = parseInt(values[2].value.toString()) + }) - funding.rate = ((funding.markPrice - funding.indexPrice) / 24) / funding.indexPrice; - return funding; + funding.rate = + (funding.markPrice - funding.indexPrice) / 24 / funding.indexPrice + return funding } catch (err) { - console.log(err); - logger.error(err)(); - let reason; - err.reason ? reason = err.reason : reason = 'error getting fee'; - return reason; + console.log(err) + logger.error(err)() + let reason + err.reason ? (reason = err.reason) : (reason = 'error getting fee') + return reason } } } diff --git a/src/services/terra.js b/src/services/terra.js index 613f284..48d8485 100644 --- a/src/services/terra.js +++ b/src/services/terra.js @@ -1,12 +1,16 @@ import { - LCDClient, Coin, MsgSwap, MnemonicKey, isTxError, -} from '@terra-money/terra.js'; -import BigNumber from 'bignumber.js'; -import { logger } from './logger'; -import { getHummingbotMemo } from './utils'; - -const debug = require('debug')('router'); -require('dotenv').config(); + LCDClient, + Coin, + MsgSwap, + MnemonicKey, + isTxError +} from '@terra-money/terra.js' +import BigNumber from 'bignumber.js' +import { logger } from './logger' +import { getHummingbotMemo } from './utils' + +const debug = require('debug')('router') +require('dotenv').config() // constants const TERRA_TOKENS = { @@ -14,36 +18,36 @@ const TERRA_TOKENS = { uusd: { symbol: 'UST' }, ukrw: { symbol: 'KRT' }, usdr: { symbol: 'SDT' }, - umnt: { symbol: 'MNT' }, -}; -const DENOM_UNIT = BigNumber('1e+6'); -const TOBIN_TAX = 0.0025; // a Tobin Tax (set at 0.25%) for spot-converting Terra<>Terra swaps -const MIN_SPREAD = 0.02; // a minimum spread (set at 2%) for Terra<>Luna swaps -const GAS_PRICE = { uluna: 0.16 }; -const GAS_ADJUSTMENT = 1.4; + umnt: { symbol: 'MNT' } +} +const DENOM_UNIT = BigNumber('1e+6') +const TOBIN_TAX = 0.0025 // a Tobin Tax (set at 0.25%) for spot-converting Terra<>Terra swaps +const MIN_SPREAD = 0.02 // a minimum spread (set at 2%) for Terra<>Luna swaps +const GAS_PRICE = { uluna: 0.16 } +const GAS_ADJUSTMENT = 1.4 export default class Terra { constructor() { - this.lcdUrl = process.env.TERRA_LCD_URL; - this.network = process.env.TERRA_CHAIN; - this.tokens = TERRA_TOKENS; - this.denomUnitMultiplier = DENOM_UNIT; - this.tobinTax = TOBIN_TAX; - this.minSpread = MIN_SPREAD; - this.memo = getHummingbotMemo(); + this.lcdUrl = process.env.TERRA_LCD_URL + this.network = process.env.TERRA_CHAIN + this.tokens = TERRA_TOKENS + this.denomUnitMultiplier = DENOM_UNIT + this.tobinTax = TOBIN_TAX + this.minSpread = MIN_SPREAD + this.memo = getHummingbotMemo() try { - this.lcd = this.connect(); + this.lcd = this.connect() this.lcd.market.parameters().catch(() => { - throw new Error('Connection error'); - }); + throw new Error('Connection error') + }) // set gas & fee - this.lcd.config.gasAdjustment = GAS_ADJUSTMENT; - this.lcd.config.gasPrices = GAS_PRICE; + this.lcd.config.gasAdjustment = GAS_ADJUSTMENT + this.lcd.config.gasPrices = GAS_PRICE } catch (err) { - logger.error(err); - throw Error(`Connection failed: ${this.network}`); + logger.error(err) + throw Error(`Connection failed: ${this.network}`) } } @@ -52,268 +56,307 @@ export default class Terra { try { const lcd = new LCDClient({ URL: this.lcdUrl, - chainID: this.network, - }); - lcd.config.gasAdjustment = GAS_ADJUSTMENT; - lcd.config.gasPrices = GAS_PRICE; - return lcd; + chainID: this.network + }) + lcd.config.gasAdjustment = GAS_ADJUSTMENT + lcd.config.gasPrices = GAS_PRICE + return lcd } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error Terra LCD connect'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error Terra LCD connect') + return reason } } // get Token Denom getTokenDenom(symbol) { try { - let denom; + let denom Object.keys(TERRA_TOKENS).forEach((item) => { if (TERRA_TOKENS[item].symbol === symbol) { - denom = item; + denom = item } - }); - return denom; + }) + return denom } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error Terra Denom lookup'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error Terra Denom lookup') + return reason } } // get Token Symbol getTokenSymbol(denom) { try { - const { symbol } = TERRA_TOKENS[denom]; - return symbol; + const { symbol } = TERRA_TOKENS[denom] + return symbol } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error Terra Denom lookup'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error Terra Denom lookup') + return reason } } getTxAttributes(attributes) { - const attrib = {}; + const attrib = {} attributes.forEach((item) => { - attrib[item.key] = item.value; - }); - return attrib; + attrib[item.key] = item.value + }) + return attrib } async getEstimateFee(tx) { try { - const fee = await this.lcd.tx.estimateFee(tx); - return fee; + const fee = await this.lcd.tx.estimateFee(tx) + return fee } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error Terra estimate fee lookup'; - return reason; + logger.error(err) + let reason + err.reason + ? (reason = err.reason) + : (reason = 'error Terra estimate fee lookup') + return reason } } async getExchangeRate(denom) { try { - const exchangeRates = await this.lcd.oracle.exchangeRates(); - return exchangeRates.get(denom); + const exchangeRates = await this.lcd.oracle.exchangeRates() + return exchangeRates.get(denom) } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup'; - return reason; + logger.error(err) + let reason + err.reason + ? (reason = err.reason) + : (reason = 'error Terra exchange rate lookup') + return reason } } async getTxFee() { try { - const lunaFee = GAS_PRICE.uluna * GAS_ADJUSTMENT; - const feeList = { uluna: lunaFee }; + const lunaFee = GAS_PRICE.uluna * GAS_ADJUSTMENT + const feeList = { uluna: lunaFee } await this.lcd.oracle.exchangeRates().then((rates) => { Object.keys(rates._coins).forEach((key) => { - feeList[key] = rates._coins[key].amount * lunaFee; - }); - }); - debug('lunaFee', lunaFee, feeList); + feeList[key] = rates._coins[key].amount * lunaFee + }) + }) + debug('lunaFee', lunaFee, feeList) - return feeList; + return feeList } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error Terra exchange rate lookup'; - return reason; + logger.error(err) + let reason + err.reason + ? (reason = err.reason) + : (reason = 'error Terra exchange rate lookup') + return reason } } // get Terra Swap Rate async getSwapRate(baseToken, quoteToken, amount, tradeType) { try { - let exchangeRate; let offerCoin; let offerDenom; let swapDenom; let cost; let costAmount; let - offer; - const swaps = {}; + let exchangeRate + let offerCoin + let offerDenom + let swapDenom + let cost + let costAmount + let offer + const swaps = {} if (tradeType.toLowerCase() === 'sell') { // sell base - offerDenom = this.getTokenDenom(baseToken); - swapDenom = this.getTokenDenom(quoteToken); - - offerCoin = new Coin(offerDenom, amount * DENOM_UNIT); - await this.lcd.market.swapRate(offerCoin, swapDenom).then((swapCoin) => { - offer = { amount }; - exchangeRate = { - amount: (swapCoin.amount / DENOM_UNIT) / amount, - token: quoteToken, - }; - costAmount = amount * exchangeRate.amount; - cost = { - amount: costAmount, - token: quoteToken, - }; - }); + offerDenom = this.getTokenDenom(baseToken) + swapDenom = this.getTokenDenom(quoteToken) + + offerCoin = new Coin(offerDenom, amount * DENOM_UNIT) + await this.lcd.market + .swapRate(offerCoin, swapDenom) + .then((swapCoin) => { + offer = { amount } + exchangeRate = { + amount: swapCoin.amount / DENOM_UNIT / amount, + token: quoteToken + } + costAmount = amount * exchangeRate.amount + cost = { + amount: costAmount, + token: quoteToken + } + }) } else { // buy base - offerDenom = this.getTokenDenom(quoteToken); - swapDenom = this.getTokenDenom(baseToken); - - offerCoin = new Coin(offerDenom, 1 * DENOM_UNIT); - await this.lcd.market.swapRate(offerCoin, swapDenom).then((swapCoin) => { - exchangeRate = { - amount: (amount / parseInt(swapCoin.amount) * DENOM_UNIT) / amount, // adjusted amount - token: quoteToken, - }; - costAmount = amount * exchangeRate.amount; - cost = { - amount: costAmount, - token: quoteToken, - }; - offer = { amount: cost.amount }; - }); + offerDenom = this.getTokenDenom(quoteToken) + swapDenom = this.getTokenDenom(baseToken) + + offerCoin = new Coin(offerDenom, 1 * DENOM_UNIT) + await this.lcd.market + .swapRate(offerCoin, swapDenom) + .then((swapCoin) => { + exchangeRate = { + amount: + ((amount / parseInt(swapCoin.amount)) * DENOM_UNIT) / amount, // adjusted amount + token: quoteToken + } + costAmount = amount * exchangeRate.amount + cost = { + amount: costAmount, + token: quoteToken + } + offer = { amount: cost.amount } + }) } - let txFee; + let txFee await this.getTxFee().then((fee) => { // fee in quote - txFee = { amount: parseFloat(fee[this.getTokenDenom(quoteToken)]), token: quoteToken }; - }); - - swaps.offer = offer; - swaps.price = exchangeRate; - swaps.cost = cost; - swaps.txFee = txFee; - debug('swaps', swaps); - return swaps; + txFee = { + amount: parseFloat(fee[this.getTokenDenom(quoteToken)]), + token: quoteToken + } + }) + + swaps.offer = offer + swaps.price = exchangeRate + swaps.cost = cost + swaps.txFee = txFee + debug('swaps', swaps) + return swaps } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = 'error swap rate lookup'; - return reason; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = 'error swap rate lookup') + return reason } } // Swap tokens - async swapTokens(baseToken, quoteToken, amount, tradeType, gasPrice, gasAdjustment, secret) { - let swapResult; + async swapTokens( + baseToken, + quoteToken, + amount, + tradeType, + gasPrice, + gasAdjustment, + secret + ) { + let swapResult try { // connect to lcd - const lcd = this.connect(); + const lcd = this.connect() const mk = new MnemonicKey({ - mnemonic: secret, - }); - let wallet; + mnemonic: secret + }) + let wallet try { - wallet = lcd.wallet(mk); + wallet = lcd.wallet(mk) } catch (err) { - logger.error(err); - throw Error('Wallet access error'); + logger.error(err) + throw Error('Wallet access error') } - const address = wallet.key.accAddress; + const address = wallet.key.accAddress // get the current swap rate - const baseDenom = this.getTokenDenom(baseToken); - const quoteDenom = this.getTokenDenom(quoteToken); + const baseDenom = this.getTokenDenom(baseToken) + const quoteDenom = this.getTokenDenom(quoteToken) - let offerDenom; let - swapDenom; - let swaps; let - txAttributes; - const tokenSwap = {}; + let offerDenom + let swapDenom + let swaps + let txAttributes + const tokenSwap = {} if (tradeType.toLowerCase() === 'sell') { - offerDenom = baseDenom; - swapDenom = quoteDenom; + offerDenom = baseDenom + swapDenom = quoteDenom } else { - offerDenom = quoteDenom; - swapDenom = baseDenom; + offerDenom = quoteDenom + swapDenom = baseDenom } - await this.getSwapRate(baseToken, quoteToken, amount, tradeType, secret).then((rate) => { - swaps = rate; - }); + await this.getSwapRate( + baseToken, + quoteToken, + amount, + tradeType, + secret + ).then((rate) => { + swaps = rate + }) - const offerAmount = parseInt((swaps.offer.amount) * DENOM_UNIT); - const offerCoin = new Coin(offerDenom, offerAmount); + const offerAmount = parseInt(swaps.offer.amount * DENOM_UNIT) + const offerCoin = new Coin(offerDenom, offerAmount) // Create and Sign Transaction - const msgSwap = new MsgSwap(address, offerCoin, swapDenom); + const msgSwap = new MsgSwap(address, offerCoin, swapDenom) - let txOptions; - if (gasPrice !== null && gasPrice !== null) { // ignore gasAdjustment when gasPrice is not set + let txOptions + if (gasPrice !== null && gasPrice !== null) { + // ignore gasAdjustment when gasPrice is not set txOptions = { msgs: [msgSwap], gasPrices: { uluna: parseFloat(gasPrice) }, gasAdjustment, - memo: this.memo, - }; + memo: this.memo + } } else { txOptions = { msgs: [msgSwap], - memo: this.memo, - }; + memo: this.memo + } } - await wallet.createAndSignTx(txOptions).then((tx) => lcd.tx.broadcast(tx)).then((txResult) => { - swapResult = txResult; - - const swapSuccess = !isTxError(txResult); - if (swapSuccess) { - tokenSwap.txSuccess = swapSuccess; - } else { - tokenSwap.txSuccess = !swapSuccess; - throw new Error(`encountered an error while running the transaction: ${txResult.code} ${txResult.codespace}`); - } - const txHash = txResult.txhash; - const { events } = JSON.parse(txResult.raw_log)[0]; - const swap = events.find((obj) => obj.type === 'swap'); - txAttributes = this.getTxAttributes(swap.attributes); - const offer = Coin.fromString(txAttributes.offer); - const ask = Coin.fromString(txAttributes.swap_coin); - const fee = Coin.fromString(txAttributes.swap_fee); - - tokenSwap.expectedIn = { - amount: parseFloat(offer.amount) / DENOM_UNIT, - token: TERRA_TOKENS[offer.denom].symbol, - }; - tokenSwap.expectedOut = { - amount: parseFloat(ask.amount) / DENOM_UNIT, - token: TERRA_TOKENS[ask.denom].symbol, - }; - tokenSwap.fee = { - amount: parseFloat(fee.amount) / DENOM_UNIT, - token: TERRA_TOKENS[fee.denom].symbol, - }; - tokenSwap.txHash = txHash; - }); - return tokenSwap; + await wallet + .createAndSignTx(txOptions) + .then((tx) => lcd.tx.broadcast(tx)) + .then((txResult) => { + swapResult = txResult + + const swapSuccess = !isTxError(txResult) + if (swapSuccess) { + tokenSwap.txSuccess = swapSuccess + } else { + tokenSwap.txSuccess = !swapSuccess + throw new Error( + `encountered an error while running the transaction: ${txResult.code} ${txResult.codespace}` + ) + } + const txHash = txResult.txhash + const { events } = JSON.parse(txResult.raw_log)[0] + const swap = events.find((obj) => obj.type === 'swap') + txAttributes = this.getTxAttributes(swap.attributes) + const offer = Coin.fromString(txAttributes.offer) + const ask = Coin.fromString(txAttributes.swap_coin) + const fee = Coin.fromString(txAttributes.swap_fee) + + tokenSwap.expectedIn = { + amount: parseFloat(offer.amount) / DENOM_UNIT, + token: TERRA_TOKENS[offer.denom].symbol + } + tokenSwap.expectedOut = { + amount: parseFloat(ask.amount) / DENOM_UNIT, + token: TERRA_TOKENS[ask.denom].symbol + } + tokenSwap.fee = { + amount: parseFloat(fee.amount) / DENOM_UNIT, + token: TERRA_TOKENS[fee.denom].symbol + } + tokenSwap.txHash = txHash + }) + return tokenSwap } catch (err) { - logger.error(err); - let reason; - err.reason ? reason = err.reason : reason = swapResult; - return { txSuccess: false, message: reason }; + logger.error(err) + let reason + err.reason ? (reason = err.reason) : (reason = swapResult) + return { txSuccess: false, message: reason } } } } diff --git a/src/services/uniswap.js b/src/services/uniswap.js index 9298b54..076dbb7 100644 --- a/src/services/uniswap.js +++ b/src/services/uniswap.js @@ -1,75 +1,88 @@ -import { logger } from './logger'; +import { logger } from './logger' -const debug = require('debug')('router'); -const math = require('mathjs'); -const uni = require('@uniswap/sdk'); -const ethers = require('ethers'); -const proxyArtifact = require('../static/uniswap_v2_router_abi.json'); -const routeTokens = require('../static/uniswap_route_tokens.json'); +const debug = require('debug')('router') +const math = require('mathjs') +const uni = require('@uniswap/sdk') +const ethers = require('ethers') +const proxyArtifact = require('../static/uniswap_v2_router_abi.json') +const routeTokens = require('../static/uniswap_route_tokens.json') // constants -const ROUTER = process.env.UNISWAP_ROUTER; -const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 150688; -const TTL = process.env.UNISWAP_TTL || 300; -const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request +const ROUTER = process.env.UNISWAP_ROUTER +const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 150688 +const TTL = process.env.UNISWAP_TTL || 300 +const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000 // stop updating pair after 5 minutes from last request export default class Uniswap { constructor(network = 'mainnet') { - this.providerUrl = process.env.ETHEREUM_RPC_URL; - this.network = process.env.ETHEREUM_CHAIN; - this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl); - this.router = ROUTER; - this.slippage = math.fraction(process.env.UNISWAP_ALLOWED_SLIPPAGE); - this.allowedSlippage = new uni.Percent(this.slippage.n, (this.slippage.d * 100)); - this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME; - this.gasLimit = GAS_LIMIT; - this.expireTokenPairUpdate = UPDATE_PERIOD; - this.zeroReserveCheckInterval = process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL; - this.zeroReservePairs = {}; // No reserve pairs - this.tokenList = {}; - this.pairs = []; - this.tokenSwapList = {}; - this.cachedRoutes = {}; + this.providerUrl = process.env.ETHEREUM_RPC_URL + this.network = process.env.ETHEREUM_CHAIN + this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) + this.router = ROUTER + this.slippage = math.fraction(process.env.UNISWAP_ALLOWED_SLIPPAGE) + this.allowedSlippage = new uni.Percent( + this.slippage.n, + this.slippage.d * 100 + ) + this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME + this.gasLimit = GAS_LIMIT + this.expireTokenPairUpdate = UPDATE_PERIOD + this.zeroReserveCheckInterval = + process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL + this.zeroReservePairs = {} // No reserve pairs + this.tokenList = {} + this.pairs = [] + this.tokenSwapList = {} + this.cachedRoutes = {} switch (network) { case 'mainnet': - this.chainID = uni.ChainId.MAINNET; - break; + this.chainID = uni.ChainId.MAINNET + break case 'kovan': - this.chainID = uni.ChainId.KOVAN; - break; + this.chainID = uni.ChainId.KOVAN + break default: - const err = `Invalid network ${network}`; - logger.error(err); - throw Error(err); + const err = `Invalid network ${network}` + logger.error(err) + throw Error(err) } } async fetch_route(tIn, tOut) { - let route; - let pair; + let route + let pair try { - pair = await uni.Fetcher.fetchPairData(tIn, tOut); - route = new uni.Route([pair], tIn, tOut); + pair = await uni.Fetcher.fetchPairData(tIn, tOut) + route = new uni.Route([pair], tIn, tOut) } catch (err) { - logger.error(err); + logger.error(err) } - return route; + return route } generate_tokens() { for (const token of routeTokens[this.network]) { - this.tokenList[token.address] = new uni.Token(this.chainID, token.address, token.decimals, token.symbol, token.name); + this.tokenList[token.address] = new uni.Token( + this.chainID, + token.address, + token.decimals, + token.symbol, + token.name + ) } } async extend_update_pairs(tokens = []) { for (const token of tokens) { if (!this.tokenList.hasOwnProperty(token)) { - this.tokenList[token] = await uni.Fetcher.fetchTokenData(this.chainID, token); + this.tokenList[token] = await uni.Fetcher.fetchTokenData( + this.chainID, + token + ) } - this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate; + this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate } } @@ -78,7 +91,7 @@ export default class Uniswap { if (Object.keys(this.zeroReservePairs).length > 0) { for (const pair in this.zeroReservePairs) { if (this.zeroReservePairs[pair] <= Date.now()) { - delete this.zeroReservePairs[pair]; + delete this.zeroReservePairs[pair] // delete this.tokenList[token]; } } @@ -88,129 +101,158 @@ export default class Uniswap { if (Object.keys(this.tokenSwapList).length > 0) { for (const token in this.tokenSwapList) { if (this.tokenSwapList[token] <= Date.now()) { - delete this.tokenSwapList[token]; + delete this.tokenSwapList[token] // delete this.tokenList[token]; } } - const tokens = Object.keys(this.tokenList); - let firstToken; let secondToken; let - position; - const length = tokens.length; - const pairs = []; - const pairAddressRequests = []; - const pairAddressResponses = []; + const tokens = Object.keys(this.tokenList) + let firstToken + let secondToken + let position + const length = tokens.length + const pairs = [] + const pairAddressRequests = [] + const pairAddressResponses = [] for (firstToken = 0; firstToken < length; firstToken++) { - for (secondToken = firstToken + 1; secondToken < length; secondToken++) { + for ( + secondToken = firstToken + 1; + secondToken < length; + secondToken++ + ) { try { - const pairString = `${this.tokenList[tokens[firstToken]].address}-${this.tokenList[tokens[secondToken]].address}`; + const pairString = `${this.tokenList[tokens[firstToken]].address}-${ + this.tokenList[tokens[secondToken]].address + }` if (!this.zeroReservePairs.hasOwnProperty(pairString)) { - pairs.push(pairString); - pairAddressRequests.push(uni.Fetcher.fetchPairData(this.tokenList[tokens[firstToken]], this.tokenList[tokens[secondToken]])); + pairs.push(pairString) + pairAddressRequests.push( + uni.Fetcher.fetchPairData( + this.tokenList[tokens[firstToken]], + this.tokenList[tokens[secondToken]] + ) + ) } } catch (err) { - logger.error(err); + logger.error(err) } } } await Promise.allSettled(pairAddressRequests).then((values) => { for (position = 0; position < pairAddressRequests.length; position++) { - if (values[position].status === 'fulfilled') { pairAddressResponses.push(values[position].value); } else { this.zeroReservePairs[pairs[position]] = Date.now() + this.zeroReserveCheckInterval; } + if (values[position].status === 'fulfilled') { + pairAddressResponses.push(values[position].value) + } else { + this.zeroReservePairs[pairs[position]] = + Date.now() + this.zeroReserveCheckInterval + } } - }); - this.pairs = pairAddressResponses; + }) + this.pairs = pairAddressResponses } - setTimeout(this.update_pairs.bind(this), 1000); + setTimeout(this.update_pairs.bind(this), 1000) } async priceSwapIn(tokenIn, tokenOut, tokenInAmount) { - await this.extend_update_pairs([tokenIn, tokenOut]); - const tIn = this.tokenList[tokenIn]; - const tOut = this.tokenList[tokenOut]; - const tokenAmountIn = new uni.TokenAmount(tIn, ethers.utils.parseUnits(tokenInAmount, tIn.decimals)); + await this.extend_update_pairs([tokenIn, tokenOut]) + const tIn = this.tokenList[tokenIn] + const tOut = this.tokenList[tokenOut] + const tokenAmountIn = new uni.TokenAmount( + tIn, + ethers.utils.parseUnits(tokenInAmount, tIn.decimals) + ) if (this.pairs.length === 0) { - const route = await this.fetch_route(tIn, tOut); - const trade = uni.Trade.exactIn(route, tokenAmountIn); + const route = await this.fetch_route(tIn, tOut) + const trade = uni.Trade.exactIn(route, tokenAmountIn) if (trade !== undefined) { - const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; - return { trade, expectedAmount }; + const expectedAmount = trade.minimumAmountOut(this.allowedSlippage) + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade + return { trade, expectedAmount } } - return "Can't find route to swap, kindly update "; + return "Can't find route to swap, kindly update " + } + let trade = uni.Trade.bestTradeExactIn( + this.pairs, + tokenAmountIn, + this.tokenList[tokenOut], + { maxHops: 5 } + )[0] + if (trade === undefined) { + trade = this.cachedRoutes[tIn.symbol + tOut.Symbol] + } else { + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade } - let trade = uni.Trade.bestTradeExactIn(this.pairs, tokenAmountIn, this.tokenList[tokenOut], { maxHops: 5 })[0]; - if (trade === undefined) { trade = this.cachedRoutes[tIn.symbol + tOut.Symbol]; } else { this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; } - const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); - return { trade, expectedAmount }; + const expectedAmount = trade.minimumAmountOut(this.allowedSlippage) + return { trade, expectedAmount } } async priceSwapOut(tokenIn, tokenOut, tokenOutAmount) { - await this.extend_update_pairs([tokenIn, tokenOut]); - const tOut = this.tokenList[tokenOut]; - const tIn = this.tokenList[tokenIn]; - const tokenAmountOut = new uni.TokenAmount(tOut, ethers.utils.parseUnits(tokenOutAmount, tOut.decimals)); + await this.extend_update_pairs([tokenIn, tokenOut]) + const tOut = this.tokenList[tokenOut] + const tIn = this.tokenList[tokenIn] + const tokenAmountOut = new uni.TokenAmount( + tOut, + ethers.utils.parseUnits(tokenOutAmount, tOut.decimals) + ) if (this.pairs.length === 0) { - const route = await this.fetch_route(tIn, tOut); - const trade = uni.Trade.exactOut(route, tokenAmountOut); + const route = await this.fetch_route(tIn, tOut) + const trade = uni.Trade.exactOut(route, tokenAmountOut) if (trade !== undefined) { - const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; - return { trade, expectedAmount }; + const expectedAmount = trade.maximumAmountIn(this.allowedSlippage) + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade + return { trade, expectedAmount } } - return; + return } - let trade = uni.Trade.bestTradeExactOut(this.pairs, this.tokenList[tokenIn], tokenAmountOut, { maxHops: 5 })[0]; - if (trade === undefined) { trade = this.cachedRoutes[tIn.symbol + tOut.Symbol]; } else { this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; } - const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); - return { trade, expectedAmount }; + let trade = uni.Trade.bestTradeExactOut( + this.pairs, + this.tokenList[tokenIn], + tokenAmountOut, + { maxHops: 5 } + )[0] + if (trade === undefined) { + trade = this.cachedRoutes[tIn.symbol + tOut.Symbol] + } else { + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade + } + const expectedAmount = trade.maximumAmountIn(this.allowedSlippage) + return { trade, expectedAmount } } async swapExactIn(wallet, trade, tokenAddress, gasPrice) { - const result = uni.Router.swapCallParameters( - trade, - { - ttl: TTL, - recipient: wallet.address, - allowedSlippage: this.allowedSlippage, - }, - ); - - const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet); - const tx = await contract[result.methodName]( - ...result.args, - { - gasPrice: gasPrice * 1e9, - gasLimit: GAS_LIMIT, - value: result.value, - }, - ); - - debug(`Tx Hash: ${tx.hash}`); - return tx; + const result = uni.Router.swapCallParameters(trade, { + ttl: TTL, + recipient: wallet.address, + allowedSlippage: this.allowedSlippage + }) + + const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) + const tx = await contract[result.methodName](...result.args, { + gasPrice: gasPrice * 1e9, + gasLimit: GAS_LIMIT, + value: result.value + }) + + debug(`Tx Hash: ${tx.hash}`) + return tx } async swapExactOut(wallet, trade, tokenAddress, gasPrice) { - const result = uni.Router.swapCallParameters( - trade, - { - ttl: TTL, - recipient: wallet.address, - allowedSlippage: this.allowedSlippage, - }, - ); - - const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet); - const tx = await contract[result.methodName]( - ...result.args, - { - gasPrice: gasPrice * 1e9, - gasLimit: GAS_LIMIT, - value: result.value, - }, - ); - - debug(`Tx Hash: ${tx.hash}`); - return tx; + const result = uni.Router.swapCallParameters(trade, { + ttl: TTL, + recipient: wallet.address, + allowedSlippage: this.allowedSlippage + }) + + const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) + const tx = await contract[result.methodName](...result.args, { + gasPrice: gasPrice * 1e9, + gasLimit: GAS_LIMIT, + value: result.value + }) + + debug(`Tx Hash: ${tx.hash}`) + return tx } } diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js index 0469f7f..fecf868 100644 --- a/src/services/uniswap_v3.js +++ b/src/services/uniswap_v3.js @@ -1,156 +1,211 @@ -import { logger } from './logger'; +import { logger } from './logger' import { - encodePriceSqrt, getTickFromPrice, -} from '../static/uniswap-v3/helper_functions'; + encodePriceSqrt, + getTickFromPrice +} from '../static/uniswap-v3/helper_functions' -const debug = require('debug')('router'); -const math = require('mathjs'); -const uni = require('@uniswap/sdk'); -const ethers = require('ethers'); -const coreArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json'); -const nftArtifact = require('@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'); -const routerArtifact = require('@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json'); -const poolArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json'); +const debug = require('debug')('router') +const math = require('mathjs') +const uni = require('@uniswap/sdk') +const ethers = require('ethers') +const coreArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json') +const nftArtifact = require('@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json') +const routerArtifact = require('@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json') +const poolArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json') // const routeTokens = require('../static/uniswap_route_tokens.json') -const abiDecoder = require('abi-decoder'); +const abiDecoder = require('abi-decoder') // constants -const FeeAmount = { LOW: 500, MEDIUM: 3000, HIGH: 10000 }; -const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 5506880; -const TTL = process.env.UNISWAP_TTL || 300; -const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request -const MaxUint128 = ethers.BigNumber.from(2).pow(128).sub(1); +const FeeAmount = { LOW: 500, MEDIUM: 3000, HIGH: 10000 } +const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 5506880 +const TTL = process.env.UNISWAP_TTL || 300 +const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000 // stop updating pair after 5 minutes from last request +const MaxUint128 = ethers.BigNumber.from(2).pow(128).sub(1) -abiDecoder.addABI(nftArtifact.abi); -abiDecoder.addABI(routerArtifact.abi); +abiDecoder.addABI(nftArtifact.abi) +abiDecoder.addABI(routerArtifact.abi) export default class UniswapV3 { constructor(network = 'mainnet') { - this.providerUrl = process.env.ETHEREUM_RPC_URL; - this.network = process.env.ETHEREUM_CHAIN; - this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl); - this.router = process.env.UNISWAP_V3_ROUTER; - this.nftManager = process.env.UNISWAP_V3_NFT_MANAGER; - this.core = process.env.UNISWAP_V3_CORE; - this.slippage = process.env.UNISWAP_ALLOWED_SLIPPAGE; - this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME; - this.gasLimit = GAS_LIMIT; - this.expireTokenPairUpdate = UPDATE_PERIOD; - this.zeroReserveCheckInterval = process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL; - this.zeroReservePairs = {}; // No reserve pairs - this.tokenList = {}; - this.pairs = []; - this.tokenSwapList = {}; - this.cachedRoutes = {}; - this.abiDecoder = abiDecoder; + this.providerUrl = process.env.ETHEREUM_RPC_URL + this.network = process.env.ETHEREUM_CHAIN + this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) + this.router = process.env.UNISWAP_V3_ROUTER + this.nftManager = process.env.UNISWAP_V3_NFT_MANAGER + this.core = process.env.UNISWAP_V3_CORE + this.slippage = process.env.UNISWAP_ALLOWED_SLIPPAGE + this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME + this.gasLimit = GAS_LIMIT + this.expireTokenPairUpdate = UPDATE_PERIOD + this.zeroReserveCheckInterval = + process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL + this.zeroReservePairs = {} // No reserve pairs + this.tokenList = {} + this.pairs = [] + this.tokenSwapList = {} + this.cachedRoutes = {} + this.abiDecoder = abiDecoder switch (network) { case 'mainnet': - this.chainID = uni.ChainId.MAINNET; - break; + this.chainID = uni.ChainId.MAINNET + break case 'kovan': - this.chainID = uni.ChainId.KOVAN; - break; + this.chainID = uni.ChainId.KOVAN + break default: - const err = `Invalid network ${network}`; - logger.error(err); + const err = `Invalid network ${network}` + logger.error(err) } } get_contract(contract, wallet) { - if (contract === 'core') { return new ethers.Contract(this.core, coreArtifact.abi, wallet); } - if (contract === 'router') { return new ethers.Contract(this.router, routerArtifact.abi, wallet); } - return new ethers.Contract(this.nftManager, nftArtifact.abi, wallet); + if (contract === 'core') { + return new ethers.Contract(this.core, coreArtifact.abi, wallet) + } + if (contract === 'router') { + return new ethers.Contract(this.router, routerArtifact.abi, wallet) + } + return new ethers.Contract(this.nftManager, nftArtifact.abi, wallet) } async currentPrice(wallet, tokenIn, tokenOut) { - let pool; let - poolContract; - const poolPrices = []; - const poolLiquidity = []; - const keys = ['LOW', 'MEDIUM', 'HIGH']; - const coreContract = this.get_contract('core', wallet); + let pool + let poolContract + const poolPrices = [] + const poolLiquidity = [] + const keys = ['LOW', 'MEDIUM', 'HIGH'] + const coreContract = this.get_contract('core', wallet) - const poolAddressRequests = [coreContract.getPool(tokenIn, tokenOut, FeeAmount.LOW), + const poolAddressRequests = [ + coreContract.getPool(tokenIn, tokenOut, FeeAmount.LOW), coreContract.getPool(tokenIn, tokenOut, FeeAmount.MEDIUM), - coreContract.getPool(tokenIn, tokenOut, FeeAmount.HIGH)]; + coreContract.getPool(tokenIn, tokenOut, FeeAmount.HIGH) + ] await Promise.allSettled(poolAddressRequests).then((values) => { for (pool = 0; pool < 3; pool++) { - if (values[pool].value === ethers.constants.AddressZero) { poolPrices[pool] = 0; } else { - poolContract = new ethers.Contract(values[pool].value, poolArtifact.abi, wallet); - poolPrices[pool] = poolContract.observe([1, 0]); + if (values[pool].value === ethers.constants.AddressZero) { + poolPrices[pool] = 0 + } else { + poolContract = new ethers.Contract( + values[pool].value, + poolArtifact.abi, + wallet + ) + poolPrices[pool] = poolContract.observe([1, 0]) } } - }); + }) await Promise.allSettled(poolPrices).then((values) => { for (pool = 0; pool < 3; pool++) { - poolPrices[pool] = poolLiquidity[pool] = 0; + poolPrices[pool] = poolLiquidity[pool] = 0 if (values[pool].value) { for (const tick of values[pool].value.tickCumulatives) { - poolPrices[pool] = tick.toNumber() - poolPrices[pool]; + poolPrices[pool] = tick.toNumber() - poolPrices[pool] } - poolPrices[pool] = math.pow(1.0001, poolPrices[pool]); + poolPrices[pool] = math.pow(1.0001, poolPrices[pool]) } } - }); - return Object.assign(...keys.map((k, i) => ({ [k]: poolPrices[i] }))); + }) + return Object.assign(...keys.map((k, i) => ({ [k]: poolPrices[i] }))) } - async swapExactIn(wallet, baseTokenContractInfo, quoteTokenContractInfo, baseAmount, limitPrice, tier, _gasPrice) { + async swapExactIn( + wallet, + baseTokenContractInfo, + quoteTokenContractInfo, + baseAmount, + limitPrice, + tier, + _gasPrice + ) { // sell, In => base, Out => quote - const minPercentOut = (1 - (this.slippage / 100)); - const amountOutMinimum = Math.floor(baseAmount * limitPrice * minPercentOut * quoteTokenContractInfo.decimals) / quoteTokenContractInfo.decimals; + const minPercentOut = 1 - this.slippage / 100 + const amountOutMinimum = + Math.floor( + baseAmount * + limitPrice * + minPercentOut * + quoteTokenContractInfo.decimals + ) / quoteTokenContractInfo.decimals // const priceFraction = math.fraction(limitPrice) - const contract = this.get_contract('router', wallet); - const tx = await contract.exactInputSingle({ - tokenIn: baseTokenContractInfo.address, - tokenOut: quoteTokenContractInfo.address, - fee: FeeAmount[tier], - recipient: wallet.signer.address, - deadline: Date.now() + TTL, - amountIn: ethers.utils.parseUnits(baseAmount, baseTokenContractInfo.decimals), - amountOutMinimum: ethers.utils.parseUnits(amountOutMinimum.toString(), quoteTokenContractInfo.decimals), - sqrtPriceLimitX96: 0, - }, - { - gasLimit: GAS_LIMIT, - }); + const contract = this.get_contract('router', wallet) + const tx = await contract.exactInputSingle( + { + tokenIn: baseTokenContractInfo.address, + tokenOut: quoteTokenContractInfo.address, + fee: FeeAmount[tier], + recipient: wallet.signer.address, + deadline: Date.now() + TTL, + amountIn: ethers.utils.parseUnits( + baseAmount, + baseTokenContractInfo.decimals + ), + amountOutMinimum: ethers.utils.parseUnits( + amountOutMinimum.toString(), + quoteTokenContractInfo.decimals + ), + sqrtPriceLimitX96: 0 + }, + { + gasLimit: GAS_LIMIT + } + ) - debug(`Tx Hash: ${tx.hash}`); - tx.expectedAmount = amountOutMinimum; - return tx; + debug(`Tx Hash: ${tx.hash}`) + tx.expectedAmount = amountOutMinimum + return tx } - async swapExactOut(wallet, baseTokenContractInfo, quoteTokenContractInfo, baseAmount, limitPrice, tier, _gasPrice) { + async swapExactOut( + wallet, + baseTokenContractInfo, + quoteTokenContractInfo, + baseAmount, + limitPrice, + tier, + _gasPrice + ) { // buy, In => quote, Out => base - const maxPercentIn = (1 + (this.slippage / 100)); - const amountInMaximum = Math.ceil(baseAmount * limitPrice * maxPercentIn * quoteTokenContractInfo.decimals) / quoteTokenContractInfo.decimals; + const maxPercentIn = 1 + this.slippage / 100 + const amountInMaximum = + Math.ceil( + baseAmount * limitPrice * maxPercentIn * quoteTokenContractInfo.decimals + ) / quoteTokenContractInfo.decimals // const priceFraction = math.fraction(limitPrice) - const contract = this.get_contract('router', wallet); - const tx = await contract.exactOutputSingle({ - tokenIn: quoteTokenContractInfo.address, - tokenOut: baseTokenContractInfo.address, - fee: FeeAmount[tier], - recipient: wallet.signer.address, - deadline: Date.now() + TTL, - amountOut: ethers.utils.parseUnits(baseAmount, baseTokenContractInfo.decimals), - amountInMaximum: ethers.utils.parseUnits(amountInMaximum.toString(), quoteTokenContractInfo.decimals), - sqrtPriceLimitX96: 0, - }, - { - gasLimit: GAS_LIMIT, - }); + const contract = this.get_contract('router', wallet) + const tx = await contract.exactOutputSingle( + { + tokenIn: quoteTokenContractInfo.address, + tokenOut: baseTokenContractInfo.address, + fee: FeeAmount[tier], + recipient: wallet.signer.address, + deadline: Date.now() + TTL, + amountOut: ethers.utils.parseUnits( + baseAmount, + baseTokenContractInfo.decimals + ), + amountInMaximum: ethers.utils.parseUnits( + amountInMaximum.toString(), + quoteTokenContractInfo.decimals + ), + sqrtPriceLimitX96: 0 + }, + { + gasLimit: GAS_LIMIT + } + ) - debug(`Tx Hash: ${tx.hash}`); - tx.expectedAmount = amountInMaximum; - return tx; + debug(`Tx Hash: ${tx.hash}`) + tx.expectedAmount = amountInMaximum + return tx } // LP section async getPosition(wallet, tokenId) { - const contract = this.get_contract('nft', wallet); - const position = await contract.positions(tokenId); + const contract = this.get_contract('nft', wallet) + const position = await contract.positions(tokenId) return { nonce: position[0].toString(), operator: position[1], @@ -163,96 +218,178 @@ export default class UniswapV3 { feeGrowthInside0LastX128: position[8].toString(), feeGrowthInside1LastX128: position[9].toString(), tokensOwed0: position[10].toString(), - tokensOwed1: position[11].toString(), - }; + tokensOwed1: position[11].toString() + } } getRemoveLiquidityData(wallet, contract, tokenId, liquidity) { - const decreaseLiquidityData = contract.interface.encodeFunctionData('decreaseLiquidity', [{ - tokenId, - liquidity, - amount0Min: 0, - amount1Min: 0, - deadline: Date.now() + TTL, - }]); - const collectFeesData = contract.interface.encodeFunctionData('collect', [{ - tokenId, - recipient: wallet.signer.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }]); - const burnData = contract.interface.encodeFunctionData('burn', [tokenId]); + const decreaseLiquidityData = contract.interface.encodeFunctionData( + 'decreaseLiquidity', + [ + { + tokenId, + liquidity, + amount0Min: 0, + amount1Min: 0, + deadline: Date.now() + TTL + } + ] + ) + const collectFeesData = contract.interface.encodeFunctionData('collect', [ + { + tokenId, + recipient: wallet.signer.address, + amount0Max: MaxUint128, + amount1Max: MaxUint128 + } + ]) + const burnData = contract.interface.encodeFunctionData('burn', [tokenId]) - return [decreaseLiquidityData, collectFeesData, burnData]; + return [decreaseLiquidityData, collectFeesData, burnData] } - getAddLiquidityData(wallet, contract, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice) { - const mintData = contract.interface.encodeFunctionData('mint', [{ - token0: token0.address, - token1: token1.address, - tickLower: getTickFromPrice(lowerPrice, fee, 'UPPER'), - tickUpper: getTickFromPrice(upperPrice, fee, 'LOWER'), - amount0Desired: ethers.utils.parseUnits(amount0, token0.decimals), - amount1Desired: ethers.utils.parseUnits(amount1, token1.decimals), - // slippage isn't applied for now - amount0Min: 0, - amount1Min: 0, - recipient: wallet.signer.address, - deadline: Date.now() + TTL, - fee: FeeAmount[fee], - }]); + getAddLiquidityData( + wallet, + contract, + token0, + token1, + amount0, + amount1, + fee, + lowerPrice, + upperPrice + ) { + const mintData = contract.interface.encodeFunctionData('mint', [ + { + token0: token0.address, + token1: token1.address, + tickLower: getTickFromPrice(lowerPrice, fee, 'UPPER'), + tickUpper: getTickFromPrice(upperPrice, fee, 'LOWER'), + amount0Desired: ethers.utils.parseUnits(amount0, token0.decimals), + amount1Desired: ethers.utils.parseUnits(amount1, token1.decimals), + // slippage isn't applied for now + amount0Min: 0, + amount1Min: 0, + recipient: wallet.signer.address, + deadline: Date.now() + TTL, + fee: FeeAmount[fee] + } + ]) - return mintData; + return mintData } - async addPosition(wallet, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice) { - const nftContract = this.get_contract('nft', wallet); - const coreContract = this.get_contract('core', wallet); - const pool = await coreContract.getPool(token0.address, token1.address, FeeAmount[fee]); - const midPrice = math.fraction((lowerPrice + upperPrice) / 2); // Use mid price to initialize uninitialized pool - - const initPoolData = nftContract.interface.encodeFunctionData('createAndInitializePoolIfNecessary', [ + async addPosition( + wallet, + token0, + token1, + amount0, + amount1, + fee, + lowerPrice, + upperPrice + ) { + const nftContract = this.get_contract('nft', wallet) + const coreContract = this.get_contract('core', wallet) + const pool = await coreContract.getPool( token0.address, token1.address, - FeeAmount[fee], - encodePriceSqrt(midPrice.n, midPrice.d)]); + FeeAmount[fee] + ) + const midPrice = math.fraction((lowerPrice + upperPrice) / 2) // Use mid price to initialize uninitialized pool + + const initPoolData = nftContract.interface.encodeFunctionData( + 'createAndInitializePoolIfNecessary', + [ + token0.address, + token1.address, + FeeAmount[fee], + encodePriceSqrt(midPrice.n, midPrice.d) + ] + ) - const mintData = this.getAddLiquidityData(wallet, nftContract, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice); + const mintData = this.getAddLiquidityData( + wallet, + nftContract, + token0, + token1, + amount0, + amount1, + fee, + lowerPrice, + upperPrice + ) - const calls = [mintData]; + const calls = [mintData] if (pool === ethers.constants.AddressZero) { - const tx = await nftContract.multicall([initPoolData, mintData], { gasLimit: GAS_LIMIT }); - return tx; + const tx = await nftContract.multicall([initPoolData, mintData], { + gasLimit: GAS_LIMIT + }) + return tx } - const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }); - return tx; + const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }) + return tx } async removePosition(wallet, tokenId) { // Reduce position and burn - const positionData = await this.getPosition(wallet, tokenId); - const contract = this.get_contract('nft', wallet); - const data = this.getRemoveLiquidityData(wallet, contract, tokenId, positionData.liquidity); - return contract.multicall(data, { gasLimit: GAS_LIMIT }); + const positionData = await this.getPosition(wallet, tokenId) + const contract = this.get_contract('nft', wallet) + const data = this.getRemoveLiquidityData( + wallet, + contract, + tokenId, + positionData.liquidity + ) + return contract.multicall(data, { gasLimit: GAS_LIMIT }) } - async replacePosition(wallet, tokenId, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice) { - const contract = this.get_contract('nft', wallet); - const positionData = await this.getPosition(wallet, tokenId); - const removeData = this.getRemoveLiquidityData(wallet, contract, tokenId, positionData.liquidity); - const mintData = this.getAddLiquidityData(wallet, contract, token0, token1, amount0, amount1, fee, lowerPrice, upperPrice); + async replacePosition( + wallet, + tokenId, + token0, + token1, + amount0, + amount1, + fee, + lowerPrice, + upperPrice + ) { + const contract = this.get_contract('nft', wallet) + const positionData = await this.getPosition(wallet, tokenId) + const removeData = this.getRemoveLiquidityData( + wallet, + contract, + tokenId, + positionData.liquidity + ) + const mintData = this.getAddLiquidityData( + wallet, + contract, + token0, + token1, + amount0, + amount1, + fee, + lowerPrice, + upperPrice + ) - return contract.multicall(removeData.concat(mintData), { gasLimit: GAS_LIMIT }); + return contract.multicall(removeData.concat(mintData), { + gasLimit: GAS_LIMIT + }) } async collectFees(wallet, tokenId) { - const contract = this.get_contract('nft', wallet); - return contract.collect({ - tokenId, - recipient: wallet.signer.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }, - { gasLimit: GAS_LIMIT }); + const contract = this.get_contract('nft', wallet) + return contract.collect( + { + tokenId, + recipient: wallet.signer.address, + amount0Max: MaxUint128, + amount1Max: MaxUint128 + }, + { gasLimit: GAS_LIMIT } + ) } } diff --git a/src/services/utils.js b/src/services/utils.js index db1ce93..bb7124c 100644 --- a/src/services/utils.js +++ b/src/services/utils.js @@ -1,9 +1,9 @@ /* Hummingbot Utils */ -const lodash = require('lodash'); -const moment = require('moment'); -const { NonceManager } = require('@ethersproject/experimental'); +const lodash = require('lodash') +const moment = require('moment') +const { NonceManager } = require('@ethersproject/experimental') export const statusMessages = { ssl_cert_required: 'SSL Certificate required', @@ -12,76 +12,81 @@ export const statusMessages = { no_pool_available: 'No Pool Available', invalid_token_symbol: 'Invalid Token Symbol', insufficient_reserves: 'Insufficient Liquidity Reserves', - page_not_found: 'Page not found. Invalid path', -}; + page_not_found: 'Page not found. Invalid path' +} -export const latency = (startTime, endTime) => parseFloat((endTime - startTime) / 1000); +export const latency = (startTime, endTime) => + parseFloat((endTime - startTime) / 1000) export const isValidParams = (params) => { - const values = Object.values(params); + const values = Object.values(params) // DO NOT use forEach, it returns callback without breaking the loop for (let i = 0; i < values.length; i++) { if (typeof values[i] === 'undefined') { - throw new Error('Invalid input params'); + throw new Error('Invalid input params') } } - return true; -}; + return true +} export const isValidData = (data, format) => { - if (typeof data !== 'undefined' && Object.keys(data).length !== 0 && lodash.isEqual(Object.keys(data).sort(), format.sort())) { - return true; + if ( + typeof data !== 'undefined' && + Object.keys(data).length !== 0 && + lodash.isEqual(Object.keys(data).sort(), format.sort()) + ) { + return true } - return false; -}; + return false +} export const getParamData = (data, format = null) => { - const dataObject = {}; + const dataObject = {} if (format !== null) { if (isValidData(data, format)) { format.forEach((key, _index) => { - dataObject[key] = data[key]; - }); + dataObject[key] = data[key] + }) } } else { Object.keys(data).forEach((key, _index) => { - dataObject[key] = data[key]; - }); + dataObject[key] = data[key] + }) } - return dataObject; -}; + return dataObject +} export const splitParamData = (param, separator = ',') => { - const dataArray = param.split(separator); - return dataArray; -}; + const dataArray = param.split(separator) + return dataArray +} export const getSymbols = (tradingPair) => { - const symbols = tradingPair.split('-'); + const symbols = tradingPair.split('-') const baseQuotePair = { base: symbols[0].toUpperCase(), - quote: symbols[1].toUpperCase(), - }; - return baseQuotePair; -}; + quote: symbols[1].toUpperCase() + } + return baseQuotePair +} export const reportConnectionError = (res, error) => { res.json({ error: error.errno, - code: error.code, - }); -}; + code: error.code + }) +} -export const strToDecimal = (str) => parseInt(str) / 100; +export const strToDecimal = (str) => parseInt(str) / 100 export const getHummingbotMemo = () => { - const prefix = 'hbot'; - const clientId = process.env.HUMMINGBOT_INSTANCE_ID; - if ((typeof clientId !== 'undefined' && clientId != null) && clientId !== '') { - return [prefix, clientId].join('-'); + const prefix = 'hbot' + const clientId = process.env.HUMMINGBOT_INSTANCE_ID + if (typeof clientId !== 'undefined' && clientId != null && clientId !== '') { + return [prefix, clientId].join('-') } - return prefix; -}; + return prefix +} export const loadConfig = () => { const config = { @@ -89,39 +94,58 @@ export const loadConfig = () => { ethereum_chain: process.env.ETHEREUM_CHAIN, exchange_proxy: process.env.EXCHANGE_PROXY, ethereum_token_list_url: process.env.ETHEREUM_TOKEN_LIST_URL, - enable_eth_gas_station: process.env.ENABLE_ETH_GAS_STATION != null ? (process.env.ENABLE_ETH_GAS_STATION.toLowerCase() === 'true') : false, + enable_eth_gas_station: + process.env.ENABLE_ETH_GAS_STATION != null + ? process.env.ENABLE_ETH_GAS_STATION.toLowerCase() === 'true' + : false, eth_gas_station_gas_level: process.env.ETH_GAS_STATION_GAS_LEVEL, - eth_gas_station_refresh_time: process.env.ETH_GAS_STATION_REFRESH_TIME != null ? parseFloat(process.env.ETH_GAS_STATION_REFRESH_TIME) : null, - manual_gas_price: process.env.MANUAL_GAS_PRICE != null ? parseFloat(process.env.MANUAL_GAS_PRICE) : null, + eth_gas_station_refresh_time: + process.env.ETH_GAS_STATION_REFRESH_TIME != null + ? parseFloat(process.env.ETH_GAS_STATION_REFRESH_TIME) + : null, + manual_gas_price: + process.env.MANUAL_GAS_PRICE != null + ? parseFloat(process.env.MANUAL_GAS_PRICE) + : null, react_app_subgraph_url: process.env.REACT_APP_SUBGRAPH_URL, - balancer_max_swaps: process.env.BALANCER_MAX_SWAPS != null ? parseInt(process.env.BALANCER_MAX_SWAPS) : null, + balancer_max_swaps: + process.env.BALANCER_MAX_SWAPS != null + ? parseInt(process.env.BALANCER_MAX_SWAPS) + : null, uniswap_router: process.env.UNISWAP_ROUTER, terra_lcd_url: process.env.TERRA_LCD_URL, - terra_chain: process.env.TERRA_CHAIN, - }; - return config; -}; + terra_chain: process.env.TERRA_CHAIN + } + return config +} export const getLocalDate = () => { - const gmtOffset = process.env.GMT_OFFSET; - let newDate = moment().format('YYYY-MM-DD hh:mm:ss').trim(); - if (typeof gmtOffset !== 'undefined' && gmtOffset !== null && gmtOffset !== '') { - newDate = moment().utcOffset(gmtOffset, false).format('YYYY-MM-DD hh:mm:ss').trim(); + const gmtOffset = process.env.GMT_OFFSET + let newDate = moment().format('YYYY-MM-DD hh:mm:ss').trim() + if ( + typeof gmtOffset !== 'undefined' && + gmtOffset !== null && + gmtOffset !== '' + ) { + newDate = moment() + .utcOffset(gmtOffset, false) + .format('YYYY-MM-DD hh:mm:ss') + .trim() } - return newDate; -}; + return newDate +} -export const nonceManagerCache = {}; +export const nonceManagerCache = {} export const getNonceManager = async (signer) => { - let key = await signer.getAddress(); + let key = await signer.getAddress() if (signer.provider) { - key += (await signer.provider.getNetwork()).chainId; + key += (await signer.provider.getNetwork()).chainId } - let nonceManager = nonceManagerCache[key]; + let nonceManager = nonceManagerCache[key] if (typeof nonceManager === 'undefined') { - nonceManager = new NonceManager(signer); - nonceManagerCache[key] = nonceManager; + nonceManager = new NonceManager(signer) + nonceManagerCache[key] = nonceManager } - return nonceManager; -}; + return nonceManager +} diff --git a/src/static/abi.js b/src/static/abi.js index 8762479..ec06099 100644 --- a/src/static/abi.js +++ b/src/static/abi.js @@ -2,233 +2,385 @@ const ERC20Abi = [ { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "balance", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" + constant: true, + inputs: [], + name: 'name', + outputs: [ + { + name: '', + type: 'string' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_spender', + type: 'address' + }, + { + name: '_value', + type: 'uint256' + } + ], + name: 'approve', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_from', + type: 'address' + }, + { + name: '_to', + type: 'address' + }, + { + name: '_value', + type: 'uint256' + } + ], + name: 'transferFrom', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [ + { + name: '', + type: 'uint8' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_owner', + type: 'address' + } + ], + name: 'balanceOf', + outputs: [ + { + name: 'balance', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [ + { + name: '', + type: 'string' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { + name: '_to', + type: 'address' + }, + { + name: '_value', + type: 'uint256' + } + ], + name: 'transfer', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [ + { + name: '_owner', + type: 'address' + }, + { + name: '_spender', + type: 'address' + } + ], + name: 'allowance', + outputs: [ + { + name: '', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + payable: true, + stateMutability: 'payable', + type: 'fallback' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address' + }, + { + indexed: true, + name: 'spender', + type: 'address' + }, + { + indexed: false, + name: 'value', + type: 'uint256' + } + ], + name: 'Approval', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'from', + type: 'address' + }, + { + indexed: true, + name: 'to', + type: 'address' + }, + { + indexed: false, + name: 'value', + type: 'uint256' + } + ], + name: 'Transfer', + type: 'event' } ] -const KovanWETHAbi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}] +const KovanWETHAbi = [ + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: 'guy', type: 'address' }, + { name: 'wad', type: 'uint256' } + ], + name: 'approve', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: 'src', type: 'address' }, + { name: 'dst', type: 'address' }, + { name: 'wad', type: 'uint256' } + ], + name: 'transferFrom', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [{ name: 'wad', type: 'uint256' }], + name: 'withdraw', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: 'dst', type: 'address' }, + { name: 'wad', type: 'uint256' } + ], + name: 'transfer', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [], + name: 'deposit', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function' + }, + { + constant: true, + inputs: [ + { name: '', type: 'address' }, + { name: '', type: 'address' } + ], + name: 'allowance', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { payable: true, stateMutability: 'payable', type: 'fallback' }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'src', type: 'address' }, + { indexed: true, name: 'guy', type: 'address' }, + { indexed: false, name: 'wad', type: 'uint256' } + ], + name: 'Approval', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'src', type: 'address' }, + { indexed: true, name: 'dst', type: 'address' }, + { indexed: false, name: 'wad', type: 'uint256' } + ], + name: 'Transfer', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'dst', type: 'address' }, + { indexed: false, name: 'wad', type: 'uint256' } + ], + name: 'Deposit', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'src', type: 'address' }, + { indexed: false, name: 'wad', type: 'uint256' } + ], + name: 'Withdrawal', + type: 'event' + } +] const KovanFaucetAddress = '0xb48Cc42C45d262534e46d5965a9Ac496F1B7a830' module.exports = { ERC20Abi, KovanWETHAbi, - KovanFaucetAddress, -}; + KovanFaucetAddress +} diff --git a/src/static/uniswap-v3/helper_functions.js b/src/static/uniswap-v3/helper_functions.js index c6e90fd..6015333 100644 --- a/src/static/uniswap-v3/helper_functions.js +++ b/src/static/uniswap-v3/helper_functions.js @@ -1,26 +1,24 @@ -import bn from 'bignumber.js'; -import JSBI from 'jsbi'; -import { - BigNumber, mulShift, Q32, ZERO, ONE, MaxUint256, -} from 'ethers'; +import bn from 'bignumber.js' +import JSBI from 'jsbi' +import { BigNumber, mulShift, Q32, ZERO, ONE, MaxUint256 } from 'ethers' -const math = require('mathjs'); +const math = require('mathjs') -const TICK_SPACINGS = { LOW: 10, MEDIUM: 60, HIGH: 2000 }; +const TICK_SPACINGS = { LOW: 10, MEDIUM: 60, HIGH: 2000 } -bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }); +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }) export function expandTo18Decimals(n) { - return BigNumber.from(n).mul(BigNumber.from(10).pow(18)); + return BigNumber.from(n).mul(BigNumber.from(10).pow(18)) } export function toHex(bigintIsh) { - const bigInt = JSBI.BigInt(bigintIsh); - let hex = bigInt.toString(16); + const bigInt = JSBI.BigInt(bigintIsh) + let hex = bigInt.toString(16) if (hex.length % 2 !== 0) { - hex = `0${hex}`; + hex = `0${hex}` } - return `0x${hex}`; + return `0x${hex}` } // returns the sqrt price as a 64x96 @@ -31,8 +29,8 @@ export function encodePriceSqrt(reserve1, reserve0) { .sqrt() .multipliedBy(new bn(2).pow(96)) .integerValue(3) - .toString(), - ); + .toString() + ) } export function getLiquidity(amount0, amount1) { @@ -40,8 +38,8 @@ export function getLiquidity(amount0, amount1) { new bn(amount0.toString()) .multipliedBy(amount1.toString()) .sqrt() - .toString(), - ); + .toString() + ) /* let tokenPrice0, tokenPrice1, tokenFraction; tokenFraction = math.fraction(amount1/amount0) tokenPrice0 = encodePriceSqrt(tokenFraction.n, tokenFraction.d) @@ -49,116 +47,160 @@ export function getLiquidity(amount0, amount1) { return tokenPrice0.mul(tokenPrice1) */ } -const TWO = JSBI.BigInt(2); +const TWO = JSBI.BigInt(2) const POWERS_OF_2 = [128, 64, 32, 16, 8, 4, 2, 1].map((pow) => [ pow, - JSBI.exponentiate(TWO, JSBI.BigInt(pow)), -]); + JSBI.exponentiate(TWO, JSBI.BigInt(pow)) +]) export function mostSignificantBit(x) { - let y = x; - let msb = 0; + let y = x + let msb = 0 for (const [power, min] of POWERS_OF_2) { if (JSBI.greaterThanOrEqual(y, min)) { - y = JSBI.signedRightShift(y, JSBI.BigInt(power)); - msb += power; + y = JSBI.signedRightShift(y, JSBI.BigInt(power)) + msb += power } } - return msb; + return msb } export function getSqrtRatioAtTick(tick) { - const absTick = tick < 0 ? tick * -1 : tick; - - let ratio = (absTick & 0x1) !== 0 - ? JSBI.BigInt('0xfffcb933bd6fad37aa2d162d1a594001') - : JSBI.BigInt('0x100000000000000000000000000000000'); - if ((absTick & 0x2) !== 0) ratio = mulShift(ratio, '0xfff97272373d413259a46990580e213a'); - if ((absTick & 0x4) !== 0) ratio = mulShift(ratio, '0xfff2e50f5f656932ef12357cf3c7fdcc'); - if ((absTick & 0x8) !== 0) ratio = mulShift(ratio, '0xffe5caca7e10e4e61c3624eaa0941cd0'); - if ((absTick & 0x10) !== 0) ratio = mulShift(ratio, '0xffcb9843d60f6159c9db58835c926644'); - if ((absTick & 0x20) !== 0) ratio = mulShift(ratio, '0xff973b41fa98c081472e6896dfb254c0'); - if ((absTick & 0x40) !== 0) ratio = mulShift(ratio, '0xff2ea16466c96a3843ec78b326b52861'); - if ((absTick & 0x80) !== 0) ratio = mulShift(ratio, '0xfe5dee046a99a2a811c461f1969c3053'); - if ((absTick & 0x100) !== 0) ratio = mulShift(ratio, '0xfcbe86c7900a88aedcffc83b479aa3a4'); - if ((absTick & 0x200) !== 0) ratio = mulShift(ratio, '0xf987a7253ac413176f2b074cf7815e54'); - if ((absTick & 0x400) !== 0) ratio = mulShift(ratio, '0xf3392b0822b70005940c7a398e4b70f3'); - if ((absTick & 0x800) !== 0) ratio = mulShift(ratio, '0xe7159475a2c29b7443b29c7fa6e889d9'); - if ((absTick & 0x1000) !== 0) ratio = mulShift(ratio, '0xd097f3bdfd2022b8845ad8f792aa5825'); - if ((absTick & 0x2000) !== 0) ratio = mulShift(ratio, '0xa9f746462d870fdf8a65dc1f90e061e5'); - if ((absTick & 0x4000) !== 0) ratio = mulShift(ratio, '0x70d869a156d2a1b890bb3df62baf32f7'); - if ((absTick & 0x8000) !== 0) ratio = mulShift(ratio, '0x31be135f97d08fd981231505542fcfa6'); - if ((absTick & 0x10000) !== 0) ratio = mulShift(ratio, '0x9aa508b5b7a84e1c677de54f3e99bc9'); - if ((absTick & 0x20000) !== 0) ratio = mulShift(ratio, '0x5d6af8dedb81196699c329225ee604'); - if ((absTick & 0x40000) !== 0) ratio = mulShift(ratio, '0x2216e584f5fa1ea926041bedfe98'); - if ((absTick & 0x80000) !== 0) ratio = mulShift(ratio, '0x48a170391f7dc42444e8fa2'); - - if (tick > 0) ratio = JSBI.divide(MaxUint256, ratio); + const absTick = tick < 0 ? tick * -1 : tick + + let ratio = + (absTick & 0x1) !== 0 + ? JSBI.BigInt('0xfffcb933bd6fad37aa2d162d1a594001') + : JSBI.BigInt('0x100000000000000000000000000000000') + if ((absTick & 0x2) !== 0) + ratio = mulShift(ratio, '0xfff97272373d413259a46990580e213a') + if ((absTick & 0x4) !== 0) + ratio = mulShift(ratio, '0xfff2e50f5f656932ef12357cf3c7fdcc') + if ((absTick & 0x8) !== 0) + ratio = mulShift(ratio, '0xffe5caca7e10e4e61c3624eaa0941cd0') + if ((absTick & 0x10) !== 0) + ratio = mulShift(ratio, '0xffcb9843d60f6159c9db58835c926644') + if ((absTick & 0x20) !== 0) + ratio = mulShift(ratio, '0xff973b41fa98c081472e6896dfb254c0') + if ((absTick & 0x40) !== 0) + ratio = mulShift(ratio, '0xff2ea16466c96a3843ec78b326b52861') + if ((absTick & 0x80) !== 0) + ratio = mulShift(ratio, '0xfe5dee046a99a2a811c461f1969c3053') + if ((absTick & 0x100) !== 0) + ratio = mulShift(ratio, '0xfcbe86c7900a88aedcffc83b479aa3a4') + if ((absTick & 0x200) !== 0) + ratio = mulShift(ratio, '0xf987a7253ac413176f2b074cf7815e54') + if ((absTick & 0x400) !== 0) + ratio = mulShift(ratio, '0xf3392b0822b70005940c7a398e4b70f3') + if ((absTick & 0x800) !== 0) + ratio = mulShift(ratio, '0xe7159475a2c29b7443b29c7fa6e889d9') + if ((absTick & 0x1000) !== 0) + ratio = mulShift(ratio, '0xd097f3bdfd2022b8845ad8f792aa5825') + if ((absTick & 0x2000) !== 0) + ratio = mulShift(ratio, '0xa9f746462d870fdf8a65dc1f90e061e5') + if ((absTick & 0x4000) !== 0) + ratio = mulShift(ratio, '0x70d869a156d2a1b890bb3df62baf32f7') + if ((absTick & 0x8000) !== 0) + ratio = mulShift(ratio, '0x31be135f97d08fd981231505542fcfa6') + if ((absTick & 0x10000) !== 0) + ratio = mulShift(ratio, '0x9aa508b5b7a84e1c677de54f3e99bc9') + if ((absTick & 0x20000) !== 0) + ratio = mulShift(ratio, '0x5d6af8dedb81196699c329225ee604') + if ((absTick & 0x40000) !== 0) + ratio = mulShift(ratio, '0x2216e584f5fa1ea926041bedfe98') + if ((absTick & 0x80000) !== 0) + ratio = mulShift(ratio, '0x48a170391f7dc42444e8fa2') + + if (tick > 0) ratio = JSBI.divide(MaxUint256, ratio) // back to Q96 return JSBI.greaterThan(JSBI.remainder(ratio, Q32), ZERO) ? JSBI.add(JSBI.divide(ratio, Q32), ONE) - : JSBI.divide(ratio, Q32); + : JSBI.divide(ratio, Q32) } export function getTickAtSqrtRatio(sqrtRatioX96) { - const sqrtRatioX128 = JSBI.leftShift(sqrtRatioX96, JSBI.BigInt(32)); + const sqrtRatioX128 = JSBI.leftShift(sqrtRatioX96, JSBI.BigInt(32)) - const msb = mostSignificantBit(sqrtRatioX128); + const msb = mostSignificantBit(sqrtRatioX128) - let r; + let r if (JSBI.greaterThanOrEqual(JSBI.BigInt(msb), JSBI.BigInt(128))) { - r = JSBI.signedRightShift(sqrtRatioX128, JSBI.BigInt(msb - 127)); + r = JSBI.signedRightShift(sqrtRatioX128, JSBI.BigInt(msb - 127)) } else { - r = JSBI.leftShift(sqrtRatioX128, JSBI.BigInt(127 - msb)); + r = JSBI.leftShift(sqrtRatioX128, JSBI.BigInt(127 - msb)) } - let log_2 = JSBI.leftShift(JSBI.subtract(JSBI.BigInt(msb), JSBI.BigInt(128)), JSBI.BigInt(64)); + let log_2 = JSBI.leftShift( + JSBI.subtract(JSBI.BigInt(msb), JSBI.BigInt(128)), + JSBI.BigInt(64) + ) for (let i = 0; i < 14; i++) { - r = JSBI.signedRightShift(JSBI.multiply(r, r), JSBI.BigInt(127)); - const f = JSBI.signedRightShift(r, JSBI.BigInt(128)); - log_2 = JSBI.bitwiseOr(log_2, JSBI.leftShift(f, JSBI.BigInt(63 - i))); - r = JSBI.signedRightShift(r, f); + r = JSBI.signedRightShift(JSBI.multiply(r, r), JSBI.BigInt(127)) + const f = JSBI.signedRightShift(r, JSBI.BigInt(128)) + log_2 = JSBI.bitwiseOr(log_2, JSBI.leftShift(f, JSBI.BigInt(63 - i))) + r = JSBI.signedRightShift(r, f) } - const log_sqrt10001 = JSBI.multiply(log_2, JSBI.BigInt('255738958999603826347141')); + const log_sqrt10001 = JSBI.multiply( + log_2, + JSBI.BigInt('255738958999603826347141') + ) const tickLow = JSBI.toNumber( JSBI.signedRightShift( - JSBI.subtract(log_sqrt10001, JSBI.BigInt('3402992956809132418596140100660247210')), - JSBI.BigInt(128), - ), - ); + JSBI.subtract( + log_sqrt10001, + JSBI.BigInt('3402992956809132418596140100660247210') + ), + JSBI.BigInt(128) + ) + ) const tickHigh = JSBI.toNumber( JSBI.signedRightShift( - JSBI.add(log_sqrt10001, JSBI.BigInt('291339464771989622907027621153398088495')), - JSBI.BigInt(128), - ), - ); + JSBI.add( + log_sqrt10001, + JSBI.BigInt('291339464771989622907027621153398088495') + ), + JSBI.BigInt(128) + ) + ) if (tickLow === tickHigh) { - return tickLow; + return tickLow } return JSBI.lessThanOrEqual(getSqrtRatioAtTick(tickHigh), sqrtRatioX96) ? tickHigh - : tickLow; + : tickLow } -export function getMinTick(tier) { return Math.ceil(-887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; } +export function getMinTick(tier) { + return Math.ceil(-887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier] +} -export function getMaxTick(tier) { return Math.floor(887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; } +export function getMaxTick(tier) { + return Math.floor(887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier] +} export function getTickFromPrice(price, tier, side) { - let tick = 0; + let tick = 0 if (side === 'UPPER') { - tick = math.ceil(math.log(price, 1.0001) / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; + tick = + math.ceil(math.log(price, 1.0001) / TICK_SPACINGS[tier]) * + TICK_SPACINGS[tier] } else { - tick = math.floor(math.log(price, 1.0001) / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; + tick = + math.floor(math.log(price, 1.0001) / TICK_SPACINGS[tier]) * + TICK_SPACINGS[tier] } - if (tick >= getMaxTick(tier)) { return getMaxTick(tier); } - if (tick <= getMinTick(tier)) { return getMinTick(tier); } - return tick; + if (tick >= getMaxTick(tier)) { + return getMaxTick(tier) + } + if (tick <= getMinTick(tier)) { + return getMinTick(tier) + } + return tick } diff --git a/src/static/uniswap_route_tokens.json b/src/static/uniswap_route_tokens.json index 08c66bf..8a2d5e2 100644 --- a/src/static/uniswap_route_tokens.json +++ b/src/static/uniswap_route_tokens.json @@ -1,15 +1,72 @@ -{"mainnet": [ - {"address":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","name":"WrappedEther","symbol":"WETH","decimals":18}, - {"address":"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599","name":"WrappedBTC","symbol":"WBTC","decimals":8}, - {"address":"0x6B175474E89094C44Da98b954EedeAC495271d0F","name":"DaiStablecoin","symbol":"DAI","decimals":18}, - {"address":"0xdAC17F958D2ee523a2206206994597C13D831ec7","name":"TetherUSD","symbol":"USDT","decimals":6}, - {"address":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","name":"USDCoin","symbol":"USDC","decimals":6}, - {"address":"0xba100000625a3754423978a60c9317c58a424e3D","name":"Balancer","symbol":"BAL","decimals":18}, - {"address":"0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD","name":"Loopring","symbol":"LRC","decimals":18} -], -"kovan":[ - {"address":"0xd0A1E359811322d97991E03f863a0C30C2cF029C","name":"WrappedEther","symbol":"WETH","decimals":18}, - {"address":"0xe0C9275E44Ea80eF17579d33c55136b7DA269aEb","name":"WrappedBTC","symbol":"WBTC","decimals":8}, - {"address":"0x1528F3FCc26d13F7079325Fb78D9442607781c8C","name":"DaiStablecoin","symbol":"DAI","decimals":18}, - {"address":"0x2F375e94FC336Cdec2Dc0cCB5277FE59CBf1cAe5","name":"USDCoin","symbol":"USDC","decimals":6} -]} +{ + "mainnet": [ + { + "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "name": "WrappedEther", + "symbol": "WETH", + "decimals": 18 + }, + { + "address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", + "name": "WrappedBTC", + "symbol": "WBTC", + "decimals": 8 + }, + { + "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", + "name": "DaiStablecoin", + "symbol": "DAI", + "decimals": 18 + }, + { + "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "name": "TetherUSD", + "symbol": "USDT", + "decimals": 6 + }, + { + "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "name": "USDCoin", + "symbol": "USDC", + "decimals": 6 + }, + { + "address": "0xba100000625a3754423978a60c9317c58a424e3D", + "name": "Balancer", + "symbol": "BAL", + "decimals": 18 + }, + { + "address": "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD", + "name": "Loopring", + "symbol": "LRC", + "decimals": 18 + } + ], + "kovan": [ + { + "address": "0xd0A1E359811322d97991E03f863a0C30C2cF029C", + "name": "WrappedEther", + "symbol": "WETH", + "decimals": 18 + }, + { + "address": "0xe0C9275E44Ea80eF17579d33c55136b7DA269aEb", + "name": "WrappedBTC", + "symbol": "WBTC", + "decimals": 8 + }, + { + "address": "0x1528F3FCc26d13F7079325Fb78D9442607781c8C", + "name": "DaiStablecoin", + "symbol": "DAI", + "decimals": 18 + }, + { + "address": "0x2F375e94FC336Cdec2Dc0cCB5277FE59CBf1cAe5", + "name": "USDCoin", + "symbol": "USDC", + "decimals": 6 + } + ] +} diff --git a/yarn.lock b/yarn.lock index 7e28c89..5435848 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2368,6 +2368,11 @@ eslint-config-airbnb-base@^14.2.1: object.assign "^4.1.2" object.entries "^1.1.2" +eslint-config-prettier@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" + integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== + eslint-config-standard@^14.1.1: version "14.1.1" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" @@ -2430,6 +2435,13 @@ eslint-plugin-node@^11.1.0: resolve "^1.10.1" semver "^6.1.0" +eslint-plugin-prettier@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz#cdbad3bf1dbd2b177e9825737fe63b476a08f0c7" + integrity sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw== + dependencies: + prettier-linter-helpers "^1.0.0" + eslint-plugin-promise@^4.2.1: version "4.3.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz#61485df2a359e03149fdafc0a68b0e030ad2ac45" @@ -2669,6 +2681,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -4044,6 +4061,18 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" + integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" From ecbbd6dac1ae5f28544472c7137f0135febf2f6c Mon Sep 17 00:00:00 2001 From: james-hummingbot Date: Fri, 4 Jun 2021 10:18:04 +0200 Subject: [PATCH 27/31] Use eslint:recommended and clean up rules --- .eslintrc.js | 33 +- .prettierrc | 2 +- README.md | 19 +- package.json | 9 +- src/app.js | 78 ++--- src/index.js | 80 ++--- src/routes/balancer.route.js | 251 +++++++------- src/routes/celo.route.js | 220 ++++++------ src/routes/eth.route.js | 314 ++++++++--------- src/routes/index.route.js | 12 +- src/routes/perpetual_finance.route.js | 388 +++++++++++----------- src/routes/terra.route.js | 178 +++++----- src/routes/uniswap.route.js | 248 +++++++------- src/routes/uniswap_v3.route.js | 380 ++++++++++----------- src/services/access.js | 28 +- src/services/balancer.js | 183 +++++----- src/services/eth.js | 146 ++++---- src/services/fees.js | 56 ++-- src/services/logger.js | 34 +- src/services/perpetual_finance.js | 301 ++++++++--------- src/services/terra.js | 328 +++++++++--------- src/services/uniswap.js | 222 +++++++------ src/services/uniswap_v3.js | 213 ++++++------ src/services/utils.js | 100 +++--- src/static/abi.js | 8 +- src/static/uniswap-v3/helper_functions.js | 132 ++++---- yarn.lock | 65 ++-- 27 files changed, 2030 insertions(+), 1998 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 7d65f3a..f8b2ed8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,32 +1,17 @@ module.exports = { - extends: ['airbnb-base', 'eslint:recommended', 'prettier'], + extends: ['eslint:recommended', 'prettier'], + parser: 'babel-eslint', plugins: ['prettier'], env: { - node: true + node: true, + es6: true }, rules: { - camelcase: 'off', - 'consistent-return': 'off', - 'class-methods-use-this': 'off', - 'guard-for-in': 'off', - 'import/prefer-default-export': 'off', - 'max-len': 'off', - 'new-cap': 'off', - 'no-await-in-loop': 'off', - 'no-bitwise': 'off', - 'no-case-declarations': 'off', - 'no-console': 'off', - 'no-mixed-operators': 'off', - 'no-multi-assign': 'off', - 'no-plusplus': 'off', - 'no-prototype-builtins': 'off', - 'no-restricted-syntax': 'off', - 'no-return-assign': 'off', - 'no-unused-expressions': 'off', - 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + 'comma-dangle': ['error', 'never'], + 'no-multi-spaces': 'off', 'no-underscore-dangle': 'off', - 'prefer-destructuring': 'off', + 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], 'prettier/prettier': 'error', - radix: 'off' + semi: [2, 'always'] } -} +}; diff --git a/.prettierrc b/.prettierrc index 0d1aa74..0acea4c 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,6 @@ { "trailingComma": "none", - "semi": false, + "semi": true, "singleQuote": true, "tabWidth": 2 } diff --git a/README.md b/README.md index 01aa595..d5efbf7 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,6 @@ Hummingbot Gateway is an open-source project that integrates cryptocurrency trad We created hummingbot to promote **decentralized market-making**: enabling members of the community to contribute to the liquidity and trading efficiency in cryptocurrency markets. - - ## Getting Started ### Learn more about Hummingbot @@ -46,3 +44,20 @@ Hummingbot Gateway was created and is maintained by CoinAlpha, Inc. We are [a gl ## Legal - **License**: Hummingbot is licensed under [Apache 2.0](./LICENSE). + +## Development + +This repo uses `eslint` and `prettier`. When you run `git commit` it will trigger the `pre-commit` hook. +This will run `eslint` on the `src` and `test` directories. + +You can lint before committing with: + +```bash +yarn run lint +``` + +You can run the prettifier before committing with: + +```bash +yarn run prettier +``` diff --git a/package.json b/package.json index 02f1555..55933c6 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "dev": "nodemon --exec babel-node src/index.js", "debug": "DEBUG=*router nodemon --exec babel-node src/index.js", "lint": "node_modules/.bin/eslint src --format table", + "prettier": "node_modules/.bin/prettier . --write", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { @@ -47,14 +48,14 @@ "@babel/core": "^7.14.0", "@babel/node": "^7.10.5", "@babel/preset-env": "^7.14.1", + "babel-eslint": "^10.1.0", "eslint": "^7.25.0", - "eslint-config-airbnb-base": "^14.2.1", "eslint-config-prettier": "^8.3.0", - "eslint-config-standard": "^14.1.1", - "eslint-plugin-import": "^2.23.3", + "eslint-config-standard": "^16.0.3", + "eslint-plugin-import": "^2.23.4", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^3.4.0", - "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-promise": "^5.1.0", "eslint-plugin-standard": "^4.0.1", "nodemon": "^2.0.4", "prettier": "^2.3.0" diff --git a/src/app.js b/src/app.js index 811c3f8..5225a31 100644 --- a/src/app.js +++ b/src/app.js @@ -1,69 +1,69 @@ -import dotenv from 'dotenv' -import bodyParser from 'body-parser' -import express from 'express' -import helmet from 'helmet' -import { IpFilter } from 'express-ipfilter' -import { statusMessages } from './services/utils' -import { validateAccess } from './services/access' -import { logger } from './services/logger' +import dotenv from 'dotenv'; +import bodyParser from 'body-parser'; +import express from 'express'; +import helmet from 'helmet'; +import { IpFilter } from 'express-ipfilter'; +import { statusMessages } from './services/utils'; +import { validateAccess } from './services/access'; +import { logger } from './services/logger'; // Routes -import apiRoutes from './routes/index.route' -import balancerRoutes from './routes/balancer.route' -import ethRoutes from './routes/eth.route' -import terraRoutes from './routes/terra.route' -import uniswapRoutes from './routes/uniswap.route' -import uniswapV3Routes from './routes/uniswap_v3.route' -import perpFiRoutes from './routes/perpetual_finance.route' +import apiRoutes from './routes/index.route'; +import balancerRoutes from './routes/balancer.route'; +import ethRoutes from './routes/eth.route'; +import terraRoutes from './routes/terra.route'; +import uniswapRoutes from './routes/uniswap.route'; +import uniswapV3Routes from './routes/uniswap_v3.route'; +import perpFiRoutes from './routes/perpetual_finance.route'; // terminate if environment not found -const result = dotenv.config() +const result = dotenv.config(); if (result.error) { - logger.error(result.error) - process.exit(1) + logger.error(result.error); + process.exit(1); } // create app -const app = express() +const app = express(); // middleware // #security: remove response headers from middleware // https://www.npmjs.com/package/helmet -app.use(helmet()) +app.use(helmet()); -const ipWhitelist = process.env.IP_WHITELIST +const ipWhitelist = process.env.IP_WHITELIST; if (ipWhitelist) { - app.use(IpFilter(JSON.parse(ipWhitelist), { mode: 'allow' })) + app.use(IpFilter(JSON.parse(ipWhitelist), { mode: 'allow' })); } -app.use(bodyParser.json()) -app.use(bodyParser.urlencoded({ extended: true })) +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); -app.use(validateAccess) +app.use(validateAccess); // mount routes to specific path -app.use('/api', apiRoutes) -app.use('/eth', ethRoutes) -app.use('/eth/uniswap', uniswapRoutes) -app.use('/eth/uniswap/v3', uniswapV3Routes) -app.use('/eth/balancer', balancerRoutes) -app.use('/terra', terraRoutes) -app.use('/perpfi', perpFiRoutes) +app.use('/api', apiRoutes); +app.use('/eth', ethRoutes); +app.use('/eth/uniswap', uniswapRoutes); +app.use('/eth/uniswap/v3', uniswapV3Routes); +app.use('/eth/balancer', balancerRoutes); +app.use('/terra', terraRoutes); +app.use('/perpfi', perpFiRoutes); // app.use('/celo', celoRoutes); app.get('/', (req, res, _next) => { - res.send('ok') -}) + res.send('ok'); +}); /** * Catch all 404 response when routes are not found */ app.use((req, res, _next) => { - const message = `${statusMessages.page_not_found} at ${req.originalUrl}` - logger.error(message) + const message = `${statusMessages.page_not_found} at ${req.originalUrl}`; + logger.error(message); res.status(404).send({ error: 'Page not found', message - }) -}) + }); +}); -export default app +export default app; diff --git a/src/index.js b/src/index.js index f7480db..b747328 100644 --- a/src/index.js +++ b/src/index.js @@ -1,37 +1,37 @@ #!/usr/bin/env node // absolute imports -import https from 'https' -import dotenv from 'dotenv' -import fs from 'fs' +import https from 'https'; +import dotenv from 'dotenv'; +import fs from 'fs'; // relative imports -import app from './app' -import { logger } from './services/logger' +import app from './app'; +import { logger } from './services/logger'; // terminate if environment not found -const result = dotenv.config() +const result = dotenv.config(); if (result.error) { - logger.info(result.error) - process.exit(1) + logger.info(result.error); + process.exit(1); } -const env = process.env.NODE_ENV -const port = process.env.PORT -const certPassphrase = process.env.CERT_PASSPHRASE -const ethereumChain = process.env.ETHEREUM_CHAIN -const terraChain = process.env.TERRA_CHAIN -let certPath = process.env.CERT_PATH +const env = process.env.NODE_ENV; +const port = process.env.PORT; +const certPassphrase = process.env.CERT_PASSPHRASE; +const ethereumChain = process.env.ETHEREUM_CHAIN; +const terraChain = process.env.TERRA_CHAIN; +let certPath = process.env.CERT_PATH; if ((typeof certPath === 'undefined' && certPath == null) || certPath === '') { // assuming it is local development using test script to generate certs - certPath = './certs' + certPath = './certs'; } else { - certPath = certPath.replace(/\/$/, '') + certPath = certPath.replace(/\/$/, ''); } // set app environment -app.set('env', env) +app.set('env', env); const options = { key: fs.readFileSync(certPath.concat('/server_key.pem'), { encoding: 'utf-8' @@ -46,52 +46,52 @@ const options = { // use ca cert created with own key for self-signed ca: [fs.readFileSync(certPath.concat('/ca_cert.pem'), { encoding: 'utf-8' })], passphrase: certPassphrase -} +}; -const server = https.createServer(options, app) +const server = https.createServer(options, app); // event listener for "error" event const onError = (error) => { if (error.syscall !== 'listen') { - throw error + throw error; } - const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}` + const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': - console.error(`${bind} requires elevated privileges`) - process.exit(1) - break + console.error(`${bind} requires elevated privileges`); + process.exit(1); + break; case 'EADDRINUSE': - console.error(`${bind} is already in use`) - process.exit(1) - break + console.error(`${bind} is already in use`); + process.exit(1); + break; default: - throw error + throw error; } -} +}; // event listener for "listening" event. const onListening = () => { - const addr = server.address() - const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}` - console.log(`listening on ${bind}`) - logger.debug(`listening on ${bind}`) -} + const addr = server.address(); + const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`; + console.log(`listening on ${bind}`); + logger.debug(`listening on ${bind}`); +}; // listen on provided port, on all network interfaces. -server.listen(port) -server.on('error', onError) -server.on('listening', onListening) +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); const serverConfig = { app: 'gateway-api', port, ethereumChain, terraChain -} +}; -logger.info(JSON.stringify(serverConfig)) -console.log(serverConfig) +logger.info(JSON.stringify(serverConfig)); +console.log(serverConfig); diff --git a/src/routes/balancer.route.js b/src/routes/balancer.route.js index ddc17e6..1b75e4b 100644 --- a/src/routes/balancer.route.js +++ b/src/routes/balancer.route.js @@ -1,28 +1,28 @@ -import BigNumber from 'bignumber.js' -import { ethers } from 'ethers' -import express from 'express' +import BigNumber from 'bignumber.js'; +import { ethers } from 'ethers'; +import express from 'express'; -import { getParamData, latency, statusMessages } from '../services/utils' +import { getParamData, latency, statusMessages } from '../services/utils'; -import Ethereum from '../services/eth' -import Balancer from '../services/balancer' -import Fees from '../services/fees' -import { logger } from '../services/logger' +import Ethereum from '../services/eth'; +import Balancer from '../services/balancer'; +import Fees from '../services/fees'; +import { logger } from '../services/logger'; -const debug = require('debug')('router') +const debug = require('debug')('router'); -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) -const balancer = new Balancer(process.env.ETHEREUM_CHAIN) -const fees = new Fees() +const router = express.Router(); +const eth = new Ethereum(process.env.ETHEREUM_CHAIN); +const balancer = new Balancer(process.env.ETHEREUM_CHAIN); +const fees = new Fees(); -const swapMoreThanMaxPriceError = 'Price too high' -const swapLessThanMaxPriceError = 'Price too low' +const swapMoreThanMaxPriceError = 'Price too high'; +const swapLessThanMaxPriceError = 'Price too low'; const estimateGasLimit = (maxswaps) => { - const gasLimit = balancer.gasBase + maxswaps * balancer.gasPerSwap - return gasLimit -} + const gasLimit = balancer.gasBase + maxswaps * balancer.gasPerSwap; + return gasLimit; +}; router.post('/', async (req, res) => { /* @@ -35,8 +35,8 @@ router.post('/', async (req, res) => { subgraphUrl: balancer.subgraphUrl, connection: true, timestamp: Date.now() - }) -}) + }); +}); router.post('/gas-limit', async (req, res) => { /* @@ -45,33 +45,33 @@ router.post('/gas-limit', async (req, res) => { "maxSwaps":4 } */ - const paramData = getParamData(req.body) + const paramData = getParamData(req.body); try { - const swaps = paramData.maxSwaps + const swaps = paramData.maxSwaps; const maxSwaps = typeof swaps === 'undefined' || parseInt(swaps) === 0 ? balancer.maxSwaps - : parseInt(swaps) - const gasLimit = estimateGasLimit(maxSwaps) + : parseInt(swaps); + const gasLimit = estimateGasLimit(maxSwaps); res.status(200).json({ network: balancer.network, gasLimit, timestamp: Date.now() - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.get('/start', async (req, res) => { /* @@ -81,23 +81,23 @@ router.get('/start', async (req, res) => { "gasPrice":30 } */ - const initTime = Date.now() - const paramData = getParamData(req.query) - const pairs = JSON.parse(paramData.pairs) - let gasPrice + const initTime = Date.now(); + const paramData = getParamData(req.query); + const pairs = JSON.parse(paramData.pairs); + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } // get token contract address and cache pools for (let pair of pairs) { - pair = pair.split('-') - const baseTokenSymbol = pair[0] - const quoteTokenSymbol = pair[1] - const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) + pair = pair.split('-'); + const baseTokenSymbol = pair[0]; + const quoteTokenSymbol = pair[1]; + const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol); // check for valid token symbols if ( @@ -105,12 +105,14 @@ router.get('/start', async (req, res) => { quoteTokenContractInfo === undefined ) { const undefinedToken = - baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol + baseTokenContractInfo === undefined + ? baseTokenSymbol + : quoteTokenSymbol; res.status(500).json({ error: `Token ${undefinedToken} contract address not found`, message: `Token contract address not found for ${undefinedToken}. Check token list source` - }) - return + }); + return; } await Promise.allSettled([ balancer.fetchPool( @@ -121,11 +123,11 @@ router.get('/start', async (req, res) => { quoteTokenContractInfo.address, baseTokenContractInfo.address ) - ]) + ]); } - const gasLimit = estimateGasLimit(balancer.maxSwaps) - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(balancer.maxSwaps); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); const result = { network: eth.network, @@ -136,10 +138,10 @@ router.get('/start', async (req, res) => { gasPrice, gasLimit, gasCost - } - console.log('Initializing balancer') - res.status(200).json(result) -}) + }; + console.log('Initializing balancer'); + res.status(200).json(result); +}); router.post('/price', async (req, res) => { /* @@ -151,23 +153,25 @@ router.post('/price', async (req, res) => { "side":buy } */ - const initTime = Date.now() + const initTime = Date.now(); // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body) - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals - const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals - const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) - const maxSwaps = balancer.maxSwaps - const side = paramData.side.toUpperCase() - let gasPrice + const paramData = getParamData(req.body); + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals; + const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals; + const amount = new BigNumber( + parseInt(paramData.amount * baseDenomMultiplier) + ); + const maxSwaps = balancer.maxSwaps; + const side = paramData.side.toUpperCase(); + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } try { @@ -185,17 +189,18 @@ router.post('/price', async (req, res) => { quoteTokenAddress, // tokenOut is quote asset amount, maxSwaps - ) + ); if (swaps != null && expectedAmount != null) { - const gasLimit = estimateGasLimit(swaps.length) - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(swaps.length); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); - const tradeAmount = parseFloat(amount) + const tradeAmount = parseFloat(amount); const expectedTradeAmount = - parseInt(expectedAmount) / quoteDenomMultiplier + parseInt(expectedAmount) / quoteDenomMultiplier; const tradePrice = - ((expectedAmount / amount) * baseDenomMultiplier) / quoteDenomMultiplier + ((expectedAmount / amount) * baseDenomMultiplier) / + quoteDenomMultiplier; const result = { network: balancer.network, @@ -211,30 +216,30 @@ router.post('/price', async (req, res) => { gasLimit, gasCost, swaps - } + }; debug( `Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH` - ) - res.status(200).json(result) + ); + res.status(200).json(result); } else { // no pool available res.status(200).json({ info: statusMessages.no_pool_available, message: statusMessages.no_pool_available - }) + }); } } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/trade', async (req, res) => { /* @@ -249,31 +254,33 @@ router.post('/trade', async (req, res) => { "privateKey":{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, balancer.provider) + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, balancer.provider); - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals - const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals - const amount = new BigNumber(parseInt(paramData.amount * baseDenomMultiplier)) + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const baseDenomMultiplier = 10 ** baseTokenContractInfo.decimals; + const quoteDenomMultiplier = 10 ** quoteTokenContractInfo.decimals; + const amount = new BigNumber( + parseInt(paramData.amount * baseDenomMultiplier) + ); - const maxSwaps = balancer.maxSwaps - const side = paramData.side.toUpperCase() + const maxSwaps = balancer.maxSwaps; + const side = paramData.side.toUpperCase(); - let limitPrice + let limitPrice; if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice) + limitPrice = parseFloat(paramData.limitPrice); } - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } try { @@ -291,15 +298,16 @@ router.post('/trade', async (req, res) => { quoteTokenAddress, // tokenOut is quote asset amount, maxSwaps - ) + ); - const gasLimit = estimateGasLimit(swaps.length) - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(swaps.length); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); if (side === 'BUY') { const price = - ((expectedAmount / amount) * baseDenomMultiplier) / quoteDenomMultiplier - logger.info(`Price: ${price.toString()}`) + ((expectedAmount / amount) * baseDenomMultiplier) / + quoteDenomMultiplier; + logger.info(`Price: ${price.toString()}`); if (!limitPrice || price <= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await balancer.swapExactOut( @@ -309,7 +317,7 @@ router.post('/trade', async (req, res) => { baseTokenAddress, // tokenOut is base asset expectedAmount.toString(), gasPrice - ) + ); // submit response res.status(200).json({ @@ -325,21 +333,22 @@ router.post('/trade', async (req, res) => { gasLimit, gasCost, txHash: tx.hash - }) + }); } else { res.status(200).json({ error: swapMoreThanMaxPriceError, message: `Swap price ${price} exceeds limitPrice ${limitPrice}` - }) - debug(`Swap price ${price} exceeds limitPrice ${limitPrice}`) + }); + debug(`Swap price ${price} exceeds limitPrice ${limitPrice}`); } } else { // sell - const minAmountOut = (limitPrice / amount) * baseDenomMultiplier - debug('minAmountOut', minAmountOut) + const minAmountOut = (limitPrice / amount) * baseDenomMultiplier; + debug('minAmountOut', minAmountOut); const price = - ((expectedAmount / amount) * baseDenomMultiplier) / quoteDenomMultiplier - logger.info(`Price: ${price.toString()}`) + ((expectedAmount / amount) * baseDenomMultiplier) / + quoteDenomMultiplier; + logger.info(`Price: ${price.toString()}`); if (!limitPrice || price >= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await balancer.swapExactIn( @@ -350,7 +359,7 @@ router.post('/trade', async (req, res) => { amount.toString(), parseInt(expectedAmount) / quoteDenomMultiplier, gasPrice - ) + ); // submit response res.status(200).json({ network: balancer.network, @@ -365,26 +374,26 @@ router.post('/trade', async (req, res) => { gasLimit, gasCost, txHash: tx.hash - }) + }); } else { res.status(200).json({ error: swapLessThanMaxPriceError, message: `Swap price ${price} lower than limitPrice ${limitPrice}` - }) - debug(`Swap price ${price} lower than limitPrice ${limitPrice}`) + }); + debug(`Swap price ${price} lower than limitPrice ${limitPrice}`); } } } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); -export default router +export default router; diff --git a/src/routes/celo.route.js b/src/routes/celo.route.js index 0581c4c..933ff92 100644 --- a/src/routes/celo.route.js +++ b/src/routes/celo.route.js @@ -1,146 +1,146 @@ -const express = require('express') +const express = require('express'); -const router = express.Router() -const BigNumber = require('bignumber.js') -const debug = require('debug')('router') -const spawn = require('child_process').spawn +const router = express.Router(); +const BigNumber = require('bignumber.js'); +const debug = require('debug')('router'); +const spawn = require('child_process').spawn; -const network = 'celo' -const celocli = 'celocli' -const DENOM_UNIT_MULTIPLIER = BigNumber('1e+18') +const network = 'celo'; +const celocli = 'celocli'; +const DENOM_UNIT_MULTIPLIER = BigNumber('1e+18'); -const hbUtils = require('../services/utils') +const hbUtils = require('../services/utils'); -const separator = '=>' +const separator = '=>'; router.use((req, res, next) => { - debug('celo route:', Date.now()) - next() -}) + debug('celo route:', Date.now()); + next(); +}); router.get('/', (req, res) => { - res.status(200).send(network) -}) + res.status(200).send(network); +}); router.get('/status', (req, res) => { /* return if the celocli ultralight node is synced */ - const nodeSync = spawn(celocli, ['node:synced']) + const nodeSync = spawn(celocli, ['node:synced']); - const err_message = [] - const out_message = [] + const err_message = []; + const out_message = []; nodeSync.stdout.on('data', (out) => { - out_message.push(out.toString().trim()) - debug('out_message', out_message) - }) + out_message.push(out.toString().trim()); + debug('out_message', out_message); + }); nodeSync.stderr.on('data', (err) => { - err_message.push(err.toString().trim()) - debug('err_message', err_message) - }) + err_message.push(err.toString().trim()); + debug('err_message', err_message); + }); nodeSync.on('close', (code) => { if (code === 0) { res.status(200).json({ synced: out_message[0].toLowerCase() === 'true', message: err_message.join('') - }) + }); } else { res.status(401).json({ error: err_message.join('') - }) + }); } - }) -}) + }); +}); router.get('/price', (req, res) => { /* api request format: /price?trading_pair=CELO-CUSD&trade_type=sell&amount=1.2345 */ - const keyFormat = ['trading_pair', 'trade_type', 'amount'] + const keyFormat = ['trading_pair', 'trade_type', 'amount']; - const initTime = Date.now() + const initTime = Date.now(); - const paramData = hbUtils.getParamData(req.query, keyFormat) - const tradingPair = paramData.trading_pair - const requestAmount = paramData.amount - const amount = parseFloat(requestAmount) * DENOM_UNIT_MULTIPLIER - debug('params', req.params) - debug('paramData', paramData) + const paramData = hbUtils.getParamData(req.query, keyFormat); + const tradingPair = paramData.trading_pair; + const requestAmount = paramData.amount; + const amount = parseFloat(requestAmount) * DENOM_UNIT_MULTIPLIER; + debug('params', req.params); + debug('paramData', paramData); - const nodeSync = spawn(celocli, ['exchange:show', '--amount', amount]) + const nodeSync = spawn(celocli, ['exchange:show', '--amount', amount]); - const err_message = [] - const out_message = [] + const err_message = []; + const out_message = []; nodeSync.stdout.on('data', (out) => { - out_message.push(out.toString().trim()) - }) + out_message.push(out.toString().trim()); + }); nodeSync.stderr.on('data', (err) => { - err_message.push(err.toString().trim()) - }) + err_message.push(err.toString().trim()); + }); nodeSync.on('close', (code) => { - const exchange_rates = {} - let price + const exchange_rates = {}; + let price; if (code === 0) { // extract exchange rate from cli output out_message.forEach((item, _index) => { if (item.includes(separator)) { - const exchangeInfo = item.split(separator) - const base = exchangeInfo[0].trim().split(' ') - const quote = exchangeInfo[1].trim().split(' ') + const exchangeInfo = item.split(separator); + const base = exchangeInfo[0].trim().split(' '); + const quote = exchangeInfo[1].trim().split(' '); const market = [base[1].toUpperCase(), quote[1].toUpperCase()].join( '-' - ) - exchange_rates[market] = quote[0] / DENOM_UNIT_MULTIPLIER - debug(exchangeInfo, exchange_rates) + ); + exchange_rates[market] = quote[0] / DENOM_UNIT_MULTIPLIER; + debug(exchangeInfo, exchange_rates); } - }) + }); - price = exchange_rates[tradingPair] + price = exchange_rates[tradingPair]; const result = Object.assign(paramData, { price, timestamp: initTime, latency: hbUtils.latency(initTime, Date.now()) - }) - res.status(200).json(result) + }); + res.status(200).json(result); } - }) -}) + }); +}); router.get('/balance', (req, res) => { /* api request format: /balance?address=0x87A4...b120 */ - const keyFormat = ['address'] - const paramData = hbUtils.getParamData(req.query, keyFormat) - const address = paramData.address - debug(paramData) + const keyFormat = ['address']; + const paramData = hbUtils.getParamData(req.query, keyFormat); + const address = paramData.address; + debug(paramData); - const balance = spawn(celocli, ['account:balance', address]) + const balance = spawn(celocli, ['account:balance', address]); - const err_message = [] - const out_message = [] - const walletBalances = {} + const err_message = []; + const out_message = []; + const walletBalances = {}; balance.stdout.on('data', (out) => { - out_message.push(out.toString().trim()) - debug(out_message) - }) + out_message.push(out.toString().trim()); + debug(out_message); + }); balance.stderr.on('data', (err) => { - err_message.push(err.toString().trim()) - debug(err_message) - }) + err_message.push(err.toString().trim()); + debug(err_message); + }); balance.on('close', (code) => { if (code === 0) { @@ -150,28 +150,28 @@ router.get('/balance', (req, res) => { item.toLowerCase().includes('lockedcelo') || item.toLowerCase().includes('lockedgold') ) { - const balanceArray = item.split('\n') + const balanceArray = item.split('\n'); balanceArray.forEach((x) => { - const keyValue = x.split(':') + const keyValue = x.split(':'); walletBalances[keyValue[0].trim()] = - keyValue[1].trim() / DENOM_UNIT_MULTIPLIER - }) - debug('walletBalances', walletBalances) + keyValue[1].trim() / DENOM_UNIT_MULTIPLIER; + }); + debug('walletBalances', walletBalances); } - }) + }); res.status(200).json({ address, balance: walletBalances, timestamp: Date.now() - }) + }); } else { res.status(401).json({ error: err_message - }) + }); } - }) -}) + }); +}); router.post('/unlock', (req, res) => { /* @@ -182,58 +182,58 @@ router.post('/unlock', (req, res) => { "secret": "mysupersecret" } */ - const keyFormat = ['address', 'secret'] - const paramData = hbUtils.getParamData(req.body, keyFormat) - const address = paramData.address - const secret = paramData.secret + const keyFormat = ['address', 'secret']; + const paramData = hbUtils.getParamData(req.body, keyFormat); + const address = paramData.address; + const secret = paramData.secret; - debug(paramData) - debug(req.body) + debug(paramData); + debug(req.body); const lockStatus = spawn(celocli, [ 'account:unlock', address, '--password', secret - ]) + ]); - const err_message = [] - const out_message = [] + const err_message = []; + const out_message = []; lockStatus.stdout.on('data', (out) => { - out_message.push(out.toString().trim()) - debug(out_message) - }) + out_message.push(out.toString().trim()); + debug(out_message); + }); lockStatus.stderr.on('data', (err) => { - err_message.push(err.toString().trim()) - debug(err_message) - }) + err_message.push(err.toString().trim()); + debug(err_message); + }); lockStatus.on('close', (code) => { - let unlocked = false + let unlocked = false; if (code === 0) { if (out_message.length > 0) { out_message.forEach((item, _index) => { if (item.includes(separator)) { - debug('item', item) + debug('item', item); } - }) + }); } else { - unlocked = true + unlocked = true; } res.status(200).json({ unlocked, message: out_message.join(), timestamp: Date.now() - }) + }); } else { res.status(401).json({ error: err_message.join() - }) + }); } - }) -}) + }); +}); router.post('/trade', (req, res) => { /* @@ -246,14 +246,14 @@ router.post('/trade', (req, res) => { "price": 3.512 } */ - const keyFormat = ['trading_pair', 'trade_type', 'amount', 'price'] - const paramData = hbUtils.getParamData(req.body, keyFormat) - debug(paramData) + const keyFormat = ['trading_pair', 'trade_type', 'amount', 'price']; + const paramData = hbUtils.getParamData(req.body, keyFormat); + debug(paramData); // const result = Object.assign(paramData, { // message: 'WIP', // timestamp: Date.now() // }) - res.status(200).json({ status: 'WIP' }) -}) + res.status(200).json({ status: 'WIP' }); +}); -module.exports = router +module.exports = router; diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index 09dac12..9943bca 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -1,22 +1,22 @@ -import { ethers, BigNumber } from 'ethers' -import express from 'express' +import { ethers, BigNumber } from 'ethers'; +import express from 'express'; -import { getParamData, latency, statusMessages } from '../services/utils' -import Ethereum from '../services/eth' -import Fees from '../services/fees' -import { logger } from '../services/logger' +import { getParamData, latency, statusMessages } from '../services/utils'; +import Ethereum from '../services/eth'; +import Fees from '../services/fees'; +import { logger } from '../services/logger'; -const debug = require('debug')('router') +const debug = require('debug')('router'); -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) +const router = express.Router(); +const eth = new Ethereum(process.env.ETHEREUM_CHAIN); const spenders = { balancer: process.env.EXCHANGE_PROXY, uniswap: process.env.UNISWAP_ROUTER, uniswapV3Router: process.env.UNISWAP_V3_ROUTER, uniswapV3NFTManager: process.env.UNISWAP_V3_NFT_MANAGER -} -const fees = new Fees() +}; +const fees = new Fees(); router.post('/', async (req, res) => { /* @@ -27,8 +27,8 @@ router.post('/', async (req, res) => { rpcUrl: eth.provider.connection.url, connection: true, timestamp: Date.now() - }) -}) + }); +}); router.post('/balances', async (req, res) => { /* @@ -38,73 +38,73 @@ router.post('/balances', async (req, res) => { tokenList:{{tokenList}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } // populate token contract info using token symbol list - const tokenContractList = [] - const tokenList = JSON.parse(paramData.tokenList) + const tokenContractList = []; + const tokenList = JSON.parse(paramData.tokenList); tokenList.forEach((symbol) => { - const tokenContractInfo = eth.getERC20TokenAddresses(symbol) - tokenContractList[symbol] = tokenContractInfo - }) + const tokenContractInfo = eth.getERC20TokenAddresses(symbol); + tokenContractList[symbol] = tokenContractInfo; + }); - const balances = {} - balances.ETH = await eth.getETHBalance(wallet, privateKey) + const balances = {}; + balances.ETH = await eth.getETHBalance(wallet, privateKey); try { Promise.all( Object.keys(tokenContractList).map(async (symbol, _index) => { if (tokenContractList[symbol] !== undefined) { - const address = tokenContractList[symbol].address - const decimals = tokenContractList[symbol].decimals + const address = tokenContractList[symbol].address; + const decimals = tokenContractList[symbol].decimals; balances[symbol] = await eth.getERC20Balance( wallet, address, decimals - ) + ); } else { - const err = `Token contract info for ${symbol} not found` - logger.error('Token info not found', { message: err }) - debug(err) + const err = `Token contract info for ${symbol} not found`; + logger.error('Token info not found', { message: err }); + debug(err); } }) ).then(() => { debug('eth.route - Get Account Balance', { message: JSON.stringify(tokenList) - }) + }); res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), balances - }) - }) + }); + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/allowances', async (req, res) => { /* @@ -115,69 +115,69 @@ router.post('/allowances', async (req, res) => { connector:{{connector_name}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const spender = spenders[paramData.connector] - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const spender = spenders[paramData.connector]; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } // populate token contract info using token symbol list - const tokenContractList = [] - const tokenList = JSON.parse(paramData.tokenList) + const tokenContractList = []; + const tokenList = JSON.parse(paramData.tokenList); tokenList.forEach((symbol) => { - const tokenContractInfo = eth.getERC20TokenAddresses(symbol) - tokenContractList[symbol] = tokenContractInfo - }) + const tokenContractInfo = eth.getERC20TokenAddresses(symbol); + tokenContractList[symbol] = tokenContractInfo; + }); - const approvals = {} + const approvals = {}; try { Promise.all( Object.keys(tokenContractList).map(async (symbol, _index) => { - const address = tokenContractList[symbol].address - const decimals = tokenContractList[symbol].decimals + const address = tokenContractList[symbol].address; + const decimals = tokenContractList[symbol].decimals; approvals[symbol] = await eth.getERC20Allowance( wallet, spender, address, decimals - ) + ); }) ).then(() => { logger.info('eth.route - Getting allowances', { message: JSON.stringify(tokenList) - }) + }); res.status(200).json({ network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), spender, approvals - }) - }) + }); + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/balances-2', async (req, res) => { /* @@ -188,32 +188,32 @@ router.post('/balances-2', async (req, res) => { tokenDecimalList:{{tokenDecimalList}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } - let tokenAddressList + let tokenAddressList; if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(',') + tokenAddressList = paramData.tokenAddressList.split(','); } - let tokenDecimalList + let tokenDecimalList; if (paramData.tokenDecimalList) { - tokenDecimalList = paramData.tokenDecimalList.split(',') + tokenDecimalList = paramData.tokenDecimalList.split(','); } - const balances = {} - balances.ETH = await eth.getETHBalance(wallet, privateKey) + const balances = {}; + balances.ETH = await eth.getETHBalance(wallet, privateKey); try { Promise.all( tokenAddressList.map( @@ -230,19 +230,19 @@ router.post('/balances-2', async (req, res) => { timestamp: initTime, latency: latency(initTime, Date.now()), balances - }) - }) + }); + }); } catch (err) { - let reason + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/allowances-2', async (req, res) => { /* @@ -254,32 +254,32 @@ router.post('/allowances-2', async (req, res) => { connector:{{connector_name}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const spender = spenders[paramData.connector] - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const spender = spenders[paramData.connector]; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } - let tokenAddressList + let tokenAddressList; if (paramData.tokenAddressList) { - tokenAddressList = paramData.tokenAddressList.split(',') + tokenAddressList = paramData.tokenAddressList.split(','); } - let tokenDecimalList + let tokenDecimalList; if (paramData.tokenDecimalList) { - tokenDecimalList = paramData.tokenDecimalList.split(',') + tokenDecimalList = paramData.tokenDecimalList.split(','); } - const approvals = {} + const approvals = {}; try { Promise.all( tokenAddressList.map( @@ -298,19 +298,19 @@ router.post('/allowances-2', async (req, res) => { latency: latency(initTime, Date.now()), spender, approvals - }) - }) + }); + }); } catch (err) { - let reason + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/approve', async (req, res) => { /* @@ -323,37 +323,37 @@ router.post('/approve', async (req, res) => { amount:{{amount}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const spender = spenders[paramData.connector] - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const spender = spenders[paramData.connector]; + let wallet; try { - wallet = new ethers.Wallet(privateKey, eth.provider) + wallet = new ethers.Wallet(privateKey, eth.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } - const token = paramData.token - const tokenContractInfo = eth.getERC20TokenAddresses(token) - const tokenAddress = tokenContractInfo.address - const decimals = tokenContractInfo.decimals + const token = paramData.token; + const tokenContractInfo = eth.getERC20TokenAddresses(token); + const tokenAddress = tokenContractInfo.address; + const decimals = tokenContractInfo.decimals; - let amount + let amount; paramData.amount ? (amount = ethers.utils.parseUnits(paramData.amount, decimals)) - : (amount = ethers.constants.MaxUint256) // approve max possible units if no amount specified - let gasPrice + : (amount = ethers.constants.MaxUint256); // approve max possible units if no amount specified + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } try { @@ -364,7 +364,7 @@ router.post('/approve', async (req, res) => { tokenAddress, amount, gasPrice - ) + ); // console.log('eth.route - Approving allowance', { message: approval }) // submit response res.status(200).json({ @@ -375,37 +375,37 @@ router.post('/approve', async (req, res) => { spender, amount: amount / (1e18).toString(), approval - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/poll', async (req, res) => { - const initTime = Date.now() - const paramData = getParamData(req.body) - const txHash = paramData.txHash - const txReceipt = await eth.provider.getTransactionReceipt(txHash) - const receipt = {} - const confirmed = !!(txReceipt && txReceipt.blockNumber) + const initTime = Date.now(); + const paramData = getParamData(req.body); + const txHash = paramData.txHash; + const txReceipt = await eth.provider.getTransactionReceipt(txHash); + const receipt = {}; + const confirmed = !!(txReceipt && txReceipt.blockNumber); if (confirmed) { - receipt.gasUsed = BigNumber.from(txReceipt.gasUsed).toNumber() - receipt.blockNumber = txReceipt.blockNumber - receipt.confirmations = txReceipt.confirmations - receipt.status = txReceipt.status - receipt.logs = txReceipt.logs + receipt.gasUsed = BigNumber.from(txReceipt.gasUsed).toNumber(); + receipt.blockNumber = txReceipt.blockNumber; + receipt.confirmations = txReceipt.confirmations; + receipt.status = txReceipt.status; + receipt.logs = txReceipt.logs; } logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) - }) + }); res.status(200).json({ network: eth.network, timestamp: initTime, @@ -413,9 +413,9 @@ router.post('/poll', async (req, res) => { txHash, confirmed, receipt - }) - return txReceipt -}) + }); + return txReceipt; +}); // Kovan faucet to get test tokens (wip) & weth conversion // router.post('/get-weth', async (req, res) => { @@ -472,4 +472,4 @@ router.post('/poll', async (req, res) => { // } // }) -module.exports = router +module.exports = router; diff --git a/src/routes/index.route.js b/src/routes/index.route.js index 1116b5c..dc02e08 100644 --- a/src/routes/index.route.js +++ b/src/routes/index.route.js @@ -1,8 +1,8 @@ -import { loadConfig } from '../services/utils' +import { loadConfig } from '../services/utils'; -const express = require('express') +const express = require('express'); -const router = express.Router() +const router = express.Router(); router.get('/', (req, res) => { res.status(200).json({ @@ -10,7 +10,7 @@ router.get('/', (req, res) => { image: process.env.IMAGE, config: loadConfig(), status: 'ok' - }) -}) + }); +}); -module.exports = router +module.exports = router; diff --git a/src/routes/perpetual_finance.route.js b/src/routes/perpetual_finance.route.js index 0441a39..e0858bc 100644 --- a/src/routes/perpetual_finance.route.js +++ b/src/routes/perpetual_finance.route.js @@ -1,15 +1,15 @@ -import { ethers } from 'ethers' -import express from 'express' +import { ethers } from 'ethers'; +import express from 'express'; -import { getParamData, latency, statusMessages } from '../services/utils' -import { logger } from '../services/logger' -import PerpetualFinance from '../services/perpetual_finance' +import { getParamData, latency, statusMessages } from '../services/utils'; +import { logger } from '../services/logger'; +import PerpetualFinance from '../services/perpetual_finance'; -require('dotenv').config() +require('dotenv').config(); -const router = express.Router() -const perpFi = new PerpetualFinance(process.env.ETHEREUM_CHAIN) -setTimeout(perpFi.update_price_loop.bind(perpFi), 2000) +const router = express.Router(); +const perpFi = new PerpetualFinance(process.env.ETHEREUM_CHAIN); +setTimeout(perpFi.update_price_loop.bind(perpFi), 2000); router.get('/', async (req, res) => { /* @@ -21,22 +21,22 @@ router.get('/', async (req, res) => { loadedMetadata: perpFi.loadedMetadata, connection: true, timestamp: Date.now() - }) -}) + }); +}); router.get('/load-metadata', async (req, res) => { /* GET / */ - const loadedMetadata = await perpFi.load_metadata() + const loadedMetadata = await perpFi.load_metadata(); res.status(200).json({ network: perpFi.network, provider: perpFi.provider.connection.url, loadedMetadata, connection: true, timestamp: Date.now() - }) -}) + }); +}); router.post('/balances', async (req, res) => { /* @@ -45,43 +45,43 @@ router.post('/balances', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } - const balances = {} - balances.XDAI = await perpFi.getXdaiBalance(wallet) - balances.USDC = await perpFi.getUSDCBalance(wallet) + const balances = {}; + balances.XDAI = await perpFi.getXdaiBalance(wallet); + balances.USDC = await perpFi.getUSDCBalance(wallet); try { res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), balances - }) + }); } catch (err) { - let reason + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/allowances', async (req, res) => { /* @@ -90,42 +90,42 @@ router.post('/allowances', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } - const approvals = {} - approvals.USDC = await perpFi.getAllowance(wallet) + const approvals = {}; + approvals.USDC = await perpFi.getAllowance(wallet); try { res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), approvals - }) + }); } catch (err) { - let reason + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/approve', async (req, res) => { /* @@ -135,29 +135,29 @@ router.post('/approve', async (req, res) => { amount:{{amount}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let amount - paramData.amount ? (amount = paramData.amount) : (amount = '1000000000') - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let amount; + paramData.amount ? (amount = paramData.amount) : (amount = '1000000000'); + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } try { // call approve function - const approval = await perpFi.approve(wallet, amount) - logger.info('perpFi.route - Approving allowance') + const approval = await perpFi.approve(wallet, amount); + logger.info('perpFi.route - Approving allowance'); // submit response res.status(200).json({ network: perpFi.network, @@ -165,19 +165,19 @@ router.post('/approve', async (req, res) => { latency: latency(initTime, Date.now()), amount, approval - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/open', async (req, res) => { /* @@ -191,27 +191,27 @@ router.post('/open', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const side = paramData.side - const pair = paramData.pair - const margin = paramData.margin - const leverage = paramData.leverage - const minBaseAssetAmount = paramData.minBaseAssetAmount - console.log(minBaseAssetAmount) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const side = paramData.side; + const pair = paramData.pair; + const margin = paramData.margin; + const leverage = paramData.leverage; + const minBaseAssetAmount = paramData.minBaseAssetAmount; + console.log(minBaseAssetAmount); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } try { @@ -223,8 +223,8 @@ router.post('/open', async (req, res) => { pair, minBaseAssetAmount, wallet - ) - logger.info('perpFi.route - Opening position') + ); + logger.info('perpFi.route - Opening position'); // submit response res.status(200).json({ network: perpFi.network, @@ -235,19 +235,19 @@ router.post('/open', async (req, res) => { leverage, minBaseAssetAmount, txHash: tx.hash - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/close', async (req, res) => { /* @@ -258,29 +258,29 @@ router.post('/close', async (req, res) => { pair:{{pair}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const minimalQuoteAsset = paramData.minimalQuoteAsset - const privateKey = paramData.privateKey - const pair = paramData.pair - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const minimalQuoteAsset = paramData.minimalQuoteAsset; + const privateKey = paramData.privateKey; + const pair = paramData.pair; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } try { // call closePosition function - const tx = await perpFi.closePosition(wallet, pair, minimalQuoteAsset) - logger.info('perpFi.route - Closing position') + const tx = await perpFi.closePosition(wallet, pair, minimalQuoteAsset); + logger.info('perpFi.route - Closing position'); // submit response res.status(200).json({ network: perpFi.network, @@ -288,19 +288,19 @@ router.post('/close', async (req, res) => { latency: latency(initTime, Date.now()), minimalQuoteAsset, txHash: tx.hash - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/position', async (req, res) => { /* @@ -310,47 +310,47 @@ router.post('/position', async (req, res) => { pair:{{pair}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const pair = paramData.pair - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const pair = paramData.pair; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } try { // call getPosition function - const position = await perpFi.getPosition(wallet, pair) - logger.info('perpFi.route - getting active position') + const position = await perpFi.getPosition(wallet, pair); + logger.info('perpFi.route - getting active position'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), position - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/margin', async (req, res) => { /* @@ -359,46 +359,46 @@ router.post('/margin', async (req, res) => { privateKey:{{privateKey}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - let wallet + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + let wallet; try { - wallet = new ethers.Wallet(privateKey, perpFi.provider) + wallet = new ethers.Wallet(privateKey, perpFi.provider); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - err.reason ? (reason = err.reason) : (reason = 'Error getting wallet') + logger.error(req.originalUrl, { message: err }); + let reason; + err.reason ? (reason = err.reason) : (reason = 'Error getting wallet'); res.status(500).json({ error: reason, message: err - }) - return + }); + return; } try { // call getAllBalances function - const allBalances = await perpFi.getActiveMargin(wallet) - logger.info('perpFi.route - Getting all balances') + const allBalances = await perpFi.getActiveMargin(wallet); + logger.info('perpFi.route - Getting all balances'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), margin: allBalances - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/receipt', async (req, res) => { /* @@ -407,21 +407,21 @@ router.post('/receipt', async (req, res) => { txHash:{{txHash}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const txHash = paramData.txHash - const txReceipt = await perpFi.provider.getTransactionReceipt(txHash) - const receipt = {} - const confirmed = !!(txReceipt && txReceipt.blockNumber) + const initTime = Date.now(); + const paramData = getParamData(req.body); + const txHash = paramData.txHash; + const txReceipt = await perpFi.provider.getTransactionReceipt(txHash); + const receipt = {}; + const confirmed = !!(txReceipt && txReceipt.blockNumber); if (txReceipt !== null) { - receipt.gasUsed = ethers.utils.formatEther(txReceipt.gasUsed) - receipt.blockNumber = txReceipt.blockNumber - receipt.confirmations = txReceipt.confirmations - receipt.status = txReceipt.status + receipt.gasUsed = ethers.utils.formatEther(txReceipt.gasUsed); + receipt.blockNumber = txReceipt.blockNumber; + receipt.confirmations = txReceipt.confirmations; + receipt.status = txReceipt.status; } logger.info(`eth.route - Get TX Receipt: ${txHash}`, { message: JSON.stringify(receipt) - }) + }); res.status(200).json({ network: perpFi.network, timestamp: initTime, @@ -429,9 +429,9 @@ router.post('/receipt', async (req, res) => { txHash, confirmed, receipt - }) - return txReceipt -}) + }); + return txReceipt; +}); router.post('/price', async (req, res) => { /* @@ -442,16 +442,16 @@ router.post('/price', async (req, res) => { amount:{{amount}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const side = paramData.side - const pair = paramData.pair - const amount = paramData.amount + const initTime = Date.now(); + const paramData = getParamData(req.body); + const side = paramData.side; + const pair = paramData.pair; + const amount = paramData.amount; try { // call getPrice function - const price = await perpFi.getPrice(side, amount, pair) - logger.info('perpFi.route - Getting price') + const price = await perpFi.getPrice(side, amount, pair); + logger.info('perpFi.route - Getting price'); // submit response res.status(200).json({ network: perpFi.network, @@ -459,25 +459,25 @@ router.post('/price', async (req, res) => { latency: latency(initTime, Date.now()), side, price - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.get('/pairs', async (req, res) => { /* GET */ - const initTime = Date.now() + const initTime = Date.now(); try { res.status(200).json({ @@ -485,19 +485,19 @@ router.get('/pairs', async (req, res) => { timestamp: initTime, latency: latency(initTime, Date.now()), pairs: Object.keys(perpFi.amm) - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/funding', async (req, res) => { /* @@ -506,32 +506,32 @@ router.post('/funding', async (req, res) => { pair:{{pair}} } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const pair = paramData.pair + const initTime = Date.now(); + const paramData = getParamData(req.body); + const pair = paramData.pair; try { // call getFundingRate function - const fr = await perpFi.getFundingRate(pair) - logger.info('perpFi.route - Getting funding info') + const fr = await perpFi.getFundingRate(pair); + logger.info('perpFi.route - Getting funding info'); // submit response res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), fr - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); -export default router +export default router; diff --git a/src/routes/terra.route.js b/src/routes/terra.route.js index 6f9058f..48cb9be 100644 --- a/src/routes/terra.route.js +++ b/src/routes/terra.route.js @@ -1,20 +1,20 @@ -import express from 'express' +import express from 'express'; import { getParamData, latency, reportConnectionError, statusMessages -} from '../services/utils' -import { logger } from '../services/logger' +} from '../services/utils'; +import { logger } from '../services/logger'; -import Terra from '../services/terra' +import Terra from '../services/terra'; -const router = express.Router() -const terra = new Terra() +const router = express.Router(); +const terra = new Terra(); // constants -const network = terra.lcd.config.chainID -const denomUnitMultiplier = terra.denomUnitMultiplier +const network = terra.lcd.config.chainID; +const denomUnitMultiplier = terra.denomUnitMultiplier; router.post('/', async (req, res) => { /* @@ -27,58 +27,58 @@ router.post('/', async (req, res) => { gasAdjustment: terra.lcd.config.gasAdjustment, connection: true, timestamp: Date.now() - }) -}) + }); +}); router.post('/balances', async (req, res) => { /* POST: address:{{address}} */ - const initTime = Date.now() + const initTime = Date.now(); - const paramData = getParamData(req.body) - const address = paramData.address + const paramData = getParamData(req.body); + const address = paramData.address; - const balances = {} + const balances = {}; try { await terra.lcd.bank.balance(address).then((bal) => { bal.toArray().forEach(async (x) => { - const item = x.toData() - const denom = item.denom - const amount = item.amount / denomUnitMultiplier - const symbol = terra.tokens[denom].symbol - balances[symbol] = amount - }) - }) - logger.info('terra.route - Get Account Balance') + const item = x.toData(); + const denom = item.denom; + const amount = item.amount / denomUnitMultiplier; + const symbol = terra.tokens[denom].symbol; + balances[symbol] = amount; + }); + }); + logger.info('terra.route - Get Account Balance'); res.status(200).json({ network, timestamp: initTime, latency: latency(initTime, Date.now()), balances - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let message - let reason + logger.error(req.originalUrl, { message: err }); + let message; + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) - const isAxiosError = err.isAxiosError + : (reason = statusMessages.operation_error); + const isAxiosError = err.isAxiosError; if (isAxiosError) { - reason = err.response.status - message = err.response.statusText + reason = err.response.status; + message = err.response.statusText; } else { - message = err + message = err; } res.status(500).json({ error: reason, message - }) + }); } -}) +}); router.post('/start', async (req, res) => { /* @@ -89,10 +89,10 @@ router.post('/start', async (req, res) => { "amount":1 } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const baseTokenSymbol = paramData.base - const quoteTokenSymbol = paramData.quote + const initTime = Date.now(); + const paramData = getParamData(req.body); + const baseTokenSymbol = paramData.base; + const quoteTokenSymbol = paramData.quote; const result = { network, @@ -101,9 +101,9 @@ router.post('/start', async (req, res) => { success: true, base: baseTokenSymbol, quote: quoteTokenSymbol - } - res.status(200).json(result) -}) + }; + res.status(200).json(result); +}); router.post('/price', async (req, res) => { /* @@ -115,25 +115,25 @@ router.post('/price', async (req, res) => { "amount":1 } */ - const initTime = Date.now() + const initTime = Date.now(); - const paramData = getParamData(req.body) - const baseToken = paramData.base - const quoteToken = paramData.quote - const tradeType = paramData.side.toUpperCase() - const amount = parseFloat(paramData.amount) + const paramData = getParamData(req.body); + const baseToken = paramData.base; + const quoteToken = paramData.quote; + const tradeType = paramData.side.toUpperCase(); + const amount = parseFloat(paramData.amount); - let exchangeRate + let exchangeRate; try { await terra .getSwapRate(baseToken, quoteToken, amount, tradeType) .then((rate) => { - exchangeRate = rate + exchangeRate = rate; }) .catch((err) => { - reportConnectionError(res, err) - }) + reportConnectionError(res, err); + }); res.status(200).json({ network, @@ -146,27 +146,27 @@ router.post('/price', async (req, res) => { price: exchangeRate.price.amount, cost: exchangeRate.cost.amount, txFee: exchangeRate.txFee.amount - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let message - let reason + logger.error(req.originalUrl, { message: err }); + let message; + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) - const isAxiosError = err.isAxiosError + : (reason = statusMessages.operation_error); + const isAxiosError = err.isAxiosError; if (isAxiosError) { - reason = err.response.status - message = err.response.statusText + reason = err.response.status; + message = err.response.statusText; } else { - message = err + message = err; } res.status(500).json({ error: reason, message - }) + }); } -}) +}); router.post('/trade', async (req, res) => { /* @@ -179,20 +179,20 @@ router.post('/trade', async (req, res) => { "secret": "mysupersecret" } */ - const initTime = Date.now() + const initTime = Date.now(); - const paramData = getParamData(req.body) - const baseToken = paramData.base - const quoteToken = paramData.quote - const tradeType = paramData.side.toUpperCase() - const amount = parseFloat(paramData.amount) + const paramData = getParamData(req.body); + const baseToken = paramData.base; + const quoteToken = paramData.quote; + const tradeType = paramData.side.toUpperCase(); + const amount = parseFloat(paramData.amount); const gasPrice = - parseFloat(paramData.gas_price) || terra.lcd.config.gasPrices.uluna + parseFloat(paramData.gas_price) || terra.lcd.config.gasPrices.uluna; const gasAdjustment = - paramData.gas_adjustment || terra.lcd.config.gasAdjustment - const secret = paramData.privateKey + paramData.gas_adjustment || terra.lcd.config.gasAdjustment; + const secret = paramData.privateKey; - let tokenSwaps + let tokenSwaps; try { await terra @@ -206,11 +206,11 @@ router.post('/trade', async (req, res) => { secret ) .then((swap) => { - tokenSwaps = swap + tokenSwaps = swap; }) .catch((err) => { - reportConnectionError(res, err) - }) + reportConnectionError(res, err); + }); const swapResult = { network, @@ -220,31 +220,31 @@ router.post('/trade', async (req, res) => { tradeType, quote: quoteToken, amount - } - Object.assign(swapResult, tokenSwaps) + }; + Object.assign(swapResult, tokenSwaps); logger.info( `terra.route - ${tradeType}: ${baseToken}-${quoteToken} - Amount: ${amount}` - ) - res.status(200).json(swapResult) + ); + res.status(200).json(swapResult); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let message - let reason + logger.error(req.originalUrl, { message: err }); + let message; + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) - const isAxiosError = err.isAxiosError + : (reason = statusMessages.operation_error); + const isAxiosError = err.isAxiosError; if (isAxiosError) { - reason = err.response.status - message = err.response.statusText + reason = err.response.status; + message = err.response.statusText; } else { - message = err + message = err; } res.status(500).json({ error: reason, message - }) + }); } -}) +}); -module.exports = router +module.exports = router; diff --git a/src/routes/uniswap.route.js b/src/routes/uniswap.route.js index 6201ae0..2803e1c 100644 --- a/src/routes/uniswap.route.js +++ b/src/routes/uniswap.route.js @@ -1,44 +1,44 @@ -import { ethers } from 'ethers' -import express from 'express' +import { ethers } from 'ethers'; +import express from 'express'; -import { getParamData, latency, statusMessages } from '../services/utils' -import { logger } from '../services/logger' -import Ethereum from '../services/eth' -import Uniswap from '../services/uniswap' -import Fees from '../services/fees' +import { getParamData, latency, statusMessages } from '../services/utils'; +import { logger } from '../services/logger'; +import Ethereum from '../services/eth'; +import Uniswap from '../services/uniswap'; +import Fees from '../services/fees'; -require('dotenv').config() +require('dotenv').config(); -const debug = require('debug')('router') +const debug = require('debug')('router'); -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) -const uniswap = new Uniswap(process.env.ETHEREUM_CHAIN) -uniswap.generate_tokens() -setTimeout(uniswap.update_pairs.bind(uniswap), 2000) -const fees = new Fees() +const router = express.Router(); +const eth = new Ethereum(process.env.ETHEREUM_CHAIN); +const uniswap = new Uniswap(process.env.ETHEREUM_CHAIN); +uniswap.generate_tokens(); +setTimeout(uniswap.update_pairs.bind(uniswap), 2000); +const fees = new Fees(); -const swapMoreThanMaxPriceError = 'Price too high' -const swapLessThanMaxPriceError = 'Price too low' +const swapMoreThanMaxPriceError = 'Price too high'; +const swapLessThanMaxPriceError = 'Price too low'; -const estimateGasLimit = () => uniswap.gasLimit +const estimateGasLimit = () => uniswap.gasLimit; const getErrorMessage = (err) => { /* [WIP] Custom error message based-on string match */ - let message = err + let message = err; if (err.includes('failed to meet quorum')) { - message = 'Failed to meet quorum in Uniswap' + message = 'Failed to meet quorum in Uniswap'; } else if (err.includes('Invariant failed: ADDRESSES')) { - message = 'Invariant failed: ADDRESSES' + message = 'Invariant failed: ADDRESSES'; } else if (err.includes('"call revert exception')) { - message = statusMessages.no_pool_available + message = statusMessages.no_pool_available; } else if (err.includes('"trade" is read-only')) { - message = statusMessages.no_pool_available + message = statusMessages.no_pool_available; } - return message -} + return message; +}; router.post('/', async (req, res) => { /* @@ -50,33 +50,33 @@ router.post('/', async (req, res) => { uniswap_router: uniswap.router, connection: true, timestamp: Date.now() - }) -}) + }); +}); router.post('/gas-limit', async (req, res) => { /* POST: /buy-price */ - const gasLimit = estimateGasLimit() + const gasLimit = estimateGasLimit(); try { res.status(200).json({ network: uniswap.network, gasLimit, timestamp: Date.now() - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.get('/start', async (req, res) => { /* @@ -86,23 +86,23 @@ router.get('/start', async (req, res) => { "gasPrice":30 } */ - const initTime = Date.now() - const paramData = getParamData(req.query) - const pairs = JSON.parse(paramData.pairs) - let gasPrice + const initTime = Date.now(); + const paramData = getParamData(req.query); + const pairs = JSON.parse(paramData.pairs); + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } // get token contract address and cache paths for (let pair of pairs) { - pair = pair.split('-') - const baseTokenSymbol = pair[0] - const quoteTokenSymbol = pair[1] - const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol) + pair = pair.split('-'); + const baseTokenSymbol = pair[0]; + const quoteTokenSymbol = pair[1]; + const baseTokenContractInfo = eth.getERC20TokenAddresses(baseTokenSymbol); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(quoteTokenSymbol); // check for valid token symbols if ( @@ -110,23 +110,25 @@ router.get('/start', async (req, res) => { quoteTokenContractInfo === undefined ) { const undefinedToken = - baseTokenContractInfo === undefined ? baseTokenSymbol : quoteTokenSymbol + baseTokenContractInfo === undefined + ? baseTokenSymbol + : quoteTokenSymbol; res.status(500).json({ error: `Token ${undefinedToken} contract address not found`, message: `Token contract address not found for ${undefinedToken}. Check token list source` - }) - return + }); + return; } await Promise.allSettled([ uniswap.extend_update_pairs([ baseTokenContractInfo.address, quoteTokenContractInfo.address ]) - ]) + ]); } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); const result = { network: eth.network, @@ -137,9 +139,9 @@ router.get('/start', async (req, res) => { gasPrice, gasLimit, gasCost - } - res.status(200).json(result) -}) + }; + res.status(200).json(result); +}); router.post('/trade', async (req, res) => { /* @@ -154,31 +156,31 @@ router.post('/trade', async (req, res) => { "side":{buy|sell} } */ - const initTime = Date.now() + const initTime = Date.now(); // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey - const wallet = new ethers.Wallet(privateKey, uniswap.provider) - const amount = paramData.amount + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; + const wallet = new ethers.Wallet(privateKey, uniswap.provider); + const amount = paramData.amount; - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const side = paramData.side.toUpperCase(); - let limitPrice + let limitPrice; if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice) + limitPrice = parseFloat(paramData.limitPrice); } - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { // fetch the optimal pool mix from uniswap @@ -193,11 +195,11 @@ router.post('/trade', async (req, res) => { baseTokenAddress, // tokenIn is base asset quoteTokenAddress, // tokenOut is quote asset amount - ) + ); if (side === 'BUY') { - const price = trade.executionPrice.invert().toSignificant(8) - logger.info(`uniswap.route - Price: ${price.toString()}`) + const price = trade.executionPrice.invert().toSignificant(8); + logger.info(`uniswap.route - Price: ${price.toString()}`); if (!limitPrice || price <= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await uniswap.swapExactOut( @@ -205,7 +207,7 @@ router.post('/trade', async (req, res) => { trade, baseTokenAddress, gasPrice - ) + ); // submit response res.status(200).json({ network: uniswap.network, @@ -220,20 +222,20 @@ router.post('/trade', async (req, res) => { gasLimit, gasCost, txHash: tx.hash - }) + }); } else { res.status(200).json({ error: swapMoreThanMaxPriceError, message: `Swap price ${price} exceeds limitPrice ${limitPrice}` - }) + }); logger.info( `uniswap.route - Swap price ${price} exceeds limitPrice ${limitPrice}` - ) + ); } } else { // sell - const price = trade.executionPrice.toSignificant(8) - logger.info(`Price: ${price.toString()}`) + const price = trade.executionPrice.toSignificant(8); + logger.info(`Price: ${price.toString()}`); if (!limitPrice || price >= limitPrice) { // pass swaps to exchange-proxy to complete trade const tx = await uniswap.swapExactIn( @@ -241,7 +243,7 @@ router.post('/trade', async (req, res) => { trade, baseTokenAddress, gasPrice - ) + ); // submit response res.status(200).json({ network: uniswap.network, @@ -256,29 +258,29 @@ router.post('/trade', async (req, res) => { gasLimit, gasCost, txHash: tx.hash - }) + }); } else { res.status(200).json({ error: swapLessThanMaxPriceError, message: `Swap price ${price} lower than limitPrice ${limitPrice}` - }) + }); logger.info( `uniswap.route - Swap price ${price} lower than limitPrice ${limitPrice}` - ) + ); } } } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/price', async (req, res) => { /* @@ -289,24 +291,24 @@ router.post('/price', async (req, res) => { "amount":1 } */ - const initTime = Date.now() + const initTime = Date.now(); // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body) - const amount = paramData.amount + const paramData = getParamData(req.body); + const amount = paramData.amount; - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() - let gasPrice + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const side = paramData.side.toUpperCase(); + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { // fetch the optimal pool mix from uniswap @@ -321,17 +323,17 @@ router.post('/price', async (req, res) => { baseTokenAddress, // tokenIn is base asset quoteTokenAddress, // tokenOut is quote asset amount - ) + ); if (trade !== null && expectedAmount !== null) { const price = side === 'BUY' ? trade.executionPrice.invert().toSignificant(8) - : trade.executionPrice.toSignificant(8) + : trade.executionPrice.toSignificant(8); - const tradeAmount = parseFloat(amount) - const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)) - const tradePrice = parseFloat(price) + const tradeAmount = parseFloat(amount); + const expectedTradeAmount = parseFloat(expectedAmount.toSignificant(8)); + const tradePrice = parseFloat(price); const result = { network: uniswap.network, @@ -346,44 +348,44 @@ router.post('/price', async (req, res) => { gasLimit, gasCost, trade - } + }; debug( `Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH` - ) - res.status(200).json(result) + ); + res.status(200).json(result); } else { // no pool available res.status(200).json({ info: statusMessages.no_pool_available, message: '' - }) + }); } } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - let errCode = 500 + logger.error(req.originalUrl, { message: err }); + let reason; + let errCode = 500; if (Object.keys(err).includes('isInsufficientReservesError')) { - errCode = 200 - reason = `${statusMessages.insufficient_reserves} in ${side} at Uniswap` + errCode = 200; + reason = `${statusMessages.insufficient_reserves} in ${side} at Uniswap`; } else if (Object.getOwnPropertyNames(err).includes('message')) { - reason = getErrorMessage(err.message) + reason = getErrorMessage(err.message); if (reason === statusMessages.no_pool_available) { - errCode = 200 + errCode = 200; res.status(errCode).json({ info: reason, message: err - }) + }); } } else { err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); } res.status(errCode).json({ error: reason, message: err - }) + }); } -}) +}); -export default router +export default router; diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js index c184f40..9df8e79 100644 --- a/src/routes/uniswap_v3.route.js +++ b/src/routes/uniswap_v3.route.js @@ -1,48 +1,48 @@ -import { ethers } from 'ethers' -import express from 'express' +import { ethers } from 'ethers'; +import express from 'express'; import { getNonceManager, getParamData, latency, statusMessages -} from '../services/utils' +} from '../services/utils'; -import { logger } from '../services/logger' -import Ethereum from '../services/eth' -import UniswapV3 from '../services/uniswap_v3' -import Fees from '../services/fees' +import { logger } from '../services/logger'; +import Ethereum from '../services/eth'; +import UniswapV3 from '../services/uniswap_v3'; +import Fees from '../services/fees'; -require('dotenv').config() +require('dotenv').config(); -const debug = require('debug')('router') +const debug = require('debug')('router'); -const router = express.Router() -const eth = new Ethereum(process.env.ETHEREUM_CHAIN) -const uniswap = new UniswapV3(process.env.ETHEREUM_CHAIN) +const router = express.Router(); +const eth = new Ethereum(process.env.ETHEREUM_CHAIN); +const uniswap = new UniswapV3(process.env.ETHEREUM_CHAIN); -const fees = new Fees() +const fees = new Fees(); // const swapMoreThanMaxPriceError = 'Price too high' // const swapLessThanMaxPriceError = 'Price too low' -const estimateGasLimit = () => uniswap.gasLimit +const estimateGasLimit = () => uniswap.gasLimit; const getErrorMessage = (err) => { /* [WIP] Custom error message based-on string match */ - let message = err + let message = err; if (err.includes('failed to meet quorum')) { - message = 'Failed to meet quorum in Uniswap' + message = 'Failed to meet quorum in Uniswap'; } else if (err.includes('Invariant failed: ADDRESSES')) { - message = 'Invariant failed: ADDRESSES' + message = 'Invariant failed: ADDRESSES'; } else if (err.includes('"call revert exception')) { - message = statusMessages.no_pool_available + message = statusMessages.no_pool_available; } else if (err.includes('"trade" is read-only')) { - message = statusMessages.no_pool_available + message = statusMessages.no_pool_available; } - return message -} + return message; +}; router.post('/', async (req, res) => { /* @@ -54,33 +54,33 @@ router.post('/', async (req, res) => { uniswap_router: uniswap.router, connection: true, timestamp: Date.now() - }) -}) + }); +}); router.post('/gas-limit', async (req, res) => { /* POST: /gas-limit */ - const gasLimit = estimateGasLimit() + const gasLimit = estimateGasLimit(); try { res.status(200).json({ network: uniswap.network, gasLimit, timestamp: Date.now() - }) + }); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/result', async (req, res) => { /* @@ -89,18 +89,18 @@ router.post('/result', async (req, res) => { "logs":"[...]" } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const logs = JSON.parse(paramData.logs) + const initTime = Date.now(); + const paramData = getParamData(req.body); + const logs = JSON.parse(paramData.logs); const result = { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), info: uniswap.abiDecoder.decodeLogs(logs) - } - res.status(200).json(result) -}) + }; + res.status(200).json(result); +}); router.post('/trade', async (req, res) => { /* @@ -116,36 +116,36 @@ router.post('/trade', async (req, res) => { "side":{buy|sell} } */ - const initTime = Date.now() + const initTime = Date.now(); // params: privateKey (required), base (required), quote (required), amount (required), maxPrice (required), gasPrice (required) - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; const wallet = await getNonceManager( new ethers.Wallet(privateKey, uniswap.provider) - ) - const amount = paramData.amount + ); + const amount = paramData.amount; - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address - const side = paramData.side.toUpperCase() - const tier = paramData.tier.toUpperCase() + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; + const side = paramData.side.toUpperCase(); + const tier = paramData.tier.toUpperCase(); - let limitPrice + let limitPrice; if (paramData.limitPrice) { - limitPrice = parseFloat(paramData.limitPrice) + limitPrice = parseFloat(paramData.limitPrice); } else { - limitPrice = 0 + limitPrice = 0; } - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { if (side === 'BUY') { @@ -157,7 +157,7 @@ router.post('/trade', async (req, res) => { limitPrice, tier, gasPrice - ) + ); // submit response res.status(200).json({ network: uniswap.network, @@ -172,7 +172,7 @@ router.post('/trade', async (req, res) => { gasLimit, gasCost, txHash: tx.hash - }) + }); } else { // sell const tx = await uniswap.swapExactIn( @@ -183,7 +183,7 @@ router.post('/trade', async (req, res) => { limitPrice, tier, gasPrice - ) + ); // submit response res.status(200).json({ @@ -199,20 +199,20 @@ router.post('/trade', async (req, res) => { gasLimit, gasCost, txHash: tx.hash - }) + }); } } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason + logger.error(req.originalUrl, { message: err }); + let reason; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(500).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/price', async (req, res) => { /* @@ -222,27 +222,27 @@ router.post('/price', async (req, res) => { "base":"DAI" } */ - const initTime = Date.now() + const initTime = Date.now(); // params: base (required), quote (required), amount (required) - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; const wallet = await getNonceManager( new ethers.Wallet(privateKey, uniswap.provider) - ) + ); - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote) - const baseTokenAddress = baseTokenContractInfo.address - const quoteTokenAddress = quoteTokenContractInfo.address + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.base); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.quote); + const baseTokenAddress = baseTokenContractInfo.address; + const quoteTokenAddress = quoteTokenContractInfo.address; - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { // fetch pools for all tiers @@ -250,7 +250,7 @@ router.post('/price', async (req, res) => { wallet, baseTokenAddress, quoteTokenAddress - ) + ); const result = { network: uniswap.network, @@ -262,42 +262,42 @@ router.post('/price', async (req, res) => { gasPrice, gasLimit, gasCost - } + }; debug( `Mid Price ${baseTokenContractInfo.symbol}-${ quoteTokenContractInfo.symbol } | (rate:${JSON.stringify( prices )}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH` - ) - res.status(200).json(result) + ); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - let errCode = 500 + logger.error(req.originalUrl, { message: err }); + let reason; + let errCode = 500; if (Object.keys(err).includes('isInsufficientReservesError')) { - errCode = 200 - reason = `${statusMessages.insufficient_reserves} at Uniswap` + errCode = 200; + reason = `${statusMessages.insufficient_reserves} at Uniswap`; } else if (Object.getOwnPropertyNames(err).includes('message')) { - reason = getErrorMessage(err.message) + reason = getErrorMessage(err.message); if (reason === statusMessages.no_pool_available) { - errCode = 200 + errCode = 200; res.status(errCode).json({ info: reason, message: err - }) + }); } } else { err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); } res.status(errCode).json({ error: reason, message: err - }) + }); } -}) +}); // LP section @@ -308,34 +308,34 @@ router.post('/position', async (req, res) => { "tokenId":"tokenId" } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; const wallet = await getNonceManager( new ethers.Wallet(privateKey, uniswap.provider) - ) - const tokenId = paramData.tokenId + ); + const tokenId = paramData.tokenId; try { // fetch position data - const positionData = await uniswap.getPosition(wallet, tokenId) + const positionData = await uniswap.getPosition(wallet, tokenId); const result = { network: uniswap.network, timestamp: initTime, latency: latency(initTime, Date.now()), position: positionData - } - debug(`Position data: ${positionData} `) - res.status(200).json(result) + }; + debug(`Position data: ${positionData} `); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) + logger.error(req.originalUrl, { message: err }); res.status(500).json({ info: statusMessages.operation_error, position: {} - }) + }); } -}) +}); router.post('/add-position', async (req, res) => { /* @@ -350,29 +350,29 @@ router.post('/add-position', async (req, res) => { "amount1": amount1 } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; const wallet = await getNonceManager( new ethers.Wallet(privateKey, uniswap.provider) - ) + ); - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1) - const fee = paramData.fee - const lowerPrice = parseFloat(paramData.lowerPrice) - const upperPrice = parseFloat(paramData.upperPrice) - const amount0 = paramData.amount0 - const amount1 = paramData.amount1 + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1); + const fee = paramData.fee; + const lowerPrice = parseFloat(paramData.lowerPrice); + const upperPrice = parseFloat(paramData.upperPrice); + const amount0 = paramData.amount0; + const amount1 = paramData.amount1; - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { // add position to pool @@ -385,7 +385,7 @@ router.post('/add-position', async (req, res) => { fee, lowerPrice, upperPrice - ) + ); const result = { network: uniswap.network, @@ -402,17 +402,17 @@ router.post('/add-position', async (req, res) => { gasPrice, gasLimit, gasCost - } - debug(`New Position: ${newPosition.hash}`) - res.status(200).json(result) + }; + debug(`New Position: ${newPosition.hash}`); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) + logger.error(req.originalUrl, { message: err }); res.status(200).json({ info: statusMessages.operation_error, message: err - }) + }); } -}) +}); router.post('/remove-position', async (req, res) => { /* @@ -421,25 +421,25 @@ router.post('/remove-position', async (req, res) => { "tokenId":"12" } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; const wallet = await getNonceManager( new ethers.Wallet(privateKey, uniswap.provider) - ) - const tokenId = paramData.tokenId + ); + const tokenId = paramData.tokenId; - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { - const removelp = await uniswap.removePosition(wallet, tokenId) + const removelp = await uniswap.removePosition(wallet, tokenId); const result = { network: uniswap.network, @@ -449,22 +449,22 @@ router.post('/remove-position', async (req, res) => { gasPrice, gasLimit, gasCost - } - debug(`Remove lp: ${removelp.hash}`) - res.status(200).json(result) + }; + debug(`Remove lp: ${removelp.hash}`); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) - let reason - const errCode = 500 + logger.error(req.originalUrl, { message: err }); + let reason; + const errCode = 500; err.reason ? (reason = err.reason) - : (reason = statusMessages.operation_error) + : (reason = statusMessages.operation_error); res.status(errCode).json({ error: reason, message: err - }) + }); } -}) +}); router.post('/replace-position', async (req, res) => { /* @@ -480,29 +480,29 @@ router.post('/replace-position', async (req, res) => { "amount1": amount1 } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; const wallet = await getNonceManager( new ethers.Wallet(privateKey, uniswap.provider) - ) - const tokenId = paramData.tokenId - const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0) - const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1) - const fee = paramData.fee - const lowerPrice = parseFloat(paramData.lowerPrice) - const upperPrice = parseFloat(paramData.upperPrice) - const amount0 = paramData.amount0 - const amount1 = paramData.amount1 - - let gasPrice + ); + const tokenId = paramData.tokenId; + const baseTokenContractInfo = eth.getERC20TokenAddresses(paramData.token0); + const quoteTokenContractInfo = eth.getERC20TokenAddresses(paramData.token1); + const fee = paramData.fee; + const lowerPrice = parseFloat(paramData.lowerPrice); + const upperPrice = parseFloat(paramData.upperPrice); + const amount0 = paramData.amount0; + const amount1 = paramData.amount1; + + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { // const position = await uniswap.getPosition(wallet, tokenId) @@ -518,7 +518,7 @@ router.post('/replace-position', async (req, res) => { fee, lowerPrice, upperPrice - ) + ); const result = { network: uniswap.network, @@ -531,17 +531,17 @@ router.post('/replace-position', async (req, res) => { gasPrice, gasLimit, gasCost - } - debug(`Position change ${positionChange.hash}`) - res.status(200).json(result) + }; + debug(`Position change ${positionChange.hash}`); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) + logger.error(req.originalUrl, { message: err }); res.status(200).json({ info: statusMessages.operation_error, message: err - }) + }); } -}) +}); router.post('/collect-fees', async (req, res) => { /* @@ -552,26 +552,26 @@ router.post('/collect-fees', async (req, res) => { "amount1": amount1 } */ - const initTime = Date.now() - const paramData = getParamData(req.body) - const privateKey = paramData.privateKey + const initTime = Date.now(); + const paramData = getParamData(req.body); + const privateKey = paramData.privateKey; const wallet = await getNonceManager( new ethers.Wallet(privateKey, uniswap.provider) - ) - const tokenId = paramData.tokenId + ); + const tokenId = paramData.tokenId; - let gasPrice + let gasPrice; if (paramData.gasPrice) { - gasPrice = parseFloat(paramData.gasPrice) + gasPrice = parseFloat(paramData.gasPrice); } else { - gasPrice = fees.ethGasPrice + gasPrice = fees.ethGasPrice; } - const gasLimit = estimateGasLimit() - const gasCost = await fees.getGasCost(gasPrice, gasLimit) + const gasLimit = estimateGasLimit(); + const gasCost = await fees.getGasCost(gasPrice, gasLimit); try { // withdraw fees - const collect = await uniswap.collectFees(wallet, tokenId) + const collect = await uniswap.collectFees(wallet, tokenId); const result = { network: uniswap.network, @@ -582,16 +582,16 @@ router.post('/collect-fees', async (req, res) => { gasPrice, gasLimit, gasCost - } - debug(`Fees: ${collect.hash}`) - res.status(200).json(result) + }; + debug(`Fees: ${collect.hash}`); + res.status(200).json(result); } catch (err) { - logger.error(req.originalUrl, { message: err }) + logger.error(req.originalUrl, { message: err }); res.status(200).json({ info: statusMessages.operation_error, message: err - }) + }); } -}) +}); -export default router +export default router; diff --git a/src/services/access.js b/src/services/access.js index d917e80..cf374b9 100644 --- a/src/services/access.js +++ b/src/services/access.js @@ -2,23 +2,23 @@ middleware for validating mutual authentication access */ -import { logger } from './logger' -import { statusMessages } from './utils' +import { logger } from './logger'; +import { statusMessages } from './utils'; export const validateAccess = (req, res, next) => { - const cert = req.connection.getPeerCertificate() + const cert = req.connection.getPeerCertificate(); if (req.client.authorized) { - const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress - const method = req.method - const url = req.url - const requestInfo = `Request from IP: ${ip} ${method} ${url}` - console.log(requestInfo) - next() + const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; + const method = req.method; + const url = req.url; + const requestInfo = `Request from IP: ${ip} ${method} ${url}`; + console.log(requestInfo); + next(); } else if (cert.subject) { - logger.error(statusMessages.ssl_cert_invalid) - res.status(403).send({ error: statusMessages.ssl_cert_invalid }) + logger.error(statusMessages.ssl_cert_invalid); + res.status(403).send({ error: statusMessages.ssl_cert_invalid }); } else { - logger.error(statusMessages.ssl_cert_required) - res.status(401).send({ error: statusMessages.ssl_cert_required }) + logger.error(statusMessages.ssl_cert_required); + res.status(401).send({ error: statusMessages.ssl_cert_required }); } -} +}; diff --git a/src/services/balancer.js b/src/services/balancer.js index aa3715c..c846e90 100644 --- a/src/services/balancer.js +++ b/src/services/balancer.js @@ -1,66 +1,67 @@ -import { logger } from './logger' +import { logger } from './logger'; -const debug = require('debug')('router') -require('dotenv').config() // DO NOT REMOVE. needed to configure REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor -const sor = require('@balancer-labs/sor') -const BigNumber = require('bignumber.js') -const ethers = require('ethers') -const proxyArtifact = require('../static/ExchangeProxy.json') +const debug = require('debug')('router'); +require('dotenv').config(); // DO NOT REMOVE. needed to configure REACT_APP_SUBGRAPH_URL used by @balancer-labs/sor +const sor = require('@balancer-labs/sor'); +const BigNumber = require('bignumber.js'); +const ethers = require('ethers'); +const proxyArtifact = require('../static/ExchangeProxy.json'); // constants -const MULTI = '0xeefba1e63905ef1d7acba5a8513c70307c1ce441' -const MULTI_KOVAN = ' 0x2cc8688C5f75E365aaEEb4ea8D6a480405A48D2A' -const MAX_UINT = ethers.constants.MaxUint256 -const GAS_BASE = process.env.BALANCER_GAS_BASE || 200688 -const GAS_PER_SWAP = process.env.BALANCER_GAS_PER_SWAP || 100000 +const MULTI = '0xeefba1e63905ef1d7acba5a8513c70307c1ce441'; +const MULTI_KOVAN = ' 0x2cc8688C5f75E365aaEEb4ea8D6a480405A48D2A'; +const MAX_UINT = ethers.constants.MaxUint256; +const GAS_BASE = process.env.BALANCER_GAS_BASE || 200688; +const GAS_PER_SWAP = process.env.BALANCER_GAS_PER_SWAP || 100000; export default class Balancer { constructor(network = 'kovan') { - const providerUrl = process.env.ETHEREUM_RPC_URL - this.network = process.env.ETHEREUM_CHAIN - this.provider = new ethers.providers.JsonRpcProvider(providerUrl) - this.subgraphUrl = process.env.REACT_APP_SUBGRAPH_URL - this.gasBase = GAS_BASE - this.gasPerSwap = GAS_PER_SWAP - this.maxSwaps = process.env.BALANCER_MAX_SWAPS || 4 - this.exchangeProxy = process.env.EXCHANGE_PROXY - this.cachedPools = [] + const providerUrl = process.env.ETHEREUM_RPC_URL; + this.network = process.env.ETHEREUM_CHAIN; + this.provider = new ethers.providers.JsonRpcProvider(providerUrl); + this.subgraphUrl = process.env.REACT_APP_SUBGRAPH_URL; + this.gasBase = GAS_BASE; + this.gasPerSwap = GAS_PER_SWAP; + this.maxSwaps = process.env.BALANCER_MAX_SWAPS || 4; + this.exchangeProxy = process.env.EXCHANGE_PROXY; + this.cachedPools = []; switch (network) { case 'mainnet': - this.multiCall = MULTI - break + this.multiCall = MULTI; + break; case 'kovan': - this.multiCall = MULTI_KOVAN - break - default: - const err = `Invalid network ${network}` - logger.error(err) - throw Error(err) + this.multiCall = MULTI_KOVAN; + break; + default: { + const err = `Invalid network ${network}`; + logger.error(err); + throw Error(err); + } } } async fetchPool(tokenIn, tokenOut) { - const pools = await sor.getPoolsWithTokens(tokenIn, tokenOut) - this.cachedPools[tokenIn + tokenOut] = pools + const pools = await sor.getPoolsWithTokens(tokenIn, tokenOut); + this.cachedPools[tokenIn + tokenOut] = pools; if (pools.pools.length === 0) { debug('>>> No pools contain the tokens provided.', { message: this.network - }) - return {} + }); + return {}; } debug(`>>> ${pools.pools.length} Pools Retrieved.`, { message: this.network - }) + }); } async getCachedPools(tokenIn, tokenOut) { - const cachePools = this.cachedPools[tokenIn + tokenOut].pools + const cachePools = this.cachedPools[tokenIn + tokenOut].pools; debug(`>>> get cached Pools. ${tokenIn + tokenOut}`, { message: `total pools: ${cachePools.length}` - }) - return cachePools + }); + return cachePools; } async priceSwapIn( @@ -72,10 +73,10 @@ export default class Balancer { // Fetch all the pools that contain the tokens provided try { // Get current on-chain data about the fetched pools - await this.fetchPool(tokenIn, tokenOut) + await this.fetchPool(tokenIn, tokenOut); - let poolData - const cachedPools = await this.getCachedPools(tokenIn, tokenOut) + let poolData; + const cachedPools = await this.getCachedPools(tokenIn, tokenOut); if (this.network === 'mainnet') { poolData = await sor.parsePoolDataOnChain( cachedPools, @@ -83,10 +84,10 @@ export default class Balancer { tokenOut, this.multiCall, this.provider - ) + ); } else { // Kovan multicall throws an ENS error - poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) + poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut); } // Parse the pools and pass them to smart order outer to get the swaps needed @@ -96,14 +97,18 @@ export default class Balancer { tokenInAmount, // targetInputAmount: BigNumber new BigNumber(maxSwaps.toString()), // maxBalancers: number 0 // costOutputToken: BigNumber - ) + ); - const swapsFormatted = sor.formatSwapsExactAmountIn(sorSwaps, MAX_UINT, 0) - const expectedAmount = sor.calcTotalOutput(swapsFormatted, poolData) - debug(`Expected Out: ${expectedAmount.toString()} (${tokenOut})`) + const swapsFormatted = sor.formatSwapsExactAmountIn( + sorSwaps, + MAX_UINT, + 0 + ); + const expectedAmount = sor.calcTotalOutput(swapsFormatted, poolData); + debug(`Expected Out: ${expectedAmount.toString()} (${tokenOut})`); // Create correct swap format for new proxy - const swaps = [] + const swaps = []; for (let i = 0; i < swapsFormatted.length; i++) { const swap = { pool: swapsFormatted[i].pool, @@ -112,15 +117,15 @@ export default class Balancer { swapAmount: swapsFormatted[i].tokenInParam, limitReturnAmount: swapsFormatted[i].tokenOutParam, maxPrice: swapsFormatted[i].maxPrice.toString() - } - swaps.push(swap) + }; + swaps.push(swap); } - return { swaps, expectedAmount } + return { swaps, expectedAmount }; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error in swapExactOut') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error in swapExactOut'); + return reason; } } @@ -133,10 +138,10 @@ export default class Balancer { // Fetch all the pools that contain the tokens provided try { // Get current on-chain data about the fetched pools - await this.fetchPool(tokenIn, tokenOut) + await this.fetchPool(tokenIn, tokenOut); - let poolData - const cachedPools = await this.getCachedPools(tokenIn, tokenOut) + let poolData; + const cachedPools = await this.getCachedPools(tokenIn, tokenOut); if (this.network === 'mainnet') { poolData = await sor.parsePoolDataOnChain( cachedPools, @@ -144,10 +149,10 @@ export default class Balancer { tokenOut, this.multiCall, this.provider - ) + ); } else { // Kovan multicall throws an ENS error - poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut) + poolData = await sor.parsePoolData(cachedPools, tokenIn, tokenOut); } // Parse the pools and pass them to smart order outer to get the swaps needed @@ -157,17 +162,17 @@ export default class Balancer { tokenOutAmount, // targetInputAmount: BigNumber new BigNumber(maxSwaps.toString()), // maxBalancers: number 0 // costOutputToken: BigNumber - ) + ); const swapsFormatted = sor.formatSwapsExactAmountOut( sorSwaps, MAX_UINT, MAX_UINT - ) - const expectedAmount = sor.calcTotalInput(swapsFormatted, poolData) - debug(`Expected In: ${expectedAmount.toString()} (${tokenIn})`) + ); + const expectedAmount = sor.calcTotalInput(swapsFormatted, poolData); + debug(`Expected In: ${expectedAmount.toString()} (${tokenIn})`); // Create correct swap format for new proxy - const swaps = [] + const swaps = []; for (let i = 0; i < swapsFormatted.length; i++) { const swap = { pool: swapsFormatted[i].pool, @@ -176,15 +181,15 @@ export default class Balancer { swapAmount: swapsFormatted[i].tokenOutParam, limitReturnAmount: swapsFormatted[i].tokenInParam, maxPrice: swapsFormatted[i].maxPrice.toString() - } - swaps.push(swap) + }; + swaps.push(swap); } - return { swaps, expectedAmount } + return { swaps, expectedAmount }; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error in swapExactOut') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error in swapExactOut'); + return reason; } } @@ -197,13 +202,13 @@ export default class Balancer { minAmountOut, gasPrice ) { - debug(`Number of swaps: ${swaps.length}`) + debug(`Number of swaps: ${swaps.length}`); try { const contract = new ethers.Contract( this.exchangeProxy, proxyArtifact.abi, wallet - ) + ); const tx = await contract.batchSwapExactIn( swaps, tokenIn, @@ -214,25 +219,25 @@ export default class Balancer { gasPrice: gasPrice * 1e9, gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP } - ) - debug(`Tx Hash: ${tx.hash}`) - return tx + ); + debug(`Tx Hash: ${tx.hash}`); + return tx; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error in swapExactIn') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error in swapExactIn'); + return reason; } } async swapExactOut(wallet, swaps, tokenIn, tokenOut, expectedIn, gasPrice) { - debug(`Number of swaps: ${swaps.length}`) + debug(`Number of swaps: ${swaps.length}`); try { const contract = new ethers.Contract( this.exchangeProxy, proxyArtifact.abi, wallet - ) + ); const tx = await contract.batchSwapExactOut( swaps, tokenIn, @@ -242,14 +247,14 @@ export default class Balancer { gasPrice: gasPrice * 1e9, gasLimit: GAS_BASE + swaps.length * GAS_PER_SWAP } - ) - debug(`Tx Hash: ${tx.hash}`) - return tx + ); + debug(`Tx Hash: ${tx.hash}`); + return tx; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error in swapExactOut') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error in swapExactOut'); + return reason; } } } diff --git a/src/services/eth.js b/src/services/eth.js index 68d2ae9..13d292b 100644 --- a/src/services/eth.js +++ b/src/services/eth.js @@ -1,35 +1,37 @@ -import axios from 'axios' -import { logger } from './logger' +import axios from 'axios'; +import { logger } from './logger'; -require('dotenv').config() -const fs = require('fs') -const ethers = require('ethers') -const abi = require('../static/abi') +require('dotenv').config(); +const fs = require('fs'); +const ethers = require('ethers'); +const abi = require('../static/abi'); // constants -const APPROVAL_GAS_LIMIT = process.env.ETH_APPROVAL_GAS_LIMIT || 50000 +const APPROVAL_GAS_LIMIT = process.env.ETH_APPROVAL_GAS_LIMIT || 50000; export default class Ethereum { constructor(network = 'mainnet') { // network defaults to kovan - const providerUrl = process.env.ETHEREUM_RPC_URL - this.provider = new ethers.providers.JsonRpcProvider(providerUrl) - this.erc20TokenListURL = process.env.ETHEREUM_TOKEN_LIST_URL - this.network = network + const providerUrl = process.env.ETHEREUM_RPC_URL; + this.provider = new ethers.providers.JsonRpcProvider(providerUrl); + this.erc20TokenListURL = process.env.ETHEREUM_TOKEN_LIST_URL; + this.network = network; // update token list - this.getERC20TokenList() // erc20TokenList + this.getERC20TokenList(); // erc20TokenList } // get ETH balance async getETHBalance(wallet) { try { - const balance = await wallet.getBalance() - return balance / (1e18).toString() + const balance = await wallet.getBalance(); + return balance / (1e18).toString(); } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error ETH balance lookup') - return reason + logger.error(err); + let reason; + err.reason + ? (reason = err.reason) + : (reason = 'error ETH balance lookup'); + return reason; } } @@ -40,15 +42,15 @@ export default class Ethereum { tokenAddress, abi.ERC20Abi, this.provider - ) + ); try { - const balance = await contract.balanceOf(wallet.address) - return balance / (10 ** decimals).toString() + const balance = await contract.balanceOf(wallet.address); + return balance / (10 ** decimals).toString(); } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error balance lookup') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error balance lookup'); + return reason; } } @@ -59,15 +61,15 @@ export default class Ethereum { tokenAddress, abi.ERC20Abi, this.provider - ) + ); try { - const allowance = await contract.allowance(wallet.address, spender) - return allowance / (10 ** decimals).toString() + const allowance = await contract.allowance(wallet.address, spender); + return allowance / (10 ** decimals).toString(); } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error allowance lookup') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error allowance lookup'); + return reason; } } @@ -82,18 +84,18 @@ export default class Ethereum { ) { try { // fixate gas limit to prevent overwriting - const approvalGasLimit = APPROVAL_GAS_LIMIT + const approvalGasLimit = APPROVAL_GAS_LIMIT; // instantiate a contract and pass in wallet, which act on behalf of that signer - const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, wallet) + const contract = new ethers.Contract(tokenAddress, abi.ERC20Abi, wallet); return await contract.approve(spender, amount, { gasPrice: gasPrice * 1e9, gasLimit: approvalGasLimit - }) + }); } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error approval') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error approval'); + return reason; } } @@ -102,14 +104,14 @@ export default class Ethereum { try { this.provider.getGasPrice().then((gas) => { // gasPrice is a BigNumber; convert it to a decimal string - const gasPrice = gas.toString() - return gasPrice - }) + const gasPrice = gas.toString(); + return gasPrice; + }); } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error gas lookup') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error gas lookup'); + return reason; } } @@ -126,59 +128,59 @@ export default class Ethereum { tokenAddress, abi.KovanWETHAbi, wallet - ) + ); return await contract.deposit({ value: amount, gasPrice: gasPrice * 1e9, gasLimit - }) + }); } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error deposit') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error deposit'); + return reason; } } // get ERC20 Token List async getERC20TokenList() { - let tokenListSource + let tokenListSource; try { if (this.network === 'kovan') { - tokenListSource = 'src/static/erc20_tokens_kovan.json' - this.erc20TokenList = JSON.parse(fs.readFileSync(tokenListSource)) + tokenListSource = 'src/static/erc20_tokens_kovan.json'; + this.erc20TokenList = JSON.parse(fs.readFileSync(tokenListSource)); } else if (this.network === 'mainnet') { - tokenListSource = this.erc20TokenListURL + tokenListSource = this.erc20TokenListURL; if (tokenListSource === undefined || tokenListSource === null) { - const errMessage = 'Token List source not found' - logger.error('ERC20 Token List Error', { message: errMessage }) - console.log('eth - Error: ', errMessage) + const errMessage = 'Token List source not found'; + logger.error('ERC20 Token List Error', { message: errMessage }); + console.log('eth - Error: ', errMessage); } if ( this.erc20TokenList === undefined || this.erc20TokenList === null || this.erc20TokenList === {} ) { - const response = await axios.get(tokenListSource) + const response = await axios.get(tokenListSource); if (response.status === 200 && response.data) { - this.erc20TokenList = response.data + this.erc20TokenList = response.data; } } } else { - throw Error(`Invalid network ${this.network}`) + throw Error(`Invalid network ${this.network}`); } console.log( 'get ERC20 Token List', this.network, 'source', tokenListSource - ) + ); } catch (err) { - console.log(err) - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error ERC 20 Token List') - return reason + console.log(err); + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error ERC 20 Token List'); + return reason; } } @@ -186,14 +188,14 @@ export default class Ethereum { getERC20TokenAddresses(tokenSymbol) { const tokenContractAddress = this.erc20TokenList.tokens.filter( (obj) => obj.symbol === tokenSymbol.toUpperCase() - ) - return tokenContractAddress[0] + ); + return tokenContractAddress[0]; } getERC20TokenByAddress(tokenAddress) { const tokenContract = this.erc20TokenList.tokens.filter( (obj) => obj.address.toUpperCase() === tokenAddress.toUpperCase() - ) - return tokenContract[0] + ); + return tokenContract[0]; } } diff --git a/src/services/fees.js b/src/services/fees.js index 4a3ab6e..3f7ab37 100644 --- a/src/services/fees.js +++ b/src/services/fees.js @@ -1,25 +1,25 @@ -import axios from 'axios' -import BigNumber from 'bignumber.js' -import { logger } from './logger' +import axios from 'axios'; +import BigNumber from 'bignumber.js'; +import { logger } from './logger'; -require('dotenv').config() +require('dotenv').config(); // constants -const ethGasStationHost = 'https://ethgasstation.info' -const ethGasStationEnabled = process.env.ENABLE_ETH_GAS_STATION || false -const ethGasStationApiKey = process.env.ETH_GAS_STATION_API_KEY -const ethManualGasPrice = parseInt(process.env.MANUAL_GAS_PRICE) -const ethGasStationURL = `${ethGasStationHost}/api/ethgasAPI.json?api-key=${ethGasStationApiKey}` -const defaultRefreshInterval = 120 -const denom = BigNumber('1e+9') +const ethGasStationHost = 'https://ethgasstation.info'; +const ethGasStationEnabled = process.env.ENABLE_ETH_GAS_STATION || false; +const ethGasStationApiKey = process.env.ETH_GAS_STATION_API_KEY; +const ethManualGasPrice = parseInt(process.env.MANUAL_GAS_PRICE); +const ethGasStationURL = `${ethGasStationHost}/api/ethgasAPI.json?api-key=${ethGasStationApiKey}`; +const defaultRefreshInterval = 120; +const denom = BigNumber('1e+9'); export default class Fees { constructor() { - this.ethGasStationGasLevel = process.env.ETH_GAS_STATION_GAS_LEVEL + this.ethGasStationGasLevel = process.env.ETH_GAS_STATION_GAS_LEVEL; this.ethGasStationRefreshTime = (process.env.ETH_GAS_STATION_REFRESH_TIME || defaultRefreshInterval) * - 1000 - this.getETHGasStationFee(this.ethGasStationGasLevel, 0) + 1000; + this.getETHGasStationFee(this.ethGasStationGasLevel, 0); } // get ETH Gas Station @@ -32,41 +32,43 @@ export default class Fees { ethGasStationEnabled === true || ethGasStationEnabled.toLowerCase() === 'true' ) { - const response = await axios.get(ethGasStationURL) + const response = await axios.get(ethGasStationURL); // divite by 10 to convert it to Gwei) - this.ethGasPrice = response.data[gasLevel] / 10 + this.ethGasPrice = response.data[gasLevel] / 10; console.log( `get ETHGasStation gas price (${gasLevel}): ${ this.ethGasPrice } / interval: ${this.ethGasStationRefreshTime / 1000} sec` - ) + ); } else { - this.ethGasPrice = ethManualGasPrice + this.ethGasPrice = ethManualGasPrice; console.log( `get manual fixed gas price: ${this.ethGasPrice} / interval: ${ this.ethGasStationRefreshTime / 1000 } sec` - ) + ); } } catch (err) { - console.log(err) - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error ETH gas fee lookup') - return reason + console.log(err); + logger.error(err); + let reason; + err.reason + ? (reason = err.reason) + : (reason = 'error ETH gas fee lookup'); + return reason; } if (interval > 0) { // set to '0' for one-time retrieval setTimeout( this.getETHGasStationFee.bind(this), this.ethGasStationRefreshTime - ) // update every x seconds + ); // update every x seconds } } // get gas cost async getGasCost(gasPrice, gasLimit, inGwei = false) { - const cost = gasPrice * gasLimit - return inGwei ? cost : cost / denom + const cost = gasPrice * gasLimit; + return inGwei ? cost : cost / denom; } } diff --git a/src/services/logger.js b/src/services/logger.js index 774e0af..c7c6c56 100644 --- a/src/services/logger.js +++ b/src/services/logger.js @@ -1,26 +1,26 @@ -import { getLocalDate } from './utils' +import { getLocalDate } from './utils'; -require('dotenv').config() -const appRoot = require('app-root-path') -const winston = require('winston') -require('winston-daily-rotate-file') +require('dotenv').config(); +const appRoot = require('app-root-path'); +const winston = require('winston'); +require('winston-daily-rotate-file'); const logFormat = winston.format.combine( winston.format.timestamp(), winston.format.align(), winston.format.printf((info) => { - const localDate = getLocalDate() - return `${localDate} | ${info.level} | ${info.message}` + const localDate = getLocalDate(); + return `${localDate} | ${info.level} | ${info.message}`; }) -) +); const getLogPath = () => { - let logPath = process.env.LOG_PATH + let logPath = process.env.LOG_PATH; if (typeof logPath === 'undefined' || logPath == null || logPath === '') { - logPath = [appRoot.path, 'logs'].join('/') + logPath = [appRoot.path, 'logs'].join('/'); } - return logPath -} + return logPath; +}; const config = { file: { @@ -30,14 +30,16 @@ const config = { handleExceptions: true, handleRejections: true } -} +}; -const allLogsFileTransport = new winston.transports.DailyRotateFile(config.file) +const allLogsFileTransport = new winston.transports.DailyRotateFile( + config.file +); const options = { format: logFormat, transports: [allLogsFileTransport], exitOnError: false -} +}; -export const logger = winston.createLogger(options) +export const logger = winston.createLogger(options); diff --git a/src/services/perpetual_finance.js b/src/services/perpetual_finance.js index 98d0afc..9999aef 100644 --- a/src/services/perpetual_finance.js +++ b/src/services/perpetual_finance.js @@ -1,70 +1,71 @@ -import { logger } from './logger' +import { logger } from './logger'; -const fetch = require('cross-fetch') +const fetch = require('cross-fetch'); -const Ethers = require('ethers') -const AmmArtifact = require('@perp/contract/build/contracts/Amm.json') -const ClearingHouseArtifact = require('@perp/contract/build/contracts/ClearingHouse.json') -const ClearingHouseViewerArtifact = require('@perp/contract/build/contracts/ClearingHouseViewer.json') -const TetherTokenArtifact = require('@perp/contract/build/contracts/TetherToken.json') +const Ethers = require('ethers'); +const AmmArtifact = require('@perp/contract/build/contracts/Amm.json'); +const ClearingHouseArtifact = require('@perp/contract/build/contracts/ClearingHouse.json'); +const ClearingHouseViewerArtifact = require('@perp/contract/build/contracts/ClearingHouseViewer.json'); +const TetherTokenArtifact = require('@perp/contract/build/contracts/TetherToken.json'); -const GAS_LIMIT = 2123456 -const DEFAULT_DECIMALS = 18 -const CONTRACT_ADDRESSES = 'https://metadata.perp.exchange/' -const XDAI_PROVIDER = process.env.XDAI_PROVIDER || 'https://dai.poa.network' -const PNL_OPTION_SPOT_PRICE = 0 -const UPDATE_PERIOD = 60000 // stop updating prices after 30 secs from last request +const GAS_LIMIT = 2123456; +const DEFAULT_DECIMALS = 18; +const CONTRACT_ADDRESSES = 'https://metadata.perp.exchange/'; +const XDAI_PROVIDER = process.env.XDAI_PROVIDER || 'https://dai.poa.network'; +const PNL_OPTION_SPOT_PRICE = 0; +const UPDATE_PERIOD = 60000; // stop updating prices after 30 secs from last request export default class PerpetualFinance { constructor(network = 'mainnet') { - this.providerUrl = XDAI_PROVIDER - this.network = network - this.provider = new Ethers.providers.JsonRpcProvider(this.providerUrl) - this.gasLimit = GAS_LIMIT - this.contractAddressesUrl = CONTRACT_ADDRESSES - this.amm = {} - this.priceCache = {} - this.cacheExpirary = {} - this.pairAmountCache = {} + this.providerUrl = XDAI_PROVIDER; + this.network = network; + this.provider = new Ethers.providers.JsonRpcProvider(this.providerUrl); + this.gasLimit = GAS_LIMIT; + this.contractAddressesUrl = CONTRACT_ADDRESSES; + this.amm = {}; + this.priceCache = {}; + this.cacheExpirary = {}; + this.pairAmountCache = {}; switch (network) { case 'mainnet': - this.contractAddressesUrl += 'production.json' - break + this.contractAddressesUrl += 'production.json'; + break; case 'kovan': - this.contractAddressesUrl += 'staging.json' - break - default: - const err = `Invalid network ${network}` - logger.error(err) - throw Error(err) + this.contractAddressesUrl += 'staging.json'; + break; + default: { + const err = `Invalid network ${network}`; + logger.error(err); + throw Error(err); + } } - this.loadedMetadata = this.load_metadata() + this.loadedMetadata = this.load_metadata(); } async load_metadata() { try { const metadata = await fetch(this.contractAddressesUrl).then((res) => res.json() - ) - const layer2 = Object.keys(metadata.layers.layer2.contracts) + ); + const layer2 = Object.keys(metadata.layers.layer2.contracts); for (const key of layer2) { if (metadata.layers.layer2.contracts[key].name === 'Amm') { - this.amm[key] = metadata.layers.layer2.contracts[key].address + this.amm[key] = metadata.layers.layer2.contracts[key].address; } else { - this[key] = metadata.layers.layer2.contracts[key].address + this[key] = metadata.layers.layer2.contracts[key].address; } } this.layer2AmbAddr = - metadata.layers.layer2.externalContracts.ambBridgeOnXDai - this.xUsdcAddr = metadata.layers.layer2.externalContracts.usdc - this.loadedMetadata = true - return true + metadata.layers.layer2.externalContracts.ambBridgeOnXDai; + this.xUsdcAddr = metadata.layers.layer2.externalContracts.usdc; + this.loadedMetadata = true; + return true; } catch (err) { - return false + return false; } } @@ -72,8 +73,8 @@ export default class PerpetualFinance { if (Object.keys(this.cacheExpirary).length > 0) { for (const pair in this.cacheExpirary) { if (this.cacheExpirary[pair] <= Date.now()) { - delete this.cacheExpirary[pair] - delete this.priceCache[pair] + delete this.cacheExpirary[pair]; + delete this.priceCache[pair]; } } @@ -82,7 +83,7 @@ export default class PerpetualFinance { this.amm[pair], AmmArtifact.abi, this.provider - ) + ); await Promise.allSettled([ amm.getInputPrice(0, { d: Ethers.utils.parseUnits( @@ -97,33 +98,33 @@ export default class PerpetualFinance { ) }) ]).then((values) => { - if (!this.priceCache.hasOwnProperty(pair)) { - this.priceCache[pair] = [] + if (!Object.prototype.hasOwnProperty.call(this.priceCache, pair)) { + this.priceCache[pair] = []; } this.priceCache[pair][0] = this.pairAmountCache[pair] / - Ethers.utils.formatUnits(values[0].value.d) + Ethers.utils.formatUnits(values[0].value.d); this.priceCache[pair][1] = Ethers.utils.formatUnits(values[1].value.d) / - this.pairAmountCache[pair] - }) + this.pairAmountCache[pair]; + }); } } - setTimeout(this.update_price_loop.bind(this), 10000) // update every 10 seconds + setTimeout(this.update_price_loop.bind(this), 10000); // update every 10 seconds } // get XDai balance async getXdaiBalance(wallet) { try { - const xDaiBalance = await wallet.getBalance() - return Ethers.utils.formatEther(xDaiBalance) + const xDaiBalance = await wallet.getBalance(); + return Ethers.utils.formatEther(xDaiBalance); } catch (err) { - logger.error(err) - let reason + logger.error(err); + let reason; err.reason ? (reason = err.reason) - : (reason = 'error xDai balance lookup') - return reason + : (reason = 'error xDai balance lookup'); + return reason; } } @@ -134,15 +135,15 @@ export default class PerpetualFinance { this.xUsdcAddr, TetherTokenArtifact.abi, wallet - ) - const layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address) - const layer2UsdcDecimals = await layer2Usdc.decimals() - return Ethers.utils.formatUnits(layer2UsdcBalance, layer2UsdcDecimals) + ); + const layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address); + const layer2UsdcDecimals = await layer2Usdc.decimals(); + return Ethers.utils.formatUnits(layer2UsdcBalance, layer2UsdcDecimals); } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error balance lookup') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error balance lookup'); + return reason; } } @@ -153,23 +154,23 @@ export default class PerpetualFinance { this.xUsdcAddr, TetherTokenArtifact.abi, wallet - ) + ); try { const allowanceForClearingHouse = await layer2Usdc.allowance( wallet.address, this.ClearingHouse - ) + ); return Ethers.utils.formatUnits( allowanceForClearingHouse, DEFAULT_DECIMALS - ) + ); } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error allowance lookup') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error allowance lookup'); + return reason; } } @@ -181,18 +182,18 @@ export default class PerpetualFinance { this.xUsdcAddr, TetherTokenArtifact.abi, wallet - ) + ); const tx = await layer2Usdc.approve( this.ClearingHouse, Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) - ) + ); // TO-DO: We may want to supply custom gasLimit value above - return tx.hash + return tx.hash; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error approval') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error approval'); + return reason; } } @@ -201,16 +202,16 @@ export default class PerpetualFinance { try { const quoteAssetAmount = { d: Ethers.utils.parseUnits(margin, DEFAULT_DECIMALS) - } - const leverage = { d: Ethers.utils.parseUnits(levrg, DEFAULT_DECIMALS) } + }; + const leverage = { d: Ethers.utils.parseUnits(levrg, DEFAULT_DECIMALS) }; const minBaseAssetAmount = { d: Ethers.utils.parseUnits(minBaseAmount, DEFAULT_DECIMALS) - } + }; const clearingHouse = new Ethers.Contract( this.ClearingHouse, ClearingHouseArtifact.abi, wallet - ) + ); const tx = await clearingHouse.openPosition( this.amm[pair], side, @@ -218,13 +219,13 @@ export default class PerpetualFinance { leverage, minBaseAssetAmount, { gasLimit: this.gasLimit } - ) - return tx + ); + return tx; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error opening position') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error opening position'); + return reason; } } @@ -233,36 +234,36 @@ export default class PerpetualFinance { try { const minimalQuoteAsset = { d: Ethers.utils.parseUnits(minimalQuote, DEFAULT_DECIMALS) - } + }; const clearingHouse = new Ethers.Contract( this.ClearingHouse, ClearingHouseArtifact.abi, wallet - ) + ); const tx = await clearingHouse.closePosition( this.amm[pair], minimalQuoteAsset, { gasLimit: this.gasLimit } - ) - return tx + ); + return tx; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error closing position') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error closing position'); + return reason; } } // get active position async getPosition(wallet, pair) { try { - const positionValues = {} + const positionValues = {}; const clearingHouse = new Ethers.Contract( this.ClearingHouse, ClearingHouseArtifact.abi, wallet - ) - let premIndex = 0 + ); + let premIndex = 0; await Promise.allSettled([ clearingHouse.getPosition(this.amm[pair], wallet.address), clearingHouse.getLatestCumulativePremiumFraction(this.amm[pair]), @@ -275,47 +276,47 @@ export default class PerpetualFinance { positionValues.openNotional = Ethers.utils.formatUnits( values[0].value.openNotional.d, DEFAULT_DECIMALS - ) + ); positionValues.size = Ethers.utils.formatUnits( values[0].value.size.d, DEFAULT_DECIMALS - ) + ); positionValues.margin = Ethers.utils.formatUnits( values[0].value.margin.d, DEFAULT_DECIMALS - ) + ); positionValues.cumulativePremiumFraction = Ethers.utils.formatUnits( values[0].value.lastUpdatedCumulativePremiumFraction.d, DEFAULT_DECIMALS - ) + ); premIndex = Ethers.utils.formatUnits( values[1].value.d, DEFAULT_DECIMALS - ) + ); positionValues.pnl = Ethers.utils.formatUnits( values[2].value.unrealizedPnl.d, DEFAULT_DECIMALS - ) + ); positionValues.positionNotional = Ethers.utils.formatUnits( values[2].value.positionNotional.d, DEFAULT_DECIMALS - ) - }) + ); + }); positionValues.entryPrice = Math.abs( positionValues.openNotional / positionValues.size - ) + ); positionValues.fundingPayment = (premIndex - positionValues.cumulativePremiumFraction) * - positionValues.size // * -1 - return positionValues + positionValues.size; // * -1 + return positionValues; } catch (err) { - logger.error(err) - let reason + logger.error(err); + let reason; err.reason ? (reason = err.reason) - : (reason = 'error getting active position') - return reason + : (reason = 'error getting active position'); + return reason; } } @@ -326,70 +327,70 @@ export default class PerpetualFinance { this.ClearingHouseViewer, ClearingHouseViewerArtifact.abi, wallet - ) + ); const activeMargin = await clearingHouseViewer.getPersonalBalanceWithFundingPayment( this.xUsdcAddr, wallet.address - ) - return activeMargin / (1e18).toString() + ); + return activeMargin / (1e18).toString(); } catch (err) { - logger.error(err) - let reason + logger.error(err); + let reason; err.reason ? (reason = err.reason) - : (reason = 'error getting active position') - return reason + : (reason = 'error getting active position'); + return reason; } } // get Price async getPrice(side, amount, pair) { try { - let price - this.cacheExpirary[pair] = Date.now() + UPDATE_PERIOD - this.pairAmountCache[pair] = amount - if (!this.priceCache.hasOwnProperty(pair)) { + let price; + this.cacheExpirary[pair] = Date.now() + UPDATE_PERIOD; + this.pairAmountCache[pair] = amount; + if (!Object.prototype.hasOwnProperty.call(this.priceCache, pair)) { const amm = new Ethers.Contract( this.amm[pair], AmmArtifact.abi, this.provider - ) + ); if (side === 'buy') { price = await amm.getInputPrice(0, { d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) - }) - price = amount / Ethers.utils.formatUnits(price.d) + }); + price = amount / Ethers.utils.formatUnits(price.d); } else { price = await amm.getOutputPrice(0, { d: Ethers.utils.parseUnits(amount, DEFAULT_DECIMALS) - }) - price = Ethers.utils.formatUnits(price.d) / amount + }); + price = Ethers.utils.formatUnits(price.d) / amount; } } else if (side === 'buy') { - price = this.priceCache[pair][0] + price = this.priceCache[pair][0]; } else { - price = this.priceCache[pair][1] + price = this.priceCache[pair][1]; } - return price + return price; } catch (err) { - console.log(err) - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error getting Price') - return reason + console.log(err); + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error getting Price'); + return reason; } } // get getFundingRate async getFundingRate(pair) { try { - const funding = {} + const funding = {}; const amm = new Ethers.Contract( this.amm[pair], AmmArtifact.abi, this.provider - ) + ); await Promise.allSettled([ amm.getUnderlyingTwapPrice(3600), amm.getTwapPrice(3600), @@ -397,22 +398,22 @@ export default class PerpetualFinance { ]).then((values) => { funding.indexPrice = parseFloat( Ethers.utils.formatUnits(values[0].value.d) - ) + ); funding.markPrice = parseFloat( Ethers.utils.formatUnits(values[1].value.d) - ) - funding.nextFundingTime = parseInt(values[2].value.toString()) - }) + ); + funding.nextFundingTime = parseInt(values[2].value.toString()); + }); funding.rate = - (funding.markPrice - funding.indexPrice) / 24 / funding.indexPrice - return funding + (funding.markPrice - funding.indexPrice) / 24 / funding.indexPrice; + return funding; } catch (err) { - console.log(err) - logger.error(err)() - let reason - err.reason ? (reason = err.reason) : (reason = 'error getting fee') - return reason + console.log(err); + logger.error(err)(); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error getting fee'); + return reason; } } } diff --git a/src/services/terra.js b/src/services/terra.js index 48d8485..601802e 100644 --- a/src/services/terra.js +++ b/src/services/terra.js @@ -4,13 +4,13 @@ import { MsgSwap, MnemonicKey, isTxError -} from '@terra-money/terra.js' -import BigNumber from 'bignumber.js' -import { logger } from './logger' -import { getHummingbotMemo } from './utils' +} from '@terra-money/terra.js'; +import BigNumber from 'bignumber.js'; +import { logger } from './logger'; +import { getHummingbotMemo } from './utils'; -const debug = require('debug')('router') -require('dotenv').config() +const debug = require('debug')('router'); +require('dotenv').config(); // constants const TERRA_TOKENS = { @@ -19,35 +19,35 @@ const TERRA_TOKENS = { ukrw: { symbol: 'KRT' }, usdr: { symbol: 'SDT' }, umnt: { symbol: 'MNT' } -} -const DENOM_UNIT = BigNumber('1e+6') -const TOBIN_TAX = 0.0025 // a Tobin Tax (set at 0.25%) for spot-converting Terra<>Terra swaps -const MIN_SPREAD = 0.02 // a minimum spread (set at 2%) for Terra<>Luna swaps -const GAS_PRICE = { uluna: 0.16 } -const GAS_ADJUSTMENT = 1.4 +}; +const DENOM_UNIT = BigNumber('1e+6'); +const TOBIN_TAX = 0.0025; // a Tobin Tax (set at 0.25%) for spot-converting Terra<>Terra swaps +const MIN_SPREAD = 0.02; // a minimum spread (set at 2%) for Terra<>Luna swaps +const GAS_PRICE = { uluna: 0.16 }; +const GAS_ADJUSTMENT = 1.4; export default class Terra { constructor() { - this.lcdUrl = process.env.TERRA_LCD_URL - this.network = process.env.TERRA_CHAIN - this.tokens = TERRA_TOKENS - this.denomUnitMultiplier = DENOM_UNIT - this.tobinTax = TOBIN_TAX - this.minSpread = MIN_SPREAD - this.memo = getHummingbotMemo() + this.lcdUrl = process.env.TERRA_LCD_URL; + this.network = process.env.TERRA_CHAIN; + this.tokens = TERRA_TOKENS; + this.denomUnitMultiplier = DENOM_UNIT; + this.tobinTax = TOBIN_TAX; + this.minSpread = MIN_SPREAD; + this.memo = getHummingbotMemo(); try { - this.lcd = this.connect() + this.lcd = this.connect(); this.lcd.market.parameters().catch(() => { - throw new Error('Connection error') - }) + throw new Error('Connection error'); + }); // set gas & fee - this.lcd.config.gasAdjustment = GAS_ADJUSTMENT - this.lcd.config.gasPrices = GAS_PRICE + this.lcd.config.gasAdjustment = GAS_ADJUSTMENT; + this.lcd.config.gasPrices = GAS_PRICE; } catch (err) { - logger.error(err) - throw Error(`Connection failed: ${this.network}`) + logger.error(err); + throw Error(`Connection failed: ${this.network}`); } } @@ -57,145 +57,149 @@ export default class Terra { const lcd = new LCDClient({ URL: this.lcdUrl, chainID: this.network - }) - lcd.config.gasAdjustment = GAS_ADJUSTMENT - lcd.config.gasPrices = GAS_PRICE - return lcd + }); + lcd.config.gasAdjustment = GAS_ADJUSTMENT; + lcd.config.gasPrices = GAS_PRICE; + return lcd; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error Terra LCD connect') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error Terra LCD connect'); + return reason; } } // get Token Denom getTokenDenom(symbol) { try { - let denom + let denom; Object.keys(TERRA_TOKENS).forEach((item) => { if (TERRA_TOKENS[item].symbol === symbol) { - denom = item + denom = item; } - }) - return denom + }); + return denom; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error Terra Denom lookup') - return reason + logger.error(err); + let reason; + err.reason + ? (reason = err.reason) + : (reason = 'error Terra Denom lookup'); + return reason; } } // get Token Symbol getTokenSymbol(denom) { try { - const { symbol } = TERRA_TOKENS[denom] - return symbol + const { symbol } = TERRA_TOKENS[denom]; + return symbol; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error Terra Denom lookup') - return reason + logger.error(err); + let reason; + err.reason + ? (reason = err.reason) + : (reason = 'error Terra Denom lookup'); + return reason; } } getTxAttributes(attributes) { - const attrib = {} + const attrib = {}; attributes.forEach((item) => { - attrib[item.key] = item.value - }) - return attrib + attrib[item.key] = item.value; + }); + return attrib; } async getEstimateFee(tx) { try { - const fee = await this.lcd.tx.estimateFee(tx) - return fee + const fee = await this.lcd.tx.estimateFee(tx); + return fee; } catch (err) { - logger.error(err) - let reason + logger.error(err); + let reason; err.reason ? (reason = err.reason) - : (reason = 'error Terra estimate fee lookup') - return reason + : (reason = 'error Terra estimate fee lookup'); + return reason; } } async getExchangeRate(denom) { try { - const exchangeRates = await this.lcd.oracle.exchangeRates() - return exchangeRates.get(denom) + const exchangeRates = await this.lcd.oracle.exchangeRates(); + return exchangeRates.get(denom); } catch (err) { - logger.error(err) - let reason + logger.error(err); + let reason; err.reason ? (reason = err.reason) - : (reason = 'error Terra exchange rate lookup') - return reason + : (reason = 'error Terra exchange rate lookup'); + return reason; } } async getTxFee() { try { - const lunaFee = GAS_PRICE.uluna * GAS_ADJUSTMENT - const feeList = { uluna: lunaFee } + const lunaFee = GAS_PRICE.uluna * GAS_ADJUSTMENT; + const feeList = { uluna: lunaFee }; await this.lcd.oracle.exchangeRates().then((rates) => { Object.keys(rates._coins).forEach((key) => { - feeList[key] = rates._coins[key].amount * lunaFee - }) - }) - debug('lunaFee', lunaFee, feeList) + feeList[key] = rates._coins[key].amount * lunaFee; + }); + }); + debug('lunaFee', lunaFee, feeList); - return feeList + return feeList; } catch (err) { - logger.error(err) - let reason + logger.error(err); + let reason; err.reason ? (reason = err.reason) - : (reason = 'error Terra exchange rate lookup') - return reason + : (reason = 'error Terra exchange rate lookup'); + return reason; } } // get Terra Swap Rate async getSwapRate(baseToken, quoteToken, amount, tradeType) { try { - let exchangeRate - let offerCoin - let offerDenom - let swapDenom - let cost - let costAmount - let offer - const swaps = {} + let exchangeRate; + let offerCoin; + let offerDenom; + let swapDenom; + let cost; + let costAmount; + let offer; + const swaps = {}; if (tradeType.toLowerCase() === 'sell') { // sell base - offerDenom = this.getTokenDenom(baseToken) - swapDenom = this.getTokenDenom(quoteToken) + offerDenom = this.getTokenDenom(baseToken); + swapDenom = this.getTokenDenom(quoteToken); - offerCoin = new Coin(offerDenom, amount * DENOM_UNIT) + offerCoin = new Coin(offerDenom, amount * DENOM_UNIT); await this.lcd.market .swapRate(offerCoin, swapDenom) .then((swapCoin) => { - offer = { amount } + offer = { amount }; exchangeRate = { amount: swapCoin.amount / DENOM_UNIT / amount, token: quoteToken - } - costAmount = amount * exchangeRate.amount + }; + costAmount = amount * exchangeRate.amount; cost = { amount: costAmount, token: quoteToken - } - }) + }; + }); } else { // buy base - offerDenom = this.getTokenDenom(quoteToken) - swapDenom = this.getTokenDenom(baseToken) + offerDenom = this.getTokenDenom(quoteToken); + swapDenom = this.getTokenDenom(baseToken); - offerCoin = new Coin(offerDenom, 1 * DENOM_UNIT) + offerCoin = new Coin(offerDenom, 1 * DENOM_UNIT); await this.lcd.market .swapRate(offerCoin, swapDenom) .then((swapCoin) => { @@ -203,36 +207,36 @@ export default class Terra { amount: ((amount / parseInt(swapCoin.amount)) * DENOM_UNIT) / amount, // adjusted amount token: quoteToken - } - costAmount = amount * exchangeRate.amount + }; + costAmount = amount * exchangeRate.amount; cost = { amount: costAmount, token: quoteToken - } - offer = { amount: cost.amount } - }) + }; + offer = { amount: cost.amount }; + }); } - let txFee + let txFee; await this.getTxFee().then((fee) => { // fee in quote txFee = { amount: parseFloat(fee[this.getTokenDenom(quoteToken)]), token: quoteToken - } - }) - - swaps.offer = offer - swaps.price = exchangeRate - swaps.cost = cost - swaps.txFee = txFee - debug('swaps', swaps) - return swaps + }; + }); + + swaps.offer = offer; + swaps.price = exchangeRate; + swaps.cost = cost; + swaps.txFee = txFee; + debug('swaps', swaps); + return swaps; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = 'error swap rate lookup') - return reason + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = 'error swap rate lookup'); + return reason; } } @@ -246,40 +250,40 @@ export default class Terra { gasAdjustment, secret ) { - let swapResult + let swapResult; try { // connect to lcd - const lcd = this.connect() + const lcd = this.connect(); const mk = new MnemonicKey({ mnemonic: secret - }) - let wallet + }); + let wallet; try { - wallet = lcd.wallet(mk) + wallet = lcd.wallet(mk); } catch (err) { - logger.error(err) - throw Error('Wallet access error') + logger.error(err); + throw Error('Wallet access error'); } - const address = wallet.key.accAddress + const address = wallet.key.accAddress; // get the current swap rate - const baseDenom = this.getTokenDenom(baseToken) - const quoteDenom = this.getTokenDenom(quoteToken) + const baseDenom = this.getTokenDenom(baseToken); + const quoteDenom = this.getTokenDenom(quoteToken); - let offerDenom - let swapDenom - let swaps - let txAttributes - const tokenSwap = {} + let offerDenom; + let swapDenom; + let swaps; + let txAttributes; + const tokenSwap = {}; if (tradeType.toLowerCase() === 'sell') { - offerDenom = baseDenom - swapDenom = quoteDenom + offerDenom = baseDenom; + swapDenom = quoteDenom; } else { - offerDenom = quoteDenom - swapDenom = baseDenom + offerDenom = quoteDenom; + swapDenom = baseDenom; } await this.getSwapRate( @@ -289,16 +293,16 @@ export default class Terra { tradeType, secret ).then((rate) => { - swaps = rate - }) + swaps = rate; + }); - const offerAmount = parseInt(swaps.offer.amount * DENOM_UNIT) - const offerCoin = new Coin(offerDenom, offerAmount) + const offerAmount = parseInt(swaps.offer.amount * DENOM_UNIT); + const offerCoin = new Coin(offerDenom, offerAmount); // Create and Sign Transaction - const msgSwap = new MsgSwap(address, offerCoin, swapDenom) + const msgSwap = new MsgSwap(address, offerCoin, swapDenom); - let txOptions + let txOptions; if (gasPrice !== null && gasPrice !== null) { // ignore gasAdjustment when gasPrice is not set txOptions = { @@ -306,57 +310,57 @@ export default class Terra { gasPrices: { uluna: parseFloat(gasPrice) }, gasAdjustment, memo: this.memo - } + }; } else { txOptions = { msgs: [msgSwap], memo: this.memo - } + }; } await wallet .createAndSignTx(txOptions) .then((tx) => lcd.tx.broadcast(tx)) .then((txResult) => { - swapResult = txResult + swapResult = txResult; - const swapSuccess = !isTxError(txResult) + const swapSuccess = !isTxError(txResult); if (swapSuccess) { - tokenSwap.txSuccess = swapSuccess + tokenSwap.txSuccess = swapSuccess; } else { - tokenSwap.txSuccess = !swapSuccess + tokenSwap.txSuccess = !swapSuccess; throw new Error( `encountered an error while running the transaction: ${txResult.code} ${txResult.codespace}` - ) + ); } - const txHash = txResult.txhash - const { events } = JSON.parse(txResult.raw_log)[0] - const swap = events.find((obj) => obj.type === 'swap') - txAttributes = this.getTxAttributes(swap.attributes) - const offer = Coin.fromString(txAttributes.offer) - const ask = Coin.fromString(txAttributes.swap_coin) - const fee = Coin.fromString(txAttributes.swap_fee) + const txHash = txResult.txhash; + const { events } = JSON.parse(txResult.raw_log)[0]; + const swap = events.find((obj) => obj.type === 'swap'); + txAttributes = this.getTxAttributes(swap.attributes); + const offer = Coin.fromString(txAttributes.offer); + const ask = Coin.fromString(txAttributes.swap_coin); + const fee = Coin.fromString(txAttributes.swap_fee); tokenSwap.expectedIn = { amount: parseFloat(offer.amount) / DENOM_UNIT, token: TERRA_TOKENS[offer.denom].symbol - } + }; tokenSwap.expectedOut = { amount: parseFloat(ask.amount) / DENOM_UNIT, token: TERRA_TOKENS[ask.denom].symbol - } + }; tokenSwap.fee = { amount: parseFloat(fee.amount) / DENOM_UNIT, token: TERRA_TOKENS[fee.denom].symbol - } - tokenSwap.txHash = txHash - }) - return tokenSwap + }; + tokenSwap.txHash = txHash; + }); + return tokenSwap; } catch (err) { - logger.error(err) - let reason - err.reason ? (reason = err.reason) : (reason = swapResult) - return { txSuccess: false, message: reason } + logger.error(err); + let reason; + err.reason ? (reason = err.reason) : (reason = swapResult); + return { txSuccess: false, message: reason }; } } } diff --git a/src/services/uniswap.js b/src/services/uniswap.js index 076dbb7..e41ee81 100644 --- a/src/services/uniswap.js +++ b/src/services/uniswap.js @@ -1,65 +1,66 @@ -import { logger } from './logger' +import { logger } from './logger'; -const debug = require('debug')('router') -const math = require('mathjs') -const uni = require('@uniswap/sdk') -const ethers = require('ethers') -const proxyArtifact = require('../static/uniswap_v2_router_abi.json') -const routeTokens = require('../static/uniswap_route_tokens.json') +const debug = require('debug')('router'); +const math = require('mathjs'); +const uni = require('@uniswap/sdk'); +const ethers = require('ethers'); +const proxyArtifact = require('../static/uniswap_v2_router_abi.json'); +const routeTokens = require('../static/uniswap_route_tokens.json'); // constants -const ROUTER = process.env.UNISWAP_ROUTER -const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 150688 -const TTL = process.env.UNISWAP_TTL || 300 -const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000 // stop updating pair after 5 minutes from last request +const ROUTER = process.env.UNISWAP_ROUTER; +const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 150688; +const TTL = process.env.UNISWAP_TTL || 300; +const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request export default class Uniswap { constructor(network = 'mainnet') { - this.providerUrl = process.env.ETHEREUM_RPC_URL - this.network = process.env.ETHEREUM_CHAIN - this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) - this.router = ROUTER - this.slippage = math.fraction(process.env.UNISWAP_ALLOWED_SLIPPAGE) + this.providerUrl = process.env.ETHEREUM_RPC_URL; + this.network = process.env.ETHEREUM_CHAIN; + this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl); + this.router = ROUTER; + this.slippage = math.fraction(process.env.UNISWAP_ALLOWED_SLIPPAGE); this.allowedSlippage = new uni.Percent( this.slippage.n, this.slippage.d * 100 - ) - this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME - this.gasLimit = GAS_LIMIT - this.expireTokenPairUpdate = UPDATE_PERIOD + ); + this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME; + this.gasLimit = GAS_LIMIT; + this.expireTokenPairUpdate = UPDATE_PERIOD; this.zeroReserveCheckInterval = - process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL - this.zeroReservePairs = {} // No reserve pairs - this.tokenList = {} - this.pairs = [] - this.tokenSwapList = {} - this.cachedRoutes = {} + process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL; + this.zeroReservePairs = {}; // No reserve pairs + this.tokenList = {}; + this.pairs = []; + this.tokenSwapList = {}; + this.cachedRoutes = {}; switch (network) { case 'mainnet': - this.chainID = uni.ChainId.MAINNET - break + this.chainID = uni.ChainId.MAINNET; + break; case 'kovan': - this.chainID = uni.ChainId.KOVAN - break - default: - const err = `Invalid network ${network}` - logger.error(err) - throw Error(err) + this.chainID = uni.ChainId.KOVAN; + break; + default: { + const err = `Invalid network ${network}`; + logger.error(err); + throw Error(err); + } } } async fetch_route(tIn, tOut) { - let route - let pair + let route; + let pair; try { - pair = await uni.Fetcher.fetchPairData(tIn, tOut) - route = new uni.Route([pair], tIn, tOut) + pair = await uni.Fetcher.fetchPairData(tIn, tOut); + route = new uni.Route([pair], tIn, tOut); } catch (err) { - logger.error(err) + logger.error(err); } - return route + return route; } generate_tokens() { @@ -70,19 +71,19 @@ export default class Uniswap { token.decimals, token.symbol, token.name - ) + ); } } async extend_update_pairs(tokens = []) { for (const token of tokens) { - if (!this.tokenList.hasOwnProperty(token)) { + if (!Object.prototype.hasOwnProperty.call(this.tokenList, token)) { this.tokenList[token] = await uni.Fetcher.fetchTokenData( this.chainID, token - ) + ); } - this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate + this.tokenSwapList[token] = Date.now() + this.expireTokenPairUpdate; } } @@ -91,7 +92,7 @@ export default class Uniswap { if (Object.keys(this.zeroReservePairs).length > 0) { for (const pair in this.zeroReservePairs) { if (this.zeroReservePairs[pair] <= Date.now()) { - delete this.zeroReservePairs[pair] + delete this.zeroReservePairs[pair]; // delete this.tokenList[token]; } } @@ -101,19 +102,19 @@ export default class Uniswap { if (Object.keys(this.tokenSwapList).length > 0) { for (const token in this.tokenSwapList) { if (this.tokenSwapList[token] <= Date.now()) { - delete this.tokenSwapList[token] + delete this.tokenSwapList[token]; // delete this.tokenList[token]; } } - const tokens = Object.keys(this.tokenList) - let firstToken - let secondToken - let position - const length = tokens.length - const pairs = [] - const pairAddressRequests = [] - const pairAddressResponses = [] + const tokens = Object.keys(this.tokenList); + let firstToken; + let secondToken; + let position; + const length = tokens.length; + const pairs = []; + const pairAddressRequests = []; + const pairAddressResponses = []; for (firstToken = 0; firstToken < length; firstToken++) { for ( secondToken = firstToken + 1; @@ -123,18 +124,23 @@ export default class Uniswap { try { const pairString = `${this.tokenList[tokens[firstToken]].address}-${ this.tokenList[tokens[secondToken]].address - }` - if (!this.zeroReservePairs.hasOwnProperty(pairString)) { - pairs.push(pairString) + }`; + if ( + !Object.prototype.hasOwnProperty.call( + this.zeroReservePairs, + pairString + ) + ) { + pairs.push(pairString); pairAddressRequests.push( uni.Fetcher.fetchPairData( this.tokenList[tokens[firstToken]], this.tokenList[tokens[secondToken]] ) - ) + ); } } catch (err) { - logger.error(err) + logger.error(err); } } } @@ -142,82 +148,82 @@ export default class Uniswap { await Promise.allSettled(pairAddressRequests).then((values) => { for (position = 0; position < pairAddressRequests.length; position++) { if (values[position].status === 'fulfilled') { - pairAddressResponses.push(values[position].value) + pairAddressResponses.push(values[position].value); } else { this.zeroReservePairs[pairs[position]] = - Date.now() + this.zeroReserveCheckInterval + Date.now() + this.zeroReserveCheckInterval; } } - }) - this.pairs = pairAddressResponses + }); + this.pairs = pairAddressResponses; } - setTimeout(this.update_pairs.bind(this), 1000) + setTimeout(this.update_pairs.bind(this), 1000); } async priceSwapIn(tokenIn, tokenOut, tokenInAmount) { - await this.extend_update_pairs([tokenIn, tokenOut]) - const tIn = this.tokenList[tokenIn] - const tOut = this.tokenList[tokenOut] + await this.extend_update_pairs([tokenIn, tokenOut]); + const tIn = this.tokenList[tokenIn]; + const tOut = this.tokenList[tokenOut]; const tokenAmountIn = new uni.TokenAmount( tIn, ethers.utils.parseUnits(tokenInAmount, tIn.decimals) - ) + ); if (this.pairs.length === 0) { - const route = await this.fetch_route(tIn, tOut) - const trade = uni.Trade.exactIn(route, tokenAmountIn) + const route = await this.fetch_route(tIn, tOut); + const trade = uni.Trade.exactIn(route, tokenAmountIn); if (trade !== undefined) { - const expectedAmount = trade.minimumAmountOut(this.allowedSlippage) - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade - return { trade, expectedAmount } + const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; + return { trade, expectedAmount }; } - return "Can't find route to swap, kindly update " + return "Can't find route to swap, kindly update "; } let trade = uni.Trade.bestTradeExactIn( this.pairs, tokenAmountIn, this.tokenList[tokenOut], { maxHops: 5 } - )[0] + )[0]; if (trade === undefined) { - trade = this.cachedRoutes[tIn.symbol + tOut.Symbol] + trade = this.cachedRoutes[tIn.symbol + tOut.Symbol]; } else { - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; } - const expectedAmount = trade.minimumAmountOut(this.allowedSlippage) - return { trade, expectedAmount } + const expectedAmount = trade.minimumAmountOut(this.allowedSlippage); + return { trade, expectedAmount }; } async priceSwapOut(tokenIn, tokenOut, tokenOutAmount) { - await this.extend_update_pairs([tokenIn, tokenOut]) - const tOut = this.tokenList[tokenOut] - const tIn = this.tokenList[tokenIn] + await this.extend_update_pairs([tokenIn, tokenOut]); + const tOut = this.tokenList[tokenOut]; + const tIn = this.tokenList[tokenIn]; const tokenAmountOut = new uni.TokenAmount( tOut, ethers.utils.parseUnits(tokenOutAmount, tOut.decimals) - ) + ); if (this.pairs.length === 0) { - const route = await this.fetch_route(tIn, tOut) - const trade = uni.Trade.exactOut(route, tokenAmountOut) + const route = await this.fetch_route(tIn, tOut); + const trade = uni.Trade.exactOut(route, tokenAmountOut); if (trade !== undefined) { - const expectedAmount = trade.maximumAmountIn(this.allowedSlippage) - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade - return { trade, expectedAmount } + const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; + return { trade, expectedAmount }; } - return + return; } let trade = uni.Trade.bestTradeExactOut( this.pairs, this.tokenList[tokenIn], tokenAmountOut, { maxHops: 5 } - )[0] + )[0]; if (trade === undefined) { - trade = this.cachedRoutes[tIn.symbol + tOut.Symbol] + trade = this.cachedRoutes[tIn.symbol + tOut.Symbol]; } else { - this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade + this.cachedRoutes[tIn.symbol + tOut.Symbol] = trade; } - const expectedAmount = trade.maximumAmountIn(this.allowedSlippage) - return { trade, expectedAmount } + const expectedAmount = trade.maximumAmountIn(this.allowedSlippage); + return { trade, expectedAmount }; } async swapExactIn(wallet, trade, tokenAddress, gasPrice) { @@ -225,17 +231,21 @@ export default class Uniswap { ttl: TTL, recipient: wallet.address, allowedSlippage: this.allowedSlippage - }) + }); - const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) + const contract = new ethers.Contract( + this.router, + proxyArtifact.abi, + wallet + ); const tx = await contract[result.methodName](...result.args, { gasPrice: gasPrice * 1e9, gasLimit: GAS_LIMIT, value: result.value - }) + }); - debug(`Tx Hash: ${tx.hash}`) - return tx + debug(`Tx Hash: ${tx.hash}`); + return tx; } async swapExactOut(wallet, trade, tokenAddress, gasPrice) { @@ -243,16 +253,20 @@ export default class Uniswap { ttl: TTL, recipient: wallet.address, allowedSlippage: this.allowedSlippage - }) + }); - const contract = new ethers.Contract(this.router, proxyArtifact.abi, wallet) + const contract = new ethers.Contract( + this.router, + proxyArtifact.abi, + wallet + ); const tx = await contract[result.methodName](...result.args, { gasPrice: gasPrice * 1e9, gasLimit: GAS_LIMIT, value: result.value - }) + }); - debug(`Tx Hash: ${tx.hash}`) - return tx + debug(`Tx Hash: ${tx.hash}`); + return tx; } } diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js index fecf868..88fe990 100644 --- a/src/services/uniswap_v3.js +++ b/src/services/uniswap_v3.js @@ -1,113 +1,114 @@ -import { logger } from './logger' +import { logger } from './logger'; import { encodePriceSqrt, getTickFromPrice -} from '../static/uniswap-v3/helper_functions' +} from '../static/uniswap-v3/helper_functions'; -const debug = require('debug')('router') -const math = require('mathjs') -const uni = require('@uniswap/sdk') -const ethers = require('ethers') -const coreArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json') -const nftArtifact = require('@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json') -const routerArtifact = require('@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json') -const poolArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json') +const debug = require('debug')('router'); +const math = require('mathjs'); +const uni = require('@uniswap/sdk'); +const ethers = require('ethers'); +const coreArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json'); +const nftArtifact = require('@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'); +const routerArtifact = require('@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json'); +const poolArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json'); // const routeTokens = require('../static/uniswap_route_tokens.json') -const abiDecoder = require('abi-decoder') +const abiDecoder = require('abi-decoder'); // constants -const FeeAmount = { LOW: 500, MEDIUM: 3000, HIGH: 10000 } -const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 5506880 -const TTL = process.env.UNISWAP_TTL || 300 -const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000 // stop updating pair after 5 minutes from last request -const MaxUint128 = ethers.BigNumber.from(2).pow(128).sub(1) +const FeeAmount = { LOW: 500, MEDIUM: 3000, HIGH: 10000 }; +const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 5506880; +const TTL = process.env.UNISWAP_TTL || 300; +const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request +const MaxUint128 = ethers.BigNumber.from(2).pow(128).sub(1); -abiDecoder.addABI(nftArtifact.abi) -abiDecoder.addABI(routerArtifact.abi) +abiDecoder.addABI(nftArtifact.abi); +abiDecoder.addABI(routerArtifact.abi); export default class UniswapV3 { constructor(network = 'mainnet') { - this.providerUrl = process.env.ETHEREUM_RPC_URL - this.network = process.env.ETHEREUM_CHAIN - this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) - this.router = process.env.UNISWAP_V3_ROUTER - this.nftManager = process.env.UNISWAP_V3_NFT_MANAGER - this.core = process.env.UNISWAP_V3_CORE - this.slippage = process.env.UNISWAP_ALLOWED_SLIPPAGE - this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME - this.gasLimit = GAS_LIMIT - this.expireTokenPairUpdate = UPDATE_PERIOD + this.providerUrl = process.env.ETHEREUM_RPC_URL; + this.network = process.env.ETHEREUM_CHAIN; + this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl); + this.router = process.env.UNISWAP_V3_ROUTER; + this.nftManager = process.env.UNISWAP_V3_NFT_MANAGER; + this.core = process.env.UNISWAP_V3_CORE; + this.slippage = process.env.UNISWAP_ALLOWED_SLIPPAGE; + this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME; + this.gasLimit = GAS_LIMIT; + this.expireTokenPairUpdate = UPDATE_PERIOD; this.zeroReserveCheckInterval = - process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL - this.zeroReservePairs = {} // No reserve pairs - this.tokenList = {} - this.pairs = [] - this.tokenSwapList = {} - this.cachedRoutes = {} - this.abiDecoder = abiDecoder + process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL; + this.zeroReservePairs = {}; // No reserve pairs + this.tokenList = {}; + this.pairs = []; + this.tokenSwapList = {}; + this.cachedRoutes = {}; + this.abiDecoder = abiDecoder; switch (network) { case 'mainnet': - this.chainID = uni.ChainId.MAINNET - break + this.chainID = uni.ChainId.MAINNET; + break; case 'kovan': - this.chainID = uni.ChainId.KOVAN - break - default: - const err = `Invalid network ${network}` - logger.error(err) + this.chainID = uni.ChainId.KOVAN; + break; + default: { + const err = `Invalid network ${network}`; + logger.error(err); + } } } get_contract(contract, wallet) { if (contract === 'core') { - return new ethers.Contract(this.core, coreArtifact.abi, wallet) + return new ethers.Contract(this.core, coreArtifact.abi, wallet); } if (contract === 'router') { - return new ethers.Contract(this.router, routerArtifact.abi, wallet) + return new ethers.Contract(this.router, routerArtifact.abi, wallet); } - return new ethers.Contract(this.nftManager, nftArtifact.abi, wallet) + return new ethers.Contract(this.nftManager, nftArtifact.abi, wallet); } async currentPrice(wallet, tokenIn, tokenOut) { - let pool - let poolContract - const poolPrices = [] - const poolLiquidity = [] - const keys = ['LOW', 'MEDIUM', 'HIGH'] - const coreContract = this.get_contract('core', wallet) + let pool; + let poolContract; + const poolPrices = []; + const poolLiquidity = []; + const keys = ['LOW', 'MEDIUM', 'HIGH']; + const coreContract = this.get_contract('core', wallet); const poolAddressRequests = [ coreContract.getPool(tokenIn, tokenOut, FeeAmount.LOW), coreContract.getPool(tokenIn, tokenOut, FeeAmount.MEDIUM), coreContract.getPool(tokenIn, tokenOut, FeeAmount.HIGH) - ] + ]; await Promise.allSettled(poolAddressRequests).then((values) => { for (pool = 0; pool < 3; pool++) { if (values[pool].value === ethers.constants.AddressZero) { - poolPrices[pool] = 0 + poolPrices[pool] = 0; } else { poolContract = new ethers.Contract( values[pool].value, poolArtifact.abi, wallet - ) - poolPrices[pool] = poolContract.observe([1, 0]) + ); + poolPrices[pool] = poolContract.observe([1, 0]); } } - }) + }); await Promise.allSettled(poolPrices).then((values) => { for (pool = 0; pool < 3; pool++) { - poolPrices[pool] = poolLiquidity[pool] = 0 + poolPrices[pool] = poolLiquidity[pool] = 0; if (values[pool].value) { for (const tick of values[pool].value.tickCumulatives) { - poolPrices[pool] = tick.toNumber() - poolPrices[pool] + poolPrices[pool] = tick.toNumber() - poolPrices[pool]; } - poolPrices[pool] = math.pow(1.0001, poolPrices[pool]) + poolPrices[pool] = math.pow(1.0001, poolPrices[pool]); } } - }) - return Object.assign(...keys.map((k, i) => ({ [k]: poolPrices[i] }))) + }); + return Object.assign(...keys.map((k, i) => ({ [k]: poolPrices[i] }))); } async swapExactIn( @@ -120,16 +121,16 @@ export default class UniswapV3 { _gasPrice ) { // sell, In => base, Out => quote - const minPercentOut = 1 - this.slippage / 100 + const minPercentOut = 1 - this.slippage / 100; const amountOutMinimum = Math.floor( baseAmount * limitPrice * minPercentOut * quoteTokenContractInfo.decimals - ) / quoteTokenContractInfo.decimals + ) / quoteTokenContractInfo.decimals; // const priceFraction = math.fraction(limitPrice) - const contract = this.get_contract('router', wallet) + const contract = this.get_contract('router', wallet); const tx = await contract.exactInputSingle( { tokenIn: baseTokenContractInfo.address, @@ -150,11 +151,11 @@ export default class UniswapV3 { { gasLimit: GAS_LIMIT } - ) + ); - debug(`Tx Hash: ${tx.hash}`) - tx.expectedAmount = amountOutMinimum - return tx + debug(`Tx Hash: ${tx.hash}`); + tx.expectedAmount = amountOutMinimum; + return tx; } async swapExactOut( @@ -167,13 +168,13 @@ export default class UniswapV3 { _gasPrice ) { // buy, In => quote, Out => base - const maxPercentIn = 1 + this.slippage / 100 + const maxPercentIn = 1 + this.slippage / 100; const amountInMaximum = Math.ceil( baseAmount * limitPrice * maxPercentIn * quoteTokenContractInfo.decimals - ) / quoteTokenContractInfo.decimals + ) / quoteTokenContractInfo.decimals; // const priceFraction = math.fraction(limitPrice) - const contract = this.get_contract('router', wallet) + const contract = this.get_contract('router', wallet); const tx = await contract.exactOutputSingle( { tokenIn: quoteTokenContractInfo.address, @@ -194,18 +195,18 @@ export default class UniswapV3 { { gasLimit: GAS_LIMIT } - ) + ); - debug(`Tx Hash: ${tx.hash}`) - tx.expectedAmount = amountInMaximum - return tx + debug(`Tx Hash: ${tx.hash}`); + tx.expectedAmount = amountInMaximum; + return tx; } // LP section async getPosition(wallet, tokenId) { - const contract = this.get_contract('nft', wallet) - const position = await contract.positions(tokenId) + const contract = this.get_contract('nft', wallet); + const position = await contract.positions(tokenId); return { nonce: position[0].toString(), operator: position[1], @@ -219,7 +220,7 @@ export default class UniswapV3 { feeGrowthInside1LastX128: position[9].toString(), tokensOwed0: position[10].toString(), tokensOwed1: position[11].toString() - } + }; } getRemoveLiquidityData(wallet, contract, tokenId, liquidity) { @@ -234,7 +235,7 @@ export default class UniswapV3 { deadline: Date.now() + TTL } ] - ) + ); const collectFeesData = contract.interface.encodeFunctionData('collect', [ { tokenId, @@ -242,10 +243,10 @@ export default class UniswapV3 { amount0Max: MaxUint128, amount1Max: MaxUint128 } - ]) - const burnData = contract.interface.encodeFunctionData('burn', [tokenId]) + ]); + const burnData = contract.interface.encodeFunctionData('burn', [tokenId]); - return [decreaseLiquidityData, collectFeesData, burnData] + return [decreaseLiquidityData, collectFeesData, burnData]; } getAddLiquidityData( @@ -274,9 +275,9 @@ export default class UniswapV3 { deadline: Date.now() + TTL, fee: FeeAmount[fee] } - ]) + ]); - return mintData + return mintData; } async addPosition( @@ -289,14 +290,14 @@ export default class UniswapV3 { lowerPrice, upperPrice ) { - const nftContract = this.get_contract('nft', wallet) - const coreContract = this.get_contract('core', wallet) + const nftContract = this.get_contract('nft', wallet); + const coreContract = this.get_contract('core', wallet); const pool = await coreContract.getPool( token0.address, token1.address, FeeAmount[fee] - ) - const midPrice = math.fraction((lowerPrice + upperPrice) / 2) // Use mid price to initialize uninitialized pool + ); + const midPrice = math.fraction((lowerPrice + upperPrice) / 2); // Use mid price to initialize uninitialized pool const initPoolData = nftContract.interface.encodeFunctionData( 'createAndInitializePoolIfNecessary', @@ -306,7 +307,7 @@ export default class UniswapV3 { FeeAmount[fee], encodePriceSqrt(midPrice.n, midPrice.d) ] - ) + ); const mintData = this.getAddLiquidityData( wallet, @@ -318,30 +319,30 @@ export default class UniswapV3 { fee, lowerPrice, upperPrice - ) + ); - const calls = [mintData] + const calls = [mintData]; if (pool === ethers.constants.AddressZero) { const tx = await nftContract.multicall([initPoolData, mintData], { gasLimit: GAS_LIMIT - }) - return tx + }); + return tx; } - const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }) - return tx + const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }); + return tx; } async removePosition(wallet, tokenId) { // Reduce position and burn - const positionData = await this.getPosition(wallet, tokenId) - const contract = this.get_contract('nft', wallet) + const positionData = await this.getPosition(wallet, tokenId); + const contract = this.get_contract('nft', wallet); const data = this.getRemoveLiquidityData( wallet, contract, tokenId, positionData.liquidity - ) - return contract.multicall(data, { gasLimit: GAS_LIMIT }) + ); + return contract.multicall(data, { gasLimit: GAS_LIMIT }); } async replacePosition( @@ -355,14 +356,14 @@ export default class UniswapV3 { lowerPrice, upperPrice ) { - const contract = this.get_contract('nft', wallet) - const positionData = await this.getPosition(wallet, tokenId) + const contract = this.get_contract('nft', wallet); + const positionData = await this.getPosition(wallet, tokenId); const removeData = this.getRemoveLiquidityData( wallet, contract, tokenId, positionData.liquidity - ) + ); const mintData = this.getAddLiquidityData( wallet, contract, @@ -373,15 +374,15 @@ export default class UniswapV3 { fee, lowerPrice, upperPrice - ) + ); return contract.multicall(removeData.concat(mintData), { gasLimit: GAS_LIMIT - }) + }); } async collectFees(wallet, tokenId) { - const contract = this.get_contract('nft', wallet) + const contract = this.get_contract('nft', wallet); return contract.collect( { tokenId, @@ -390,6 +391,6 @@ export default class UniswapV3 { amount1Max: MaxUint128 }, { gasLimit: GAS_LIMIT } - ) + ); } } diff --git a/src/services/utils.js b/src/services/utils.js index bb7124c..c161b45 100644 --- a/src/services/utils.js +++ b/src/services/utils.js @@ -1,9 +1,9 @@ /* Hummingbot Utils */ -const lodash = require('lodash') -const moment = require('moment') -const { NonceManager } = require('@ethersproject/experimental') +const lodash = require('lodash'); +const moment = require('moment'); +const { NonceManager } = require('@ethersproject/experimental'); export const statusMessages = { ssl_cert_required: 'SSL Certificate required', @@ -13,21 +13,21 @@ export const statusMessages = { invalid_token_symbol: 'Invalid Token Symbol', insufficient_reserves: 'Insufficient Liquidity Reserves', page_not_found: 'Page not found. Invalid path' -} +}; export const latency = (startTime, endTime) => - parseFloat((endTime - startTime) / 1000) + parseFloat((endTime - startTime) / 1000); export const isValidParams = (params) => { - const values = Object.values(params) + const values = Object.values(params); // DO NOT use forEach, it returns callback without breaking the loop for (let i = 0; i < values.length; i++) { if (typeof values[i] === 'undefined') { - throw new Error('Invalid input params') + throw new Error('Invalid input params'); } } - return true -} + return true; +}; export const isValidData = (data, format) => { if ( @@ -35,58 +35,58 @@ export const isValidData = (data, format) => { Object.keys(data).length !== 0 && lodash.isEqual(Object.keys(data).sort(), format.sort()) ) { - return true + return true; } - return false -} + return false; +}; export const getParamData = (data, format = null) => { - const dataObject = {} + const dataObject = {}; if (format !== null) { if (isValidData(data, format)) { format.forEach((key, _index) => { - dataObject[key] = data[key] - }) + dataObject[key] = data[key]; + }); } } else { Object.keys(data).forEach((key, _index) => { - dataObject[key] = data[key] - }) + dataObject[key] = data[key]; + }); } - return dataObject -} + return dataObject; +}; export const splitParamData = (param, separator = ',') => { - const dataArray = param.split(separator) - return dataArray -} + const dataArray = param.split(separator); + return dataArray; +}; export const getSymbols = (tradingPair) => { - const symbols = tradingPair.split('-') + const symbols = tradingPair.split('-'); const baseQuotePair = { base: symbols[0].toUpperCase(), quote: symbols[1].toUpperCase() - } - return baseQuotePair -} + }; + return baseQuotePair; +}; export const reportConnectionError = (res, error) => { res.json({ error: error.errno, code: error.code - }) -} + }); +}; -export const strToDecimal = (str) => parseInt(str) / 100 +export const strToDecimal = (str) => parseInt(str) / 100; export const getHummingbotMemo = () => { - const prefix = 'hbot' - const clientId = process.env.HUMMINGBOT_INSTANCE_ID + const prefix = 'hbot'; + const clientId = process.env.HUMMINGBOT_INSTANCE_ID; if (typeof clientId !== 'undefined' && clientId != null && clientId !== '') { - return [prefix, clientId].join('-') + return [prefix, clientId].join('-'); } - return prefix -} + return prefix; +}; export const loadConfig = () => { const config = { @@ -115,13 +115,13 @@ export const loadConfig = () => { uniswap_router: process.env.UNISWAP_ROUTER, terra_lcd_url: process.env.TERRA_LCD_URL, terra_chain: process.env.TERRA_CHAIN - } - return config -} + }; + return config; +}; export const getLocalDate = () => { - const gmtOffset = process.env.GMT_OFFSET - let newDate = moment().format('YYYY-MM-DD hh:mm:ss').trim() + const gmtOffset = process.env.GMT_OFFSET; + let newDate = moment().format('YYYY-MM-DD hh:mm:ss').trim(); if ( typeof gmtOffset !== 'undefined' && gmtOffset !== null && @@ -130,22 +130,22 @@ export const getLocalDate = () => { newDate = moment() .utcOffset(gmtOffset, false) .format('YYYY-MM-DD hh:mm:ss') - .trim() + .trim(); } - return newDate -} + return newDate; +}; -export const nonceManagerCache = {} +export const nonceManagerCache = {}; export const getNonceManager = async (signer) => { - let key = await signer.getAddress() + let key = await signer.getAddress(); if (signer.provider) { - key += (await signer.provider.getNetwork()).chainId + key += (await signer.provider.getNetwork()).chainId; } - let nonceManager = nonceManagerCache[key] + let nonceManager = nonceManagerCache[key]; if (typeof nonceManager === 'undefined') { - nonceManager = new NonceManager(signer) - nonceManagerCache[key] = nonceManager + nonceManager = new NonceManager(signer); + nonceManagerCache[key] = nonceManager; } - return nonceManager -} + return nonceManager; +}; diff --git a/src/static/abi.js b/src/static/abi.js index ec06099..439080b 100644 --- a/src/static/abi.js +++ b/src/static/abi.js @@ -221,7 +221,7 @@ const ERC20Abi = [ name: 'Transfer', type: 'event' } -] +]; const KovanWETHAbi = [ { @@ -375,12 +375,12 @@ const KovanWETHAbi = [ name: 'Withdrawal', type: 'event' } -] +]; -const KovanFaucetAddress = '0xb48Cc42C45d262534e46d5965a9Ac496F1B7a830' +const KovanFaucetAddress = '0xb48Cc42C45d262534e46d5965a9Ac496F1B7a830'; module.exports = { ERC20Abi, KovanWETHAbi, KovanFaucetAddress -} +}; diff --git a/src/static/uniswap-v3/helper_functions.js b/src/static/uniswap-v3/helper_functions.js index 6015333..7cc3ae1 100644 --- a/src/static/uniswap-v3/helper_functions.js +++ b/src/static/uniswap-v3/helper_functions.js @@ -1,24 +1,24 @@ -import bn from 'bignumber.js' -import JSBI from 'jsbi' -import { BigNumber, mulShift, Q32, ZERO, ONE, MaxUint256 } from 'ethers' +import bn from 'bignumber.js'; +import JSBI from 'jsbi'; +import { BigNumber, mulShift, Q32, ZERO, ONE, MaxUint256 } from 'ethers'; -const math = require('mathjs') +const math = require('mathjs'); -const TICK_SPACINGS = { LOW: 10, MEDIUM: 60, HIGH: 2000 } +const TICK_SPACINGS = { LOW: 10, MEDIUM: 60, HIGH: 2000 }; -bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }) +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }); export function expandTo18Decimals(n) { - return BigNumber.from(n).mul(BigNumber.from(10).pow(18)) + return BigNumber.from(n).mul(BigNumber.from(10).pow(18)); } export function toHex(bigintIsh) { - const bigInt = JSBI.BigInt(bigintIsh) - let hex = bigInt.toString(16) + const bigInt = JSBI.BigInt(bigintIsh); + let hex = bigInt.toString(16); if (hex.length % 2 !== 0) { - hex = `0${hex}` + hex = `0${hex}`; } - return `0x${hex}` + return `0x${hex}`; } // returns the sqrt price as a 64x96 @@ -30,7 +30,7 @@ export function encodePriceSqrt(reserve1, reserve0) { .multipliedBy(new bn(2).pow(96)) .integerValue(3) .toString() - ) + ); } export function getLiquidity(amount0, amount1) { @@ -39,7 +39,7 @@ export function getLiquidity(amount0, amount1) { .multipliedBy(amount1.toString()) .sqrt() .toString() - ) + ); /* let tokenPrice0, tokenPrice1, tokenFraction; tokenFraction = math.fraction(amount1/amount0) tokenPrice0 = encodePriceSqrt(tokenFraction.n, tokenFraction.d) @@ -47,106 +47,106 @@ export function getLiquidity(amount0, amount1) { return tokenPrice0.mul(tokenPrice1) */ } -const TWO = JSBI.BigInt(2) +const TWO = JSBI.BigInt(2); const POWERS_OF_2 = [128, 64, 32, 16, 8, 4, 2, 1].map((pow) => [ pow, JSBI.exponentiate(TWO, JSBI.BigInt(pow)) -]) +]); export function mostSignificantBit(x) { - let y = x - let msb = 0 + let y = x; + let msb = 0; for (const [power, min] of POWERS_OF_2) { if (JSBI.greaterThanOrEqual(y, min)) { - y = JSBI.signedRightShift(y, JSBI.BigInt(power)) - msb += power + y = JSBI.signedRightShift(y, JSBI.BigInt(power)); + msb += power; } } - return msb + return msb; } export function getSqrtRatioAtTick(tick) { - const absTick = tick < 0 ? tick * -1 : tick + const absTick = tick < 0 ? tick * -1 : tick; let ratio = (absTick & 0x1) !== 0 ? JSBI.BigInt('0xfffcb933bd6fad37aa2d162d1a594001') - : JSBI.BigInt('0x100000000000000000000000000000000') + : JSBI.BigInt('0x100000000000000000000000000000000'); if ((absTick & 0x2) !== 0) - ratio = mulShift(ratio, '0xfff97272373d413259a46990580e213a') + ratio = mulShift(ratio, '0xfff97272373d413259a46990580e213a'); if ((absTick & 0x4) !== 0) - ratio = mulShift(ratio, '0xfff2e50f5f656932ef12357cf3c7fdcc') + ratio = mulShift(ratio, '0xfff2e50f5f656932ef12357cf3c7fdcc'); if ((absTick & 0x8) !== 0) - ratio = mulShift(ratio, '0xffe5caca7e10e4e61c3624eaa0941cd0') + ratio = mulShift(ratio, '0xffe5caca7e10e4e61c3624eaa0941cd0'); if ((absTick & 0x10) !== 0) - ratio = mulShift(ratio, '0xffcb9843d60f6159c9db58835c926644') + ratio = mulShift(ratio, '0xffcb9843d60f6159c9db58835c926644'); if ((absTick & 0x20) !== 0) - ratio = mulShift(ratio, '0xff973b41fa98c081472e6896dfb254c0') + ratio = mulShift(ratio, '0xff973b41fa98c081472e6896dfb254c0'); if ((absTick & 0x40) !== 0) - ratio = mulShift(ratio, '0xff2ea16466c96a3843ec78b326b52861') + ratio = mulShift(ratio, '0xff2ea16466c96a3843ec78b326b52861'); if ((absTick & 0x80) !== 0) - ratio = mulShift(ratio, '0xfe5dee046a99a2a811c461f1969c3053') + ratio = mulShift(ratio, '0xfe5dee046a99a2a811c461f1969c3053'); if ((absTick & 0x100) !== 0) - ratio = mulShift(ratio, '0xfcbe86c7900a88aedcffc83b479aa3a4') + ratio = mulShift(ratio, '0xfcbe86c7900a88aedcffc83b479aa3a4'); if ((absTick & 0x200) !== 0) - ratio = mulShift(ratio, '0xf987a7253ac413176f2b074cf7815e54') + ratio = mulShift(ratio, '0xf987a7253ac413176f2b074cf7815e54'); if ((absTick & 0x400) !== 0) - ratio = mulShift(ratio, '0xf3392b0822b70005940c7a398e4b70f3') + ratio = mulShift(ratio, '0xf3392b0822b70005940c7a398e4b70f3'); if ((absTick & 0x800) !== 0) - ratio = mulShift(ratio, '0xe7159475a2c29b7443b29c7fa6e889d9') + ratio = mulShift(ratio, '0xe7159475a2c29b7443b29c7fa6e889d9'); if ((absTick & 0x1000) !== 0) - ratio = mulShift(ratio, '0xd097f3bdfd2022b8845ad8f792aa5825') + ratio = mulShift(ratio, '0xd097f3bdfd2022b8845ad8f792aa5825'); if ((absTick & 0x2000) !== 0) - ratio = mulShift(ratio, '0xa9f746462d870fdf8a65dc1f90e061e5') + ratio = mulShift(ratio, '0xa9f746462d870fdf8a65dc1f90e061e5'); if ((absTick & 0x4000) !== 0) - ratio = mulShift(ratio, '0x70d869a156d2a1b890bb3df62baf32f7') + ratio = mulShift(ratio, '0x70d869a156d2a1b890bb3df62baf32f7'); if ((absTick & 0x8000) !== 0) - ratio = mulShift(ratio, '0x31be135f97d08fd981231505542fcfa6') + ratio = mulShift(ratio, '0x31be135f97d08fd981231505542fcfa6'); if ((absTick & 0x10000) !== 0) - ratio = mulShift(ratio, '0x9aa508b5b7a84e1c677de54f3e99bc9') + ratio = mulShift(ratio, '0x9aa508b5b7a84e1c677de54f3e99bc9'); if ((absTick & 0x20000) !== 0) - ratio = mulShift(ratio, '0x5d6af8dedb81196699c329225ee604') + ratio = mulShift(ratio, '0x5d6af8dedb81196699c329225ee604'); if ((absTick & 0x40000) !== 0) - ratio = mulShift(ratio, '0x2216e584f5fa1ea926041bedfe98') + ratio = mulShift(ratio, '0x2216e584f5fa1ea926041bedfe98'); if ((absTick & 0x80000) !== 0) - ratio = mulShift(ratio, '0x48a170391f7dc42444e8fa2') + ratio = mulShift(ratio, '0x48a170391f7dc42444e8fa2'); - if (tick > 0) ratio = JSBI.divide(MaxUint256, ratio) + if (tick > 0) ratio = JSBI.divide(MaxUint256, ratio); // back to Q96 return JSBI.greaterThan(JSBI.remainder(ratio, Q32), ZERO) ? JSBI.add(JSBI.divide(ratio, Q32), ONE) - : JSBI.divide(ratio, Q32) + : JSBI.divide(ratio, Q32); } export function getTickAtSqrtRatio(sqrtRatioX96) { - const sqrtRatioX128 = JSBI.leftShift(sqrtRatioX96, JSBI.BigInt(32)) + const sqrtRatioX128 = JSBI.leftShift(sqrtRatioX96, JSBI.BigInt(32)); - const msb = mostSignificantBit(sqrtRatioX128) + const msb = mostSignificantBit(sqrtRatioX128); - let r + let r; if (JSBI.greaterThanOrEqual(JSBI.BigInt(msb), JSBI.BigInt(128))) { - r = JSBI.signedRightShift(sqrtRatioX128, JSBI.BigInt(msb - 127)) + r = JSBI.signedRightShift(sqrtRatioX128, JSBI.BigInt(msb - 127)); } else { - r = JSBI.leftShift(sqrtRatioX128, JSBI.BigInt(127 - msb)) + r = JSBI.leftShift(sqrtRatioX128, JSBI.BigInt(127 - msb)); } let log_2 = JSBI.leftShift( JSBI.subtract(JSBI.BigInt(msb), JSBI.BigInt(128)), JSBI.BigInt(64) - ) + ); for (let i = 0; i < 14; i++) { - r = JSBI.signedRightShift(JSBI.multiply(r, r), JSBI.BigInt(127)) - const f = JSBI.signedRightShift(r, JSBI.BigInt(128)) - log_2 = JSBI.bitwiseOr(log_2, JSBI.leftShift(f, JSBI.BigInt(63 - i))) - r = JSBI.signedRightShift(r, f) + r = JSBI.signedRightShift(JSBI.multiply(r, r), JSBI.BigInt(127)); + const f = JSBI.signedRightShift(r, JSBI.BigInt(128)); + log_2 = JSBI.bitwiseOr(log_2, JSBI.leftShift(f, JSBI.BigInt(63 - i))); + r = JSBI.signedRightShift(r, f); } const log_sqrt10001 = JSBI.multiply( log_2, JSBI.BigInt('255738958999603826347141') - ) + ); const tickLow = JSBI.toNumber( JSBI.signedRightShift( @@ -156,7 +156,7 @@ export function getTickAtSqrtRatio(sqrtRatioX96) { ), JSBI.BigInt(128) ) - ) + ); const tickHigh = JSBI.toNumber( JSBI.signedRightShift( JSBI.add( @@ -165,42 +165,42 @@ export function getTickAtSqrtRatio(sqrtRatioX96) { ), JSBI.BigInt(128) ) - ) + ); if (tickLow === tickHigh) { - return tickLow + return tickLow; } return JSBI.lessThanOrEqual(getSqrtRatioAtTick(tickHigh), sqrtRatioX96) ? tickHigh - : tickLow + : tickLow; } export function getMinTick(tier) { - return Math.ceil(-887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier] + return Math.ceil(-887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; } export function getMaxTick(tier) { - return Math.floor(887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier] + return Math.floor(887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; } export function getTickFromPrice(price, tier, side) { - let tick = 0 + let tick = 0; if (side === 'UPPER') { tick = math.ceil(math.log(price, 1.0001) / TICK_SPACINGS[tier]) * - TICK_SPACINGS[tier] + TICK_SPACINGS[tier]; } else { tick = math.floor(math.log(price, 1.0001) / TICK_SPACINGS[tier]) * - TICK_SPACINGS[tier] + TICK_SPACINGS[tier]; } if (tick >= getMaxTick(tier)) { - return getMaxTick(tier) + return getMaxTick(tier); } if (tick <= getMinTick(tier)) { - return getMinTick(tier) + return getMinTick(tier); } - return tick + return tick; } diff --git a/yarn.lock b/yarn.lock index 5435848..5190a68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,7 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.12.13": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== @@ -271,7 +271,7 @@ regenerator-runtime "^0.13.4" v8flags "^3.1.1" -"@babel/parser@^7.12.13", "@babel/parser@^7.14.2", "@babel/parser@^7.14.3": +"@babel/parser@^7.12.13", "@babel/parser@^7.14.2", "@babel/parser@^7.14.3", "@babel/parser@^7.7.0": version "7.14.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.4.tgz#a5c560d6db6cd8e6ed342368dea8039232cbab18" integrity sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA== @@ -876,7 +876,7 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2": +"@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2", "@babel/traverse@^7.7.0": version "7.14.2" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b" integrity sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA== @@ -890,7 +890,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.2", "@babel/types@^7.14.4", "@babel/types@^7.4.4": +"@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.2", "@babel/types@^7.14.4", "@babel/types@^7.4.4", "@babel/types@^7.7.0": version "7.14.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.4.tgz#bfd6980108168593b38b3eb48a24aa026b919bc0" integrity sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw== @@ -1594,6 +1594,18 @@ axios@^0.21.1: dependencies: follow-redirects "^1.10.0" +babel-eslint@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" + integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" + babel-plugin-dynamic-import-node@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" @@ -2015,11 +2027,6 @@ configstore@^5.0.1: write-file-atomic "^3.0.0" xdg-basedir "^4.0.0" -confusing-browser-globals@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz#30d1e7f3d1b882b25ec4933d1d1adac353d20a59" - integrity sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA== - content-disposition@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" @@ -2359,24 +2366,15 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-config-airbnb-base@^14.2.1: - version "14.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" - integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.2" - eslint-config-prettier@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== -eslint-config-standard@^14.1.1: - version "14.1.1" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" - integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg== +eslint-config-standard@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz#6c8761e544e96c531ff92642eeb87842b8488516" + integrity sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg== eslint-import-resolver-node@^0.3.4: version "0.3.4" @@ -2402,7 +2400,7 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@^2.23.3: +eslint-plugin-import@^2.23.4: version "2.23.4" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz#8dceb1ed6b73e46e50ec9a5bb2411b645e7d3d97" integrity sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ== @@ -2442,10 +2440,10 @@ eslint-plugin-prettier@^3.4.0: dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-promise@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz#61485df2a359e03149fdafc0a68b0e030ad2ac45" - integrity sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ== +eslint-plugin-promise@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz#fb2188fb734e4557993733b41aa1a688f46c6f24" + integrity sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng== eslint-plugin-standard@^4.0.1: version "4.1.0" @@ -2467,7 +2465,7 @@ eslint-utils@^2.0.0, eslint-utils@^2.1.0: dependencies: eslint-visitor-keys "^1.1.0" -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== @@ -3822,15 +3820,6 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.entries@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd" - integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.18.2" - object.getownpropertydescriptors@^2.0.3: version "2.1.2" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" @@ -4305,7 +4294,7 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.20.0: +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== From e41020ba434faf3f767a8e12a6d026fda83318be Mon Sep 17 00:00:00 2001 From: james-hummingbot Date: Fri, 4 Jun 2021 10:21:50 +0200 Subject: [PATCH 28/31] Apply prettier to test files --- .prettierignore | 1 - package.json | 2 +- ...eway-Ethereum-Base.postman_collection.json | 2441 ++++++++--------- .../Gateway-Terra.postman_collection.json | 635 +++-- test/postman/PERPFI.postman_collection.json | 836 +++--- .../Uniswap_V3_postman_collection.json | 960 +++---- test/postman/terra.postman_environment.json | 56 +- .../v2/Gateway.postman_collection.json | 1875 ++++++------- .../v2/Gateway.postman_environment.json | 66 +- 9 files changed, 3249 insertions(+), 3623 deletions(-) diff --git a/.prettierignore b/.prettierignore index b4d36e3..426ed2f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,3 @@ -test certs *.md *.yml \ No newline at end of file diff --git a/package.json b/package.json index 55933c6..bedb73a 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "start": "babel-node src/index.js", "dev": "nodemon --exec babel-node src/index.js", "debug": "DEBUG=*router nodemon --exec babel-node src/index.js", - "lint": "node_modules/.bin/eslint src --format table", + "lint": "node_modules/.bin/eslint src test --format table", "prettier": "node_modules/.bin/prettier . --write", "test": "echo \"Error: no test specified\" && exit 1" }, diff --git a/test/postman/Gateway-Ethereum-Base.postman_collection.json b/test/postman/Gateway-Ethereum-Base.postman_collection.json index 20622ac..1910611 100644 --- a/test/postman/Gateway-Ethereum-Base.postman_collection.json +++ b/test/postman/Gateway-Ethereum-Base.postman_collection.json @@ -1,1264 +1,1179 @@ { - "info": { - "_postman_id": "e39af94e-6095-479e-8ba0-66930b12e364", - "name": "Gateway-Ethereum-Base", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "ethereum", - "item": [ - { - "name": "eth/balances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenAddressList", - "value": "{ \"{{WETH}}\": 18, \"{{DAI}}\": 18}", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "eth/allowances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenAddressList", - "value": "{ \"{{BAT}}\": 18, \"{{DAI}}\": 18 }", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/allowances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "allowances" - ] - } - }, - "response": [] - }, - { - "name": "eth/approve", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenAddress", - "value": "{{WETH}}", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "gasPrice", - "value": "23", - "type": "text" - }, - { - "key": "decimals", - "value": "18", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "amount", - "value": "999999", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/approve", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "approve" - ] - } - }, - "response": [] - }, - { - "name": "eth/get-weth", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "gasPrice", - "value": "31", - "type": "text" - }, - { - "key": "amount", - "value": "0.03", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "tokenAddress", - "value": "{{WETH}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/get-weth", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "get-weth" - ] - } - }, - "response": [] - }, - { - "name": "eth/get-receipt", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "txHash", - "value": "{{txHash}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/get-receipt", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "get-receipt" - ] - } - }, - "response": [] - } - ], - "protocolProfileBehavior": {} - }, - { - "name": "balancer", - "item": [ - { - "name": "balancer", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/balancer", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer" - ] - } - }, - "response": [] - }, - { - "name": "balancer/gas-limit", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "maxSwaps", - "value": "3", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/gas-limit", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "gas-limit" - ] - } - }, - "response": [] - }, - { - "name": "balancer/buy-price/", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "maxSwaps", - "value": "4", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/buy-price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "buy-price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "balancer/sell-price/", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "maxSwaps", - "value": "4", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/sell-price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "sell-price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "balancer/buy", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "maxSwaps", - "value": "4", - "type": "text" - }, - { - "key": "maxPrice", - "value": "0.19767217120251", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/buy", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "buy" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "balancer/sell", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "0.1", - "type": "text" - }, - { - "key": "maxSwaps", - "value": "4", - "type": "text" - }, - { - "key": "maxPrice", - "value": "0.2685681573104575", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/balancer/sell", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "balancer", - "sell" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - } - ], - "protocolProfileBehavior": {} - }, - { - "name": "uniswap", - "item": [ - { - "name": "uniswap", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/uniswap", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "uniswap" - ] - } - }, - "response": [] - }, - { - "name": "uniswap/gas-limit", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/uniswap/gas-limit", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "uniswap", - "gas-limit" - ] - } - }, - "response": [] - }, - { - "name": "uniswap/buy-price/", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/uniswap/buy-price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "uniswap", - "buy-price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "uniswap/sell-price/", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "{{BAT}}", - "type": "text" - }, - { - "key": "quote", - "value": "{{DAI}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "base_decimals", - "value": "18", - "type": "text" - }, - { - "key": "quote_decimals", - "value": "18", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/uniswap/sell-price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "uniswap", - "sell-price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - } - ], - "protocolProfileBehavior": {} - } - ], - "protocolProfileBehavior": {} -} \ No newline at end of file + "info": { + "_postman_id": "e39af94e-6095-479e-8ba0-66930b12e364", + "name": "Gateway-Ethereum-Base", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "ethereum", + "item": [ + { + "name": "eth/balances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenAddressList", + "value": "{ \"{{WETH}}\": 18, \"{{DAI}}\": 18}", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balances", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "balances"] + } + }, + "response": [] + }, + { + "name": "eth/allowances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenAddressList", + "value": "{ \"{{BAT}}\": 18, \"{{DAI}}\": 18 }", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/allowances", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "allowances"] + } + }, + "response": [] + }, + { + "name": "eth/approve", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenAddress", + "value": "{{WETH}}", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "gasPrice", + "value": "23", + "type": "text" + }, + { + "key": "decimals", + "value": "18", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "amount", + "value": "999999", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/approve", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "approve"] + } + }, + "response": [] + }, + { + "name": "eth/get-weth", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "31", + "type": "text" + }, + { + "key": "amount", + "value": "0.03", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "tokenAddress", + "value": "{{WETH}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/get-weth", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "get-weth"] + } + }, + "response": [] + }, + { + "name": "eth/get-receipt", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "txHash", + "value": "{{txHash}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/get-receipt", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "get-receipt"] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "balancer", + "item": [ + { + "name": "balancer", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/balancer", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["balancer"] + } + }, + "response": [] + }, + { + "name": "balancer/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "maxSwaps", + "value": "3", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/gas-limit", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["balancer", "gas-limit"] + } + }, + "response": [] + }, + { + "name": "balancer/buy-price/", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "maxSwaps", + "value": "4", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/buy-price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["balancer", "buy-price"] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": ["localhost"], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "balancer/sell-price/", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "maxSwaps", + "value": "4", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/sell-price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["balancer", "sell-price"] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": ["localhost"], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "balancer/buy", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "maxSwaps", + "value": "4", + "type": "text" + }, + { + "key": "maxPrice", + "value": "0.19767217120251", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/buy", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["balancer", "buy"] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": ["localhost"], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "balancer/sell", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "0.1", + "type": "text" + }, + { + "key": "maxSwaps", + "value": "4", + "type": "text" + }, + { + "key": "maxPrice", + "value": "0.2685681573104575", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/balancer/sell", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["balancer", "sell"] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": ["localhost"], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "uniswap", + "item": [ + { + "name": "uniswap", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/uniswap", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["uniswap"] + } + }, + "response": [] + }, + { + "name": "uniswap/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/uniswap/gas-limit", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["uniswap", "gas-limit"] + } + }, + "response": [] + }, + { + "name": "uniswap/buy-price/", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/uniswap/buy-price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["uniswap", "buy-price"] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": ["localhost"], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "uniswap/sell-price/", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "{{BAT}}", + "type": "text" + }, + { + "key": "quote", + "value": "{{DAI}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "base_decimals", + "value": "18", + "type": "text" + }, + { + "key": "quote_decimals", + "value": "18", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/uniswap/sell-price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["uniswap", "sell-price"] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": ["localhost"], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + } + ], + "protocolProfileBehavior": {} + } + ], + "protocolProfileBehavior": {} +} diff --git a/test/postman/Gateway-Terra.postman_collection.json b/test/postman/Gateway-Terra.postman_collection.json index 40866b8..ce18b1d 100644 --- a/test/postman/Gateway-Terra.postman_collection.json +++ b/test/postman/Gateway-Terra.postman_collection.json @@ -1,328 +1,309 @@ { - "info": { - "_postman_id": "3cca9e73-0e1f-4e4f-8973-87c985a43219", - "name": "Gateway-Terra", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "terra", - "item": [ - { - "name": "terra/balances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "address", - "value": "{{address}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/terra/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "terra/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "SDT", - "type": "text" - }, - { - "key": "quote", - "value": "KRT", - "type": "text" - }, - { - "key": "trade_type", - "value": "buy", - "type": "text" - }, - { - "key": "amount", - "value": "3", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "price" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - }, - { - "name": "terra/trade", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "SDT", - "type": "text" - }, - { - "key": "quote", - "value": "KRT", - "type": "text" - }, - { - "key": "trade_type", - "value": "buy", - "type": "text" - }, - { - "key": "amount", - "value": "3", - "type": "text" - }, - { - "key": "secret", - "value": "{{secret}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/trade", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "trade" - ] - } - }, - "response": [ - { - "name": "{network}/quote", - "originalRequest": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "5000", - "path": [ - "{{network}}", - "quote", - "trading_pair", - "{{celo-cusd}}", - "amount", - "1" - ] - } - }, - "status": "OK", - "code": 200, - "_postman_previewlanguage": "json", - "header": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" - }, - { - "key": "X-DNS-Prefetch-Control", - "value": "off" - }, - { - "key": "Expect-CT", - "value": "max-age=0" - }, - { - "key": "X-Frame-Options", - "value": "SAMEORIGIN" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=15552000; includeSubDomains" - }, - { - "key": "X-Download-Options", - "value": "noopen" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "X-Permitted-Cross-Domain-Policies", - "value": "none" - }, - { - "key": "Referrer-Policy", - "value": "no-referrer" - }, - { - "key": "X-XSS-Protection", - "value": "0" - }, - { - "key": "Content-Type", - "value": "application/json; charset=utf-8" - }, - { - "key": "Content-Length", - "value": "97" - }, - { - "key": "ETag", - "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" - }, - { - "key": "Date", - "value": "Wed, 23 Sep 2020 18:07:26 GMT" - }, - { - "key": "Connection", - "value": "keep-alive" - } - ], - "cookie": [], - "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" - } - ] - } - ], - "protocolProfileBehavior": {} - } - ], - "protocolProfileBehavior": {} -} \ No newline at end of file + "info": { + "_postman_id": "3cca9e73-0e1f-4e4f-8973-87c985a43219", + "name": "Gateway-Terra", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "terra", + "item": [ + { + "name": "terra/balances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "address", + "value": "{{address}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/terra/balances", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["terra", "balances"] + } + }, + "response": [] + }, + { + "name": "terra/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "SDT", + "type": "text" + }, + { + "key": "quote", + "value": "KRT", + "type": "text" + }, + { + "key": "trade_type", + "value": "buy", + "type": "text" + }, + { + "key": "amount", + "value": "3", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["terra", "price"] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": ["localhost"], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + }, + { + "name": "terra/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "SDT", + "type": "text" + }, + { + "key": "quote", + "value": "KRT", + "type": "text" + }, + { + "key": "trade_type", + "value": "buy", + "type": "text" + }, + { + "key": "amount", + "value": "3", + "type": "text" + }, + { + "key": "secret", + "value": "{{secret}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/trade", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["terra", "trade"] + } + }, + "response": [ + { + "name": "{network}/quote", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:5000/{{network}}/quote/trading_pair/{{celo-cusd}}/amount/1", + "protocol": "http", + "host": ["localhost"], + "port": "5000", + "path": [ + "{{network}}", + "quote", + "trading_pair", + "{{celo-cusd}}", + "amount", + "1" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + }, + { + "key": "X-DNS-Prefetch-Control", + "value": "off" + }, + { + "key": "Expect-CT", + "value": "max-age=0" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=15552000; includeSubDomains" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-XSS-Protection", + "value": "0" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "97" + }, + { + "key": "ETag", + "value": "W/\"61-Wemp9YmP9g/CsUFMa7Y5zK6SoLQ\"" + }, + { + "key": "Date", + "value": "Wed, 23 Sep 2020 18:07:26 GMT" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"timestamp\": 1600884444051,\n \"latency\": 2.542,\n \"trading_pair\": \"CELO-CUSD\",\n \"price\": 2.5435604641582747\n}" + } + ] + } + ], + "protocolProfileBehavior": {} + } + ], + "protocolProfileBehavior": {} +} diff --git a/test/postman/PERPFI.postman_collection.json b/test/postman/PERPFI.postman_collection.json index 513a083..5445efa 100644 --- a/test/postman/PERPFI.postman_collection.json +++ b/test/postman/PERPFI.postman_collection.json @@ -1,454 +1,384 @@ { - "info": { - "_postman_id": "08bf4528-5e70-42cd-bf71-b97f81088b9c", - "name": "PERPFI", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "default", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "https://localhost:{{port}}/perpfi/", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/load-metadata", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "https://localhost:{{port}}/perpfi/load-metadata", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "load-metadata" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/pairs", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "https://localhost:{{port}}/perpfi/pairs", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "pairs" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/balances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/allowances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/allowances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "allowances" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/approve", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/approve", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "approve" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/open", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "margin", - "value": "15", - "type": "text" - }, - { - "key": "leverage", - "value": "2", - "type": "text" - }, - { - "key": "side", - "value": "{{SHORT}}", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/open", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "open" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/close", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/close", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "close" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/receipt", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "txHash", - "value": "0xd29120d947319c880f68a44b897c733c07ec313d670a7df55e523b501d7a03a2", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/receipt", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "receipt" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/position", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/position", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "position" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/margin", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/margin", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "margin" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/pnl", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/pnl", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "pnl" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/funding", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/funding", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "funding" - ] - } - }, - "response": [] - }, - { - "name": "perpfi/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "side", - "value": "buy", - "type": "text" - }, - { - "key": "pair", - "value": "SNXUSDC", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/perpfi/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "perpfi", - "price" - ] - } - }, - "response": [] - } - ] -} \ No newline at end of file + "info": { + "_postman_id": "08bf4528-5e70-42cd-bf71-b97f81088b9c", + "name": "PERPFI", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "default", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:{{port}}/perpfi/", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", ""] + } + }, + "response": [] + }, + { + "name": "perpfi/load-metadata", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:{{port}}/perpfi/load-metadata", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "load-metadata"] + } + }, + "response": [] + }, + { + "name": "perpfi/pairs", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:{{port}}/perpfi/pairs", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "pairs"] + } + }, + "response": [] + }, + { + "name": "perpfi/balances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/balances", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "balances"] + } + }, + "response": [] + }, + { + "name": "perpfi/allowances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/allowances", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "allowances"] + } + }, + "response": [] + }, + { + "name": "perpfi/approve", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/approve", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "approve"] + } + }, + "response": [] + }, + { + "name": "perpfi/open", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "margin", + "value": "15", + "type": "text" + }, + { + "key": "leverage", + "value": "2", + "type": "text" + }, + { + "key": "side", + "value": "{{SHORT}}", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/open", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "open"] + } + }, + "response": [] + }, + { + "name": "perpfi/close", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/close", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "close"] + } + }, + "response": [] + }, + { + "name": "perpfi/receipt", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "txHash", + "value": "0xd29120d947319c880f68a44b897c733c07ec313d670a7df55e523b501d7a03a2", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/receipt", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "receipt"] + } + }, + "response": [] + }, + { + "name": "perpfi/position", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/position", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "position"] + } + }, + "response": [] + }, + { + "name": "perpfi/margin", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/margin", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "margin"] + } + }, + "response": [] + }, + { + "name": "perpfi/pnl", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/pnl", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "pnl"] + } + }, + "response": [] + }, + { + "name": "perpfi/funding", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/funding", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "funding"] + } + }, + "response": [] + }, + { + "name": "perpfi/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "side", + "value": "buy", + "type": "text" + }, + { + "key": "pair", + "value": "SNXUSDC", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/perpfi/price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["perpfi", "price"] + } + }, + "response": [] + } + ] +} diff --git a/test/postman/Uniswap_V3_postman_collection.json b/test/postman/Uniswap_V3_postman_collection.json index 877abbd..9cccb68 100644 --- a/test/postman/Uniswap_V3_postman_collection.json +++ b/test/postman/Uniswap_V3_postman_collection.json @@ -1,518 +1,444 @@ { - "info": { - "_postman_id": "5de36bfa-027e-46e3-810d-219e42c75314", - "name": "Uniswap V3", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "uniswap v3 endpoints", - "item": [ - { - "name": "eth/uniswap/v3", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/v3/gas-limit", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/gas-limit", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3", - "gas-limit" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/v3/result", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/result?logs=§ion=lp", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3", - "result" - ], - "query": [ - { - "key": "logs", - "value": "" - }, - { - "key": "section", - "value": "lp" - } - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/v3/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "COIN1", - "type": "text" - }, - { - "key": "quote", - "value": "COIN2", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3", - "price" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/v3/trade", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "COIN1", - "type": "text" - }, - { - "key": "quote", - "value": "COIN2", - "type": "text" - }, - { - "key": "amount", - "value": "0.000009", - "type": "text" - }, - { - "key": "limitPrice", - "value": "0.000000000025", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text", - "disabled": true - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "side", - "value": "buy", - "type": "text" - }, - { - "key": "tier", - "value": "HIGH", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/trade", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3", - "trade" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/v3/position", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenId", - "value": "66", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text", - "disabled": true - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/position", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3", - "position" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/v3/add-position", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "gasPrice", - "value": "37", - "type": "text", - "disabled": true - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "token0", - "value": "DAI", - "type": "text" - }, - { - "key": "token1", - "value": "USDC", - "type": "text" - }, - { - "key": "fee", - "value": "LOW", - "type": "text" - }, - { - "key": "lowerPrice", - "value": "1561", - "type": "text" - }, - { - "key": "upperPrice", - "value": "1570", - "type": "text" - }, - { - "key": "amount0", - "value": "2", - "type": "text" - }, - { - "key": "amount1", - "value": "2", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/add-position", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3", - "add-position" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/v3/replace-position", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "gasPrice", - "value": "37", - "type": "text", - "disabled": true - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "token0", - "value": "COIN1", - "type": "text" - }, - { - "key": "token1", - "value": "COIN2", - "type": "text" - }, - { - "key": "fee", - "value": "MEDIUM", - "type": "text" - }, - { - "key": "lowerPrice", - "value": "6", - "type": "text" - }, - { - "key": "upperPrice", - "value": "20", - "type": "text" - }, - { - "key": "amount0", - "value": "2", - "type": "text" - }, - { - "key": "amount1", - "value": "2", - "type": "text" - }, - { - "key": "tokenId", - "value": "69", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/replace-position", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3", - "replace-position" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/v3/collect-fees", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "gasPrice", - "value": "37", - "type": "text", - "disabled": true - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "tokenId", - "value": "44", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3//collect-fees", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3", - "", - "collect-fees" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/v3/remove-position", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "gasPrice", - "value": "37", - "type": "text", - "disabled": true - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "tokenId", - "value": "66", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/v3/remove-position", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "v3", - "remove-position" - ] - } - }, - "response": [] - } - ], - "event": [ - { - "listen": "prerequest", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - }, - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ] - } - ] -} \ No newline at end of file + "info": { + "_postman_id": "5de36bfa-027e-46e3-810d-219e42c75314", + "name": "Uniswap V3", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "uniswap v3 endpoints", + "item": [ + { + "name": "eth/uniswap/v3", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/gas-limit", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3", "gas-limit"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/result", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/result?logs=§ion=lp", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3", "result"], + "query": [ + { + "key": "logs", + "value": "" + }, + { + "key": "section", + "value": "lp" + } + ] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "COIN1", + "type": "text" + }, + { + "key": "quote", + "value": "COIN2", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3", "price"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "COIN1", + "type": "text" + }, + { + "key": "quote", + "value": "COIN2", + "type": "text" + }, + { + "key": "amount", + "value": "0.000009", + "type": "text" + }, + { + "key": "limitPrice", + "value": "0.000000000025", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + }, + { + "key": "tier", + "value": "HIGH", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/trade", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3", "trade"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/position", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenId", + "value": "66", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/position", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3", "position"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/add-position", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "token0", + "value": "DAI", + "type": "text" + }, + { + "key": "token1", + "value": "USDC", + "type": "text" + }, + { + "key": "fee", + "value": "LOW", + "type": "text" + }, + { + "key": "lowerPrice", + "value": "1561", + "type": "text" + }, + { + "key": "upperPrice", + "value": "1570", + "type": "text" + }, + { + "key": "amount0", + "value": "2", + "type": "text" + }, + { + "key": "amount1", + "value": "2", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/add-position", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3", "add-position"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/replace-position", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "token0", + "value": "COIN1", + "type": "text" + }, + { + "key": "token1", + "value": "COIN2", + "type": "text" + }, + { + "key": "fee", + "value": "MEDIUM", + "type": "text" + }, + { + "key": "lowerPrice", + "value": "6", + "type": "text" + }, + { + "key": "upperPrice", + "value": "20", + "type": "text" + }, + { + "key": "amount0", + "value": "2", + "type": "text" + }, + { + "key": "amount1", + "value": "2", + "type": "text" + }, + { + "key": "tokenId", + "value": "69", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/replace-position", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3", "replace-position"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/collect-fees", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "tokenId", + "value": "44", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3//collect-fees", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3", "", "collect-fees"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/v3/remove-position", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "37", + "type": "text", + "disabled": true + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "tokenId", + "value": "66", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/v3/remove-position", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "v3", "remove-position"] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [""] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [""] + } + } + ] + } + ] +} diff --git a/test/postman/terra.postman_environment.json b/test/postman/terra.postman_environment.json index 735927a..eb95c30 100644 --- a/test/postman/terra.postman_environment.json +++ b/test/postman/terra.postman_environment.json @@ -1,29 +1,29 @@ { - "id": "aebe7d1f-0e85-4441-8679-2ddc38d74350", - "name": "terra", - "values": [ - { - "key": "protocol", - "value": "terra", - "enabled": true - }, - { - "key": "port", - "value": "5000", - "enabled": true - }, - { - "key": "address", - "value": "myaddresss", - "enabled": true - }, - { - "key": "secret", - "value": "mysupersecret", - "enabled": true - } - ], - "_postman_variable_scope": "environment", - "_postman_exported_at": "2020-11-13T06:00:14.142Z", - "_postman_exported_using": "Postman/7.35.0" -} \ No newline at end of file + "id": "aebe7d1f-0e85-4441-8679-2ddc38d74350", + "name": "terra", + "values": [ + { + "key": "protocol", + "value": "terra", + "enabled": true + }, + { + "key": "port", + "value": "5000", + "enabled": true + }, + { + "key": "address", + "value": "myaddresss", + "enabled": true + }, + { + "key": "secret", + "value": "mysupersecret", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2020-11-13T06:00:14.142Z", + "_postman_exported_using": "Postman/7.35.0" +} diff --git a/test/postman/v2/Gateway.postman_collection.json b/test/postman/v2/Gateway.postman_collection.json index 949efe0..a84fe12 100644 --- a/test/postman/v2/Gateway.postman_collection.json +++ b/test/postman/v2/Gateway.postman_collection.json @@ -1,1001 +1,876 @@ { - "info": { - "_postman_id": "e39af94e-6095-479e-8ba0-66930b12e364", - "name": "Gateway", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "v2", - "item": [ - { - "name": "ethereum", - "item": [ - { - "name": "eth", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth" - ] - } - }, - "response": [] - }, - { - "name": "eth/balances", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenList", - "value": "[\"BAT\",\"USDC\",\"DAI\",\"WETH\",\"ZRX\"]", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "eth/allowances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "tokenList", - "value": "[\"BAT\",\"USDC\",\"DAI\",\"WETH\",\"ZRX\"]", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/allowances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "allowances" - ] - } - }, - "response": [] - }, - { - "name": "eth/approve", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "token", - "value": "ZRX", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "gasPrice", - "value": "23", - "type": "text" - }, - { - "key": "connector", - "value": "balancer", - "type": "text" - }, - { - "key": "amount", - "value": "999", - "type": "text", - "disabled": true - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/approve", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "approve" - ] - } - }, - "response": [] - }, - { - "name": "eth/get-weth", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "gasPrice", - "value": "31", - "type": "text" - }, - { - "key": "amount", - "value": "0.03", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "tokenAddress", - "value": "{{WETH}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/get-weth", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "get-weth" - ] - } - }, - "response": [] - }, - { - "name": "eth/poll", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "txHash", - "value": "{{txHash}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/poll", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "poll" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "balancer", - "item": [ - { - "name": "eth/balancer", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer" - ] - } - }, - "response": [] - }, - { - "name": "eth/balancer/gas-limit", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer/gas-limit", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer", - "gas-limit" - ] - } - }, - "response": [] - }, - { - "name": "eth/balancer/start", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "BAT", - "type": "text" - }, - { - "key": "quote", - "value": "dai", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "approvalAmount", - "value": "1", - "type": "text", - "disabled": true - }, - { - "key": "gasPrice", - "value": "50", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer/start", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer", - "start" - ] - } - }, - "response": [] - }, - { - "name": "eth/balancer/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "BAT", - "type": "text" - }, - { - "key": "quote", - "value": "dai", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "side", - "value": "buy", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer", - "price" - ] - } - }, - "response": [] - }, - { - "name": "eth/balancer/trade", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "BAT", - "type": "text" - }, - { - "key": "quote", - "value": "USDC", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "limitPrice", - "value": "0.19767217120251", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "side", - "value": "sell", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/balancer/trade", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "balancer", - "trade" - ] - } - }, - "response": [] - } - ], - "event": [ - { - "listen": "prerequest", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - }, - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ] - }, - { - "name": "uniswap", - "item": [ - { - "name": "eth/uniswap", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/gas-limit", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/gas-limit", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "gas-limit" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/start", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "WETH", - "type": "text" - }, - { - "key": "quote", - "value": "USDC", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "approvalAmount", - "value": "1", - "type": "text", - "disabled": true - }, - { - "key": "gasPrice", - "value": "50", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/start", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "start" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "WETH", - "type": "text" - }, - { - "key": "quote", - "value": "DAI", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "side", - "value": "buy", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "price" - ] - } - }, - "response": [] - }, - { - "name": "eth/uniswap/trade", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "BAT", - "type": "text" - }, - { - "key": "quote", - "value": "DAI", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - }, - { - "key": "limitPrice", - "value": "0.19767217120251", - "type": "text" - }, - { - "key": "gasPrice", - "value": "37", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{privateKey}}", - "type": "text" - }, - { - "key": "side", - "value": "sell", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/eth/uniswap/trade", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "eth", - "uniswap", - "trade" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "terra", - "item": [ - { - "name": "terra", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "address", - "value": "{{address}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/terra", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra" - ] - } - }, - "response": [] - }, - { - "name": "terra/balances", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "address", - "value": "{{terraWalletAddress}}", - "type": "text" - } - ], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/terra/balances", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "balances" - ] - } - }, - "response": [] - }, - { - "name": "terra/start", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "LUNA", - "type": "text" - }, - { - "key": "quote", - "value": "UST", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/start", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "start" - ] - } - }, - "response": [] - }, - { - "name": "terra/price", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "UST", - "type": "text" - }, - { - "key": "quote", - "value": "KRT", - "type": "text" - }, - { - "key": "side", - "value": "buy", - "type": "text" - }, - { - "key": "amount", - "value": "1", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/price", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "price" - ] - } - }, - "response": [] - }, - { - "name": "terra/trade", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "base", - "value": "UST", - "type": "text" - }, - { - "key": "quote", - "value": "KRT", - "type": "text" - }, - { - "key": "side", - "value": "buy", - "type": "text" - }, - { - "key": "amount", - "value": "10", - "type": "text" - }, - { - "key": "privateKey", - "value": "{{terraSeeds}}", - "type": "text" - } - ] - }, - "url": { - "raw": "https://localhost:{{port}}/terra/trade", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "terra", - "trade" - ] - } - }, - "response": [] - } - ] - } - ] - }, - { - "name": "/api", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/api", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "api" - ] - } - }, - "response": [] - }, - { - "name": "/", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "urlencoded", - "urlencoded": [], - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "https://localhost:{{port}}/", - "protocol": "https", - "host": [ - "localhost" - ], - "port": "{{port}}", - "path": [ - "" - ] - } - }, - "response": [] - } - ] -} \ No newline at end of file + "info": { + "_postman_id": "e39af94e-6095-479e-8ba0-66930b12e364", + "name": "Gateway", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "v2", + "item": [ + { + "name": "ethereum", + "item": [ + { + "name": "eth", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth"] + } + }, + "response": [] + }, + { + "name": "eth/balances", + "event": [ + { + "listen": "test", + "script": { + "exec": [""], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenList", + "value": "[\"BAT\",\"USDC\",\"DAI\",\"WETH\",\"ZRX\"]", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balances", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "balances"] + } + }, + "response": [] + }, + { + "name": "eth/allowances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "tokenList", + "value": "[\"BAT\",\"USDC\",\"DAI\",\"WETH\",\"ZRX\"]", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/allowances", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "allowances"] + } + }, + "response": [] + }, + { + "name": "eth/approve", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "token", + "value": "ZRX", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "gasPrice", + "value": "23", + "type": "text" + }, + { + "key": "connector", + "value": "balancer", + "type": "text" + }, + { + "key": "amount", + "value": "999", + "type": "text", + "disabled": true + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/approve", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "approve"] + } + }, + "response": [] + }, + { + "name": "eth/get-weth", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "gasPrice", + "value": "31", + "type": "text" + }, + { + "key": "amount", + "value": "0.03", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "tokenAddress", + "value": "{{WETH}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/get-weth", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "get-weth"] + } + }, + "response": [] + }, + { + "name": "eth/poll", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "txHash", + "value": "{{txHash}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/poll", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "poll"] + } + }, + "response": [] + } + ] + }, + { + "name": "balancer", + "item": [ + { + "name": "eth/balancer", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "balancer"] + } + }, + "response": [] + }, + { + "name": "eth/balancer/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer/gas-limit", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "balancer", "gas-limit"] + } + }, + "response": [] + }, + { + "name": "eth/balancer/start", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "BAT", + "type": "text" + }, + { + "key": "quote", + "value": "dai", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "approvalAmount", + "value": "1", + "type": "text", + "disabled": true + }, + { + "key": "gasPrice", + "value": "50", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer/start", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "balancer", "start"] + } + }, + "response": [] + }, + { + "name": "eth/balancer/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "BAT", + "type": "text" + }, + { + "key": "quote", + "value": "dai", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer/price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "balancer", "price"] + } + }, + "response": [] + }, + { + "name": "eth/balancer/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "BAT", + "type": "text" + }, + { + "key": "quote", + "value": "USDC", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "limitPrice", + "value": "0.19767217120251", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "side", + "value": "sell", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/balancer/trade", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "balancer", "trade"] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [""] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [""] + } + } + ] + }, + { + "name": "uniswap", + "item": [ + { + "name": "eth/uniswap", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/gas-limit", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/gas-limit", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "gas-limit"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/start", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "WETH", + "type": "text" + }, + { + "key": "quote", + "value": "USDC", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "approvalAmount", + "value": "1", + "type": "text", + "disabled": true + }, + { + "key": "gasPrice", + "value": "50", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/start", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "start"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "WETH", + "type": "text" + }, + { + "key": "quote", + "value": "DAI", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "price"] + } + }, + "response": [] + }, + { + "name": "eth/uniswap/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "BAT", + "type": "text" + }, + { + "key": "quote", + "value": "DAI", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + }, + { + "key": "limitPrice", + "value": "0.19767217120251", + "type": "text" + }, + { + "key": "gasPrice", + "value": "37", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{privateKey}}", + "type": "text" + }, + { + "key": "side", + "value": "sell", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/eth/uniswap/trade", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["eth", "uniswap", "trade"] + } + }, + "response": [] + } + ] + }, + { + "name": "terra", + "item": [ + { + "name": "terra", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "address", + "value": "{{address}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/terra", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["terra"] + } + }, + "response": [] + }, + { + "name": "terra/balances", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "address", + "value": "{{terraWalletAddress}}", + "type": "text" + } + ], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/terra/balances", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["terra", "balances"] + } + }, + "response": [] + }, + { + "name": "terra/start", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "LUNA", + "type": "text" + }, + { + "key": "quote", + "value": "UST", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/start", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["terra", "start"] + } + }, + "response": [] + }, + { + "name": "terra/price", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "UST", + "type": "text" + }, + { + "key": "quote", + "value": "KRT", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + }, + { + "key": "amount", + "value": "1", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/price", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["terra", "price"] + } + }, + "response": [] + }, + { + "name": "terra/trade", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "base", + "value": "UST", + "type": "text" + }, + { + "key": "quote", + "value": "KRT", + "type": "text" + }, + { + "key": "side", + "value": "buy", + "type": "text" + }, + { + "key": "amount", + "value": "10", + "type": "text" + }, + { + "key": "privateKey", + "value": "{{terraSeeds}}", + "type": "text" + } + ] + }, + "url": { + "raw": "https://localhost:{{port}}/terra/trade", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["terra", "trade"] + } + }, + "response": [] + } + ] + } + ] + }, + { + "name": "/api", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/api", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": ["api"] + } + }, + "response": [] + }, + { + "name": "/", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [], + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://localhost:{{port}}/", + "protocol": "https", + "host": ["localhost"], + "port": "{{port}}", + "path": [""] + } + }, + "response": [] + } + ] +} diff --git a/test/postman/v2/Gateway.postman_environment.json b/test/postman/v2/Gateway.postman_environment.json index 834026f..5733995 100644 --- a/test/postman/v2/Gateway.postman_environment.json +++ b/test/postman/v2/Gateway.postman_environment.json @@ -1,34 +1,34 @@ { - "id": "4436d04a-e8eb-451b-b7ef-851b171508e8", - "name": "Gateway", - "values": [ - { - "key": "port", - "value": "5000", - "enabled": true - }, - { - "key": "privateKey", - "value": "myprivatekey", - "enabled": true - }, - { - "key": "txHash", - "value": "transactionhash", - "enabled": true - }, - { - "key": "terraWalletAddress", - "value": "terrawalletaddress", - "enabled": true - }, - { - "key": "terraSeeds", - "value": "terraseeds", - "enabled": true - } - ], - "_postman_variable_scope": "environment", - "_postman_exported_at": "2021-01-30T13:04:21.323Z", - "_postman_exported_using": "Postman/8.0.3" -} \ No newline at end of file + "id": "4436d04a-e8eb-451b-b7ef-851b171508e8", + "name": "Gateway", + "values": [ + { + "key": "port", + "value": "5000", + "enabled": true + }, + { + "key": "privateKey", + "value": "myprivatekey", + "enabled": true + }, + { + "key": "txHash", + "value": "transactionhash", + "enabled": true + }, + { + "key": "terraWalletAddress", + "value": "terrawalletaddress", + "enabled": true + }, + { + "key": "terraSeeds", + "value": "terraseeds", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2021-01-30T13:04:21.323Z", + "_postman_exported_using": "Postman/8.0.3" +} From b6aeadf0d5add3963018f43e600f66a5812609b7 Mon Sep 17 00:00:00 2001 From: vic-en Date: Sat, 5 Jun 2021 20:13:24 +0100 Subject: [PATCH 29/31] modify start command to run in foreground and fix a condition in fee.js file --- Dockerfile | 3 --- package.json | 2 +- src/services/fees.js | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1d5240d..fb8be0f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,9 +26,6 @@ RUN yarn install # copy pwd file to container COPY . . -# create empty env file -RUN touch .env - EXPOSE 5000 CMD ["yarn", "run", "start"] diff --git a/package.json b/package.json index 0db917c..7b547b5 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "license": "Apache 2", "repository": "https://github.com/coinalpha/gateway-api", "scripts": { - "start": "pm2 start babel-node -- src/index.js", + "start": "pm2 start babel-node --no-daemon -- src/index.js", "status": "pm2 monit", "stop": "pm2 stop all", "logs": "pm2 logs", diff --git a/src/services/fees.js b/src/services/fees.js index 8fbf378..02bdbad 100644 --- a/src/services/fees.js +++ b/src/services/fees.js @@ -23,7 +23,7 @@ export default class Fees { // get ETH Gas Station async getETHGasStationFee (gasLevel = this.ethGasStationGasLevel, interval = defaultRefreshInterval) { try { - if (ethGasStationEnabled === true || ethGasStationEnabled.toLowerCase() === 'true') { + if (ethGasStationEnabled === true || ethGasStationEnabled.toString().toLowerCase() === 'true') { const response = await axios.get(ethGasStationURL) // divite by 10 to convert it to Gwei) this.ethGasPrice = response.data[gasLevel] / 10 From 331d3ea9b346551142095fb80e84214fd790cd3e Mon Sep 17 00:00:00 2001 From: vic-en Date: Mon, 7 Jun 2021 11:08:55 +0100 Subject: [PATCH 30/31] make uniswap v3 to work with new config --- src/services/uniswap_v3.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js index b7fe98d..a2b865b 100644 --- a/src/services/uniswap_v3.js +++ b/src/services/uniswap_v3.js @@ -5,6 +5,7 @@ const debug = require('debug')('router') const math = require('mathjs') const uni = require('@uniswap/sdk') const ethers = require('ethers') +const globalConfig = require('../services/configuration_manager').configManagerInstance const coreArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json') const nftArtifact = require('@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json') const routerArtifact = require('@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json') @@ -15,10 +16,10 @@ const abiDecoder = require('abi-decoder'); // constants const FeeAmount = { LOW: 500, MEDIUM: 3000, HIGH: 10000 }; -const ROUTER = process.env.UNISWAP_V3_ROUTER -const GAS_LIMIT = process.env.UNISWAP_GAS_LIMIT || 5506880; -const TTL = process.env.UNISWAP_TTL || 300; -const UPDATE_PERIOD = process.env.UNISWAP_UPDATE_PERIOD || 300000; // stop updating pair after 5 minutes from last request +const ROUTER = globalConfig.getConfig("UNISWAP_V3_ROUTER") +const GAS_LIMIT = globalConfig.getConfig("UNISWAP_GAS_LIMIT") || 5506880; +const TTL = globalConfig.getConfig("UNISWAP_TTL") || 300; +const UPDATE_PERIOD = globalConfig.getConfig("UNISWAP_UPDATE_PERIOD") || 300000; // stop updating pair after 5 minutes from last request const MaxUint128 = ethers.BigNumber.from(2).pow(128).sub(1) abiDecoder.addABI(nftArtifact.abi); @@ -26,17 +27,17 @@ abiDecoder.addABI(routerArtifact.abi); export default class UniswapV3 { constructor (network = 'mainnet') { - this.providerUrl = process.env.ETHEREUM_RPC_URL - this.network = process.env.ETHEREUM_CHAIN + this.providerUrl = globalConfig.getConfig("ETHEREUM_RPC_URL") + this.network = globalConfig.getConfig("ETHEREUM_CHAIN") this.provider = new ethers.providers.JsonRpcProvider(this.providerUrl) - this.router = process.env.UNISWAP_V3_ROUTER; - this.nftManager = process.env.UNISWAP_V3_NFT_MANAGER; - this.core = process.env.UNISWAP_V3_CORE; - this.slippage = process.env.UNISWAP_ALLOWED_SLIPPAGE - this.pairsCacheTime = process.env.UNISWAP_PAIRS_CACHE_TIME + this.router = globalConfig.getConfig("UNISWAP_V3_ROUTER"); + this.nftManager = globalConfig.getConfig("UNISWAP_V3_NFT_MANAGER"); + this.core = globalConfig.getConfig("UNISWAP_V3_CORE"); + this.slippage = globalConfig.getConfig("UNISWAP_ALLOWED_SLIPPAGE") + this.pairsCacheTime = globalConfig.getConfig("UNISWAP_PAIRS_CACHE_TIME") this.gasLimit = GAS_LIMIT this.expireTokenPairUpdate = UPDATE_PERIOD - this.zeroReserveCheckInterval = process.env.UNISWAP_NO_RESERVE_CHECK_INTERVAL + this.zeroReserveCheckInterval = globalConfig.getConfig("UNISWAP_NO_RESERVE_CHECK_INTERVAL") this.zeroReservePairs = {} // No reserve pairs this.tokenList = {} this.pairs = [] From 53aea39a93ae24614d9e1d0531194fe9370ab884 Mon Sep 17 00:00:00 2001 From: james-hummingbot Date: Mon, 7 Jun 2021 13:43:49 +0200 Subject: [PATCH 31/31] Fix things, double check in postman --- package-lock.json | 12 +- package.json | 1 - src/app.js | 5 +- src/index.js | 33 ++-- src/routes/balancer.route.js | 36 ++--- src/routes/celo.route.js | 42 ++--- src/routes/eth.route.js | 26 +-- src/routes/perpetual_finance.route.js | 42 ++--- src/routes/terra.route.js | 30 ++-- src/routes/uniswap.route.js | 35 ++-- src/routes/uniswap_v3.route.js | 88 +++++------ src/services/access.js | 2 +- src/services/balancer.js | 16 +- src/services/eth.js | 30 ++-- src/services/fees.js | 2 +- src/services/perpetual_finance.js | 28 ++-- src/services/terra.js | 42 ++--- src/services/uniswap.js | 42 +++-- src/services/uniswap_v3.js | 85 +++++++--- src/services/utils.js | 13 +- src/static/uniswap-v3/helper_functions.js | 184 ++-------------------- yarn.lock | 12 +- 22 files changed, 348 insertions(+), 458 deletions(-) diff --git a/package-lock.json b/package-lock.json index fcef706..f058691 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5172,9 +5172,9 @@ "dev": true }, "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, "nodemon": { @@ -6675,9 +6675,9 @@ }, "dependencies": { "ajv": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz", - "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", + "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", diff --git a/package.json b/package.json index b3b8b9d..ae45f0c 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,6 @@ "express-ipfilter": "^1.1.2", "helmet": "^4.6.0", "http-status-codes": "^2.1.3", - "jsbi": "^3.1.4", "lodash": "^4.17.20", "mathjs": "^9.3.0", "moment": "^2.29.1", diff --git a/src/app.js b/src/app.js index 170a1e4..eeb44b1 100644 --- a/src/app.js +++ b/src/app.js @@ -1,14 +1,15 @@ import bodyParser from 'body-parser'; import express from 'express'; import helmet from 'helmet'; -import { IpFilter } from 'express-ipfilter'; import { statusMessages } from './services/utils'; import { validateAccess } from './services/access'; +import { IpFilter } from 'express-ipfilter'; import { logger } from './services/logger'; // Routes import apiRoutes from './routes/index.route'; import balancerRoutes from './routes/balancer.route'; +// import celoRoutes from './routes/celo.route' import ethRoutes from './routes/eth.route'; import terraRoutes from './routes/terra.route'; import uniswapRoutes from './routes/uniswap.route'; @@ -58,7 +59,7 @@ app.use((req, res, _next) => { logger.error(message); res.status(404).send({ error: 'Page not found', - message + message: message }); }); diff --git a/src/index.js b/src/index.js index 23b7908..cdd5675 100644 --- a/src/index.js +++ b/src/index.js @@ -8,12 +8,15 @@ import fs from 'fs'; import app from './app'; import { logger } from './services/logger'; -const env = process.env.NODE_ENV; -const port = process.env.PORT; -const certPassphrase = process.env.CERT_PASSPHRASE; -const ethereumChain = process.env.ETHEREUM_CHAIN; -const terraChain = process.env.TERRA_CHAIN; -let certPath = process.env.CERT_PATH; +const globalConfig = + require('./services/configuration_manager').configManagerInstance.readAllConfigs(); + +const env = globalConfig.CORE.NODE_ENV; +const port = globalConfig.CORE.PORT; +const certPassphrase = globalConfig.CERT_PASSPHRASE; +const ethereumChain = globalConfig.ETHEREUM_CHAIN; +const terraChain = globalConfig.TERRA_CHAIN; +let certPath = globalConfig.CERT_PATH; if ((typeof certPath === 'undefined' && certPath == null) || certPath === '') { // assuming it is local development using test script to generate certs @@ -48,16 +51,16 @@ const onError = (error) => { throw error; } - const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`; + const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': - console.error(`${bind} requires elevated privileges`); + console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': - console.error(`${bind} is already in use`); + console.error(bind + ' is already in use'); process.exit(1); break; default: @@ -68,9 +71,9 @@ const onError = (error) => { // event listener for "listening" event. const onListening = () => { const addr = server.address(); - const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`; - console.log(`listening on ${bind}`); - logger.debug(`listening on ${bind}`); + const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; + console.log('listening on ' + bind); + logger.debug('listening on ' + bind); }; // listen on provided port, on all network interfaces. @@ -80,9 +83,9 @@ server.on('listening', onListening); const serverConfig = { app: 'gateway-api', - port, - ethereumChain, - terraChain + port: port, + ethereumChain: ethereumChain, + terraChain: terraChain }; logger.info(JSON.stringify(serverConfig)); diff --git a/src/routes/balancer.route.js b/src/routes/balancer.route.js index fefddac..f59e7e3 100644 --- a/src/routes/balancer.route.js +++ b/src/routes/balancer.route.js @@ -58,7 +58,7 @@ router.post('/gas-limit', async (req, res) => { res.status(200).json({ network: balancer.network, - gasLimit, + gasLimit: gasLimit, timestamp: Date.now() }); } catch (err) { @@ -135,10 +135,10 @@ router.get('/start', async (req, res) => { timestamp: initTime, latency: latency(initTime, Date.now()), success: true, - pairs, - gasPrice, - gasLimit, - gasCost + pairs: pairs, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost }; console.log('Initializing balancer'); res.status(200).json(result); @@ -210,13 +210,13 @@ router.post('/price', async (req, res) => { base: baseTokenContractInfo, quote: quoteTokenContractInfo, amount: tradeAmount, - side, + side: side, expectedAmount: expectedTradeAmount, price: tradePrice, - gasPrice, - gasLimit, - gasCost, - swaps + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + swaps: swaps }; debug( `Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH` @@ -329,10 +329,10 @@ router.post('/trade', async (req, res) => { quote: quoteTokenContractInfo, amount: parseFloat(paramData.amount), expectedIn: expectedAmount / quoteDenomMultiplier, - price, - gasPrice, - gasLimit, - gasCost, + price: price, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, txHash: tx.hash }); } else { @@ -370,10 +370,10 @@ router.post('/trade', async (req, res) => { quote: quoteTokenContractInfo, amount: parseFloat(paramData.amount), expectedOut: expectedAmount / quoteDenomMultiplier, - price, - gasPrice, - gasLimit, - gasCost, + price: price, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, txHash: tx.hash }); } else { diff --git a/src/routes/celo.route.js b/src/routes/celo.route.js index 933ff92..fa0c61f 100644 --- a/src/routes/celo.route.js +++ b/src/routes/celo.route.js @@ -1,5 +1,6 @@ -const express = require('express'); +'use strict'; +const express = require('express'); const router = express.Router(); const BigNumber = require('bignumber.js'); const debug = require('debug')('router'); @@ -10,7 +11,6 @@ const celocli = 'celocli'; const DENOM_UNIT_MULTIPLIER = BigNumber('1e+18'); const hbUtils = require('../services/utils'); - const separator = '=>'; router.use((req, res, next) => { @@ -29,8 +29,8 @@ router.get('/status', (req, res) => { const nodeSync = spawn(celocli, ['node:synced']); - const err_message = []; - const out_message = []; + let err_message = [], + out_message = []; nodeSync.stdout.on('data', (out) => { out_message.push(out.toString().trim()); @@ -74,8 +74,8 @@ router.get('/price', (req, res) => { const nodeSync = spawn(celocli, ['exchange:show', '--amount', amount]); - const err_message = []; - const out_message = []; + let err_message = [], + out_message = []; nodeSync.stdout.on('data', (out) => { out_message.push(out.toString().trim()); @@ -86,17 +86,17 @@ router.get('/price', (req, res) => { }); nodeSync.on('close', (code) => { - const exchange_rates = {}; + let exchange_rates = {}; let price; if (code === 0) { // extract exchange rate from cli output out_message.forEach((item, _index) => { if (item.includes(separator)) { - const exchangeInfo = item.split(separator); - const base = exchangeInfo[0].trim().split(' '); - const quote = exchangeInfo[1].trim().split(' '); - const market = [base[1].toUpperCase(), quote[1].toUpperCase()].join( + let exchangeInfo = item.split(separator); + let base = exchangeInfo[0].trim().split(' '); + let quote = exchangeInfo[1].trim().split(' '); + let market = [base[1].toUpperCase(), quote[1].toUpperCase()].join( '-' ); exchange_rates[market] = quote[0] / DENOM_UNIT_MULTIPLIER; @@ -107,7 +107,7 @@ router.get('/price', (req, res) => { price = exchange_rates[tradingPair]; const result = Object.assign(paramData, { - price, + price: price, timestamp: initTime, latency: hbUtils.latency(initTime, Date.now()) }); @@ -128,9 +128,9 @@ router.get('/balance', (req, res) => { const balance = spawn(celocli, ['account:balance', address]); - const err_message = []; - const out_message = []; - const walletBalances = {}; + let err_message = [], + out_message = []; + let walletBalances = {}; balance.stdout.on('data', (out) => { out_message.push(out.toString().trim()); @@ -150,9 +150,9 @@ router.get('/balance', (req, res) => { item.toLowerCase().includes('lockedcelo') || item.toLowerCase().includes('lockedgold') ) { - const balanceArray = item.split('\n'); + let balanceArray = item.split('\n'); balanceArray.forEach((x) => { - const keyValue = x.split(':'); + let keyValue = x.split(':'); walletBalances[keyValue[0].trim()] = keyValue[1].trim() / DENOM_UNIT_MULTIPLIER; }); @@ -161,7 +161,7 @@ router.get('/balance', (req, res) => { }); res.status(200).json({ - address, + address: address, balance: walletBalances, timestamp: Date.now() }); @@ -197,8 +197,8 @@ router.post('/unlock', (req, res) => { secret ]); - const err_message = []; - const out_message = []; + let err_message = [], + out_message = []; lockStatus.stdout.on('data', (out) => { out_message.push(out.toString().trim()); @@ -223,7 +223,7 @@ router.post('/unlock', (req, res) => { unlocked = true; } res.status(200).json({ - unlocked, + unlocked: unlocked, message: out_message.join(), timestamp: Date.now() }); diff --git a/src/routes/eth.route.js b/src/routes/eth.route.js index 4cc1cb7..e80dbcf 100644 --- a/src/routes/eth.route.js +++ b/src/routes/eth.route.js @@ -91,7 +91,7 @@ router.post('/balances', async (req, res) => { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances + balances: balances }); }); } catch (err) { @@ -163,8 +163,8 @@ router.post('/allowances', async (req, res) => { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - spender, - approvals + spender: spender, + approvals: approvals }); }); } catch (err) { @@ -230,7 +230,7 @@ router.post('/balances-2', async (req, res) => { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances + balances: balances }); }); } catch (err) { @@ -297,8 +297,8 @@ router.post('/allowances-2', async (req, res) => { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - spender, - approvals + spender: spender, + approvals: approvals }); }); } catch (err) { @@ -372,10 +372,10 @@ router.post('/approve', async (req, res) => { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - tokenAddress, - spender, + tokenAddress: tokenAddress, + spender: spender, amount: amount / (1e18).toString(), - approval + approval: approval }); } catch (err) { logger.error(req.originalUrl, { message: err }); @@ -396,7 +396,7 @@ router.post('/poll', async (req, res) => { const txHash = paramData.txHash; const txReceipt = await eth.provider.getTransactionReceipt(txHash); const receipt = {}; - const confirmed = !!(txReceipt && txReceipt.blockNumber); + const confirmed = txReceipt && txReceipt.blockNumber ? true : false; if (confirmed) { receipt.gasUsed = BigNumber.from(txReceipt.gasUsed).toNumber(); receipt.blockNumber = txReceipt.blockNumber; @@ -411,9 +411,9 @@ router.post('/poll', async (req, res) => { network: eth.network, timestamp: initTime, latency: latency(initTime, Date.now()), - txHash, - confirmed, - receipt + txHash: txHash, + confirmed: confirmed, + receipt: receipt }); return txReceipt; }); diff --git a/src/routes/perpetual_finance.route.js b/src/routes/perpetual_finance.route.js index d2acf51..e03adbb 100644 --- a/src/routes/perpetual_finance.route.js +++ b/src/routes/perpetual_finance.route.js @@ -31,7 +31,7 @@ router.get('/load-metadata', async (req, res) => { res.status(200).json({ network: perpFi.network, provider: perpFi.provider.connection.url, - loadedMetadata, + loadedMetadata: loadedMetadata, connection: true, timestamp: Date.now() }); @@ -61,14 +61,14 @@ router.post('/balances', async (req, res) => { } const balances = {}; - balances.XDAI = await perpFi.getXdaiBalance(wallet); - balances.USDC = await perpFi.getUSDCBalance(wallet); + balances['XDAI'] = await perpFi.getXdaiBalance(wallet); + balances['USDC'] = await perpFi.getUSDCBalance(wallet); try { res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances + balances: balances }); } catch (err) { let reason; @@ -106,13 +106,13 @@ router.post('/allowances', async (req, res) => { } const approvals = {}; - approvals.USDC = await perpFi.getAllowance(wallet); + approvals['USDC'] = await perpFi.getAllowance(wallet); try { res.status(200).json({ network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - approvals + approvals: approvals }); } catch (err) { let reason; @@ -162,8 +162,8 @@ router.post('/approve', async (req, res) => { network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - amount, - approval + amount: amount, + approval: approval }); } catch (err) { logger.error(req.originalUrl, { message: err }); @@ -229,10 +229,10 @@ router.post('/open', async (req, res) => { network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - margin, - side, - leverage, - minBaseAssetAmount, + margin: margin, + side: side, + leverage: leverage, + minBaseAssetAmount: minBaseAssetAmount, txHash: tx.hash }); } catch (err) { @@ -285,7 +285,7 @@ router.post('/close', async (req, res) => { network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - minimalQuoteAsset, + minimalQuoteAsset: minimalQuoteAsset, txHash: tx.hash }); } catch (err) { @@ -336,7 +336,7 @@ router.post('/position', async (req, res) => { network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - position + position: position }); } catch (err) { logger.error(req.originalUrl, { message: err }); @@ -411,7 +411,7 @@ router.post('/receipt', async (req, res) => { const txHash = paramData.txHash; const txReceipt = await perpFi.provider.getTransactionReceipt(txHash); const receipt = {}; - const confirmed = !!(txReceipt && txReceipt.blockNumber); + const confirmed = txReceipt && txReceipt.blockNumber ? true : false; if (txReceipt !== null) { receipt.gasUsed = ethers.utils.formatEther(txReceipt.gasUsed); receipt.blockNumber = txReceipt.blockNumber; @@ -425,9 +425,9 @@ router.post('/receipt', async (req, res) => { network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - txHash, - confirmed, - receipt + txHash: txHash, + confirmed: confirmed, + receipt: receipt }); return txReceipt; }); @@ -456,8 +456,8 @@ router.post('/price', async (req, res) => { network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - side, - price + side: side, + price: price }); } catch (err) { logger.error(req.originalUrl, { message: err }); @@ -518,7 +518,7 @@ router.post('/funding', async (req, res) => { network: perpFi.network, timestamp: initTime, latency: latency(initTime, Date.now()), - fr + fr: fr }); } catch (err) { logger.error(req.originalUrl, { message: err }); diff --git a/src/routes/terra.route.js b/src/routes/terra.route.js index 48cb9be..e385295 100644 --- a/src/routes/terra.route.js +++ b/src/routes/terra.route.js @@ -1,3 +1,5 @@ +'use strict'; + import express from 'express'; import { getParamData, @@ -21,7 +23,7 @@ router.post('/', async (req, res) => { POST / */ res.status(200).json({ - network, + network: network, lcdUrl: terra.lcd.config.URL, gasPrices: terra.lcd.config.gasPrices, gasAdjustment: terra.lcd.config.gasAdjustment, @@ -40,7 +42,7 @@ router.post('/balances', async (req, res) => { const paramData = getParamData(req.body); const address = paramData.address; - const balances = {}; + let balances = {}; try { await terra.lcd.bank.balance(address).then((bal) => { @@ -54,10 +56,10 @@ router.post('/balances', async (req, res) => { }); logger.info('terra.route - Get Account Balance'); res.status(200).json({ - network, + network: network, timestamp: initTime, latency: latency(initTime, Date.now()), - balances + balances: balances }); } catch (err) { logger.error(req.originalUrl, { message: err }); @@ -75,7 +77,7 @@ router.post('/balances', async (req, res) => { } res.status(500).json({ error: reason, - message + message: message }); } }); @@ -95,7 +97,7 @@ router.post('/start', async (req, res) => { const quoteTokenSymbol = paramData.quote; const result = { - network, + network: network, timestamp: initTime, latency: latency(initTime, Date.now()), success: true, @@ -136,13 +138,13 @@ router.post('/price', async (req, res) => { }); res.status(200).json({ - network, + network: network, timestamp: initTime, latency: latency(initTime, Date.now()), base: baseToken, quote: quoteToken, - amount, - tradeType, + amount: amount, + tradeType: tradeType, price: exchangeRate.price.amount, cost: exchangeRate.cost.amount, txFee: exchangeRate.txFee.amount @@ -163,7 +165,7 @@ router.post('/price', async (req, res) => { } res.status(500).json({ error: reason, - message + message: message }); } }); @@ -213,13 +215,13 @@ router.post('/trade', async (req, res) => { }); const swapResult = { - network, + network: network, timestamp: initTime, latency: latency(initTime, Date.now()), base: baseToken, - tradeType, + tradeType: tradeType, quote: quoteToken, - amount + amount: amount }; Object.assign(swapResult, tokenSwaps); logger.info( @@ -242,7 +244,7 @@ router.post('/trade', async (req, res) => { } res.status(500).json({ error: reason, - message + message: message }); } }); diff --git a/src/routes/uniswap.route.js b/src/routes/uniswap.route.js index 6017b14..1e9b20b 100644 --- a/src/routes/uniswap.route.js +++ b/src/routes/uniswap.route.js @@ -20,7 +20,9 @@ const fees = new Fees(); const swapMoreThanMaxPriceError = 'Price too high'; const swapLessThanMaxPriceError = 'Price too low'; -const estimateGasLimit = () => uniswap.gasLimit; +const estimateGasLimit = () => { + return uniswap.gasLimit; +}; const getErrorMessage = (err) => { /* @@ -61,7 +63,7 @@ router.post('/gas-limit', async (req, res) => { try { res.status(200).json({ network: uniswap.network, - gasLimit, + gasLimit: gasLimit, timestamp: Date.now() }); } catch (err) { @@ -134,10 +136,10 @@ router.get('/start', async (req, res) => { timestamp: initTime, latency: latency(initTime, Date.now()), success: true, - pairs, - gasPrice, - gasLimit, - gasCost + pairs: pairs, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost }; res.status(200).json(result); }); @@ -214,10 +216,10 @@ router.post('/trade', async (req, res) => { latency: latency(initTime, Date.now()), base: baseTokenAddress, quote: quoteTokenAddress, - amount, + amount: amount, expectedIn: expectedAmount.toSignificant(8), - price, - gasPrice, + price: price, + gasPrice: gasPrice, gasLimit, gasCost, txHash: tx.hash @@ -253,9 +255,9 @@ router.post('/trade', async (req, res) => { amount: parseFloat(paramData.amount), expectedOut: expectedAmount.toSignificant(8), price: parseFloat(price), - gasPrice, + gasPrice: gasPrice, gasLimit, - gasCost, + gasCost: gasCost, txHash: tx.hash }); } else { @@ -343,10 +345,10 @@ router.post('/price', async (req, res) => { amount: tradeAmount, expectedAmount: expectedTradeAmount, price: tradePrice, - gasPrice, - gasLimit, - gasCost, - trade + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, + trade: trade }; debug( `Price ${side} ${baseTokenContractInfo.symbol}-${quoteTokenContractInfo.symbol} | amount:${amount} (rate:${tradePrice}) - gasPrice:${gasPrice} gasLimit:${gasLimit} estimated fee:${gasCost} ETH` @@ -365,7 +367,8 @@ router.post('/price', async (req, res) => { let errCode = 500; if (Object.keys(err).includes('isInsufficientReservesError')) { errCode = 200; - reason = `${statusMessages.insufficient_reserves} in ${side} at Uniswap`; + reason = + statusMessages.insufficient_reserves + ' in ' + side + ' at Uniswap'; } else if (Object.getOwnPropertyNames(err).includes('message')) { reason = getErrorMessage(err.message); if (reason === statusMessages.no_pool_available) { diff --git a/src/routes/uniswap_v3.route.js b/src/routes/uniswap_v3.route.js index 6b434a0..d359588 100644 --- a/src/routes/uniswap_v3.route.js +++ b/src/routes/uniswap_v3.route.js @@ -1,12 +1,8 @@ import { ethers } from 'ethers'; import express from 'express'; -import { - getNonceManager, - getParamData, - latency, - statusMessages -} from '../services/utils'; +import { getNonceManager } from '../services/utils'; +import { getParamData, latency, statusMessages } from '../services/utils'; import { logger } from '../services/logger'; import Ethereum from '../services/eth'; import UniswapV3 from '../services/uniswap_v3'; @@ -16,17 +12,18 @@ const globalConfig = require('../services/configuration_manager').configManagerInstance; const debug = require('debug')('router'); - const router = express.Router(); const eth = new Ethereum(globalConfig.getConfig('ETHEREUM_CHAIN')); const uniswap = new UniswapV3(globalConfig.getConfig('ETHEREUM_CHAIN')); const fees = new Fees(); -// const swapMoreThanMaxPriceError = 'Price too high' -// const swapLessThanMaxPriceError = 'Price too low' +//const swapMoreThanMaxPriceError = 'Price too high' +//const swapLessThanMaxPriceError = 'Price too low' -const estimateGasLimit = () => uniswap.gasLimit; +const estimateGasLimit = () => { + return uniswap.gasLimit; +}; const getErrorMessage = (err) => { /* @@ -67,7 +64,7 @@ router.post('/gas-limit', async (req, res) => { try { res.status(200).json({ network: uniswap.network, - gasLimit, + gasLimit: gasLimit, timestamp: Date.now() }); } catch (err) { @@ -166,12 +163,12 @@ router.post('/trade', async (req, res) => { latency: latency(initTime, Date.now()), base: baseTokenAddress, quote: quoteTokenAddress, - amount, + amount: amount, expectedIn: tx.expectedAmount, price: limitPrice, - gasPrice, - gasLimit, - gasCost, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, txHash: tx.hash }); } else { @@ -196,9 +193,9 @@ router.post('/trade', async (req, res) => { amount: parseFloat(paramData.amount), expectedOut: tx.expectedAmount, price: limitPrice, - gasPrice, - gasLimit, - gasCost, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost, txHash: tx.hash }); } @@ -236,6 +233,7 @@ router.post('/price', async (req, res) => { const baseTokenAddress = baseTokenContractInfo.address; const quoteTokenAddress = quoteTokenContractInfo.address; + //const side = paramData.side.toUpperCase() // not used for now let gasPrice; if (paramData.gasPrice) { gasPrice = parseFloat(paramData.gasPrice); @@ -259,10 +257,10 @@ router.post('/price', async (req, res) => { latency: latency(initTime, Date.now()), base: baseTokenAddress, quote: quoteTokenAddress, - prices, - gasPrice, - gasLimit, - gasCost + prices: prices, + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost }; debug( `Mid Price ${baseTokenContractInfo.symbol}-${ @@ -278,7 +276,7 @@ router.post('/price', async (req, res) => { let errCode = 500; if (Object.keys(err).includes('isInsufficientReservesError')) { errCode = 200; - reason = `${statusMessages.insufficient_reserves} at Uniswap`; + reason = statusMessages.insufficient_reserves + ' in ' + ' at Uniswap'; } else if (Object.getOwnPropertyNames(err).includes('message')) { reason = getErrorMessage(err.message); if (reason === statusMessages.no_pool_available) { @@ -394,15 +392,15 @@ router.post('/add-position', async (req, res) => { latency: latency(initTime, Date.now()), token0: paramData.token0, token1: paramData.token1, - fee, - amount0, - amount1, - lowerPrice, - upperPrice, + fee: fee, + amount0: amount0, + amount1: amount1, + lowerPrice: lowerPrice, + upperPrice: upperPrice, hash: newPosition.hash, - gasPrice, - gasLimit, - gasCost + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost }; debug(`New Position: ${newPosition.hash}`); res.status(200).json(result); @@ -447,16 +445,16 @@ router.post('/remove-position', async (req, res) => { timestamp: initTime, latency: latency(initTime, Date.now()), hash: removelp.hash, - gasPrice, - gasLimit, - gasCost + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost }; debug(`Remove lp: ${removelp.hash}`); res.status(200).json(result); } catch (err) { logger.error(req.originalUrl, { message: err }); let reason; - const errCode = 500; + let errCode = 500; err.reason ? (reason = err.reason) : (reason = statusMessages.operation_error); @@ -525,13 +523,13 @@ router.post('/replace-position', async (req, res) => { network: uniswap.network, timestamp: initTime, latency: latency(initTime, Date.now()), - tokenId, - amount0, - amount1, + tokenId: tokenId, + amount0: amount0, + amount1: amount1, hash: positionChange.hash, - gasPrice, - gasLimit, - gasCost + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost }; debug(`Position change ${positionChange.hash}`); res.status(200).json(result); @@ -578,11 +576,11 @@ router.post('/collect-fees', async (req, res) => { network: uniswap.network, timestamp: initTime, latency: latency(initTime, Date.now()), - tokenId, + tokenId: tokenId, hash: collect.hash, - gasPrice, - gasLimit, - gasCost + gasPrice: gasPrice, + gasLimit: gasLimit, + gasCost: gasCost }; debug(`Fees: ${collect.hash}`); res.status(200).json(result); diff --git a/src/services/access.js b/src/services/access.js index cf374b9..2596057 100644 --- a/src/services/access.js +++ b/src/services/access.js @@ -11,7 +11,7 @@ export const validateAccess = (req, res, next) => { const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; const method = req.method; const url = req.url; - const requestInfo = `Request from IP: ${ip} ${method} ${url}`; + const requestInfo = 'Request from IP: ' + ip + ' ' + method + ' ' + url; console.log(requestInfo); next(); } else if (cert.subject) { diff --git a/src/services/balancer.js b/src/services/balancer.js index 7fb60bc..2fe5b3e 100644 --- a/src/services/balancer.js +++ b/src/services/balancer.js @@ -108,12 +108,12 @@ export default class Balancer { debug(`Expected Out: ${expectedAmount.toString()} (${tokenOut})`); // Create correct swap format for new proxy - const swaps = []; + let swaps = []; for (let i = 0; i < swapsFormatted.length; i++) { - const swap = { + let swap = { pool: swapsFormatted[i].pool, - tokenIn, - tokenOut, + tokenIn: tokenIn, + tokenOut: tokenOut, swapAmount: swapsFormatted[i].tokenInParam, limitReturnAmount: swapsFormatted[i].tokenOutParam, maxPrice: swapsFormatted[i].maxPrice.toString() @@ -172,12 +172,12 @@ export default class Balancer { debug(`Expected In: ${expectedAmount.toString()} (${tokenIn})`); // Create correct swap format for new proxy - const swaps = []; + let swaps = []; for (let i = 0; i < swapsFormatted.length; i++) { - const swap = { + let swap = { pool: swapsFormatted[i].pool, - tokenIn, - tokenOut, + tokenIn: tokenIn, + tokenOut: tokenOut, swapAmount: swapsFormatted[i].tokenOutParam, limitReturnAmount: swapsFormatted[i].tokenInParam, maxPrice: swapsFormatted[i].maxPrice.toString() diff --git a/src/services/eth.js b/src/services/eth.js index a9d7768..2db6410 100644 --- a/src/services/eth.js +++ b/src/services/eth.js @@ -1,5 +1,5 @@ -import axios from 'axios'; import { logger } from './logger'; +import axios from 'axios'; const fs = require('fs'); const ethers = require('ethers'); @@ -18,7 +18,13 @@ export default class Ethereum { this.provider = new ethers.providers.JsonRpcProvider(providerUrl); this.erc20TokenListURL = globalConfig.getConfig('ETHEREUM_TOKEN_LIST_URL'); this.network = network; - + /* + this.spenders = { + balancer: process.env.EXCHANGE_PROXY, + uniswap: process.env.UNISWAP_ROUTER, + uniswapV3: process.UNISWAP_V3_ROUTER + } + */ // update token list this.getERC20TokenList(); // erc20TokenList } @@ -48,7 +54,7 @@ export default class Ethereum { ); try { const balance = await contract.balanceOf(wallet.address); - return balance / (10 ** decimals).toString(); + return balance / Math.pow(10, decimals).toString(); } catch (err) { logger.error(err); let reason; @@ -67,7 +73,7 @@ export default class Ethereum { ); try { const allowance = await contract.allowance(wallet.address, spender); - return allowance / (10 ** decimals).toString(); + return allowance / Math.pow(10, decimals).toString(); } catch (err) { logger.error(err); let reason; @@ -105,7 +111,7 @@ export default class Ethereum { // get current Gas async getCurrentGasPrice() { try { - this.provider.getGasPrice().then((gas) => { + this.provider.getGasPrice().then(function (gas) { // gasPrice is a BigNumber; convert it to a decimal string const gasPrice = gas.toString(); return gasPrice; @@ -135,7 +141,7 @@ export default class Ethereum { return await contract.deposit({ value: amount, gasPrice: gasPrice * 1e9, - gasLimit + gasLimit: gasLimit }); } catch (err) { logger.error(err); @@ -189,16 +195,16 @@ export default class Ethereum { // Refactor name to getERC20TokenByName getERC20TokenAddresses(tokenSymbol) { - const tokenContractAddress = this.erc20TokenList.tokens.filter( - (obj) => obj.symbol === tokenSymbol.toUpperCase() - ); + const tokenContractAddress = this.erc20TokenList.tokens.filter((obj) => { + return obj.symbol === tokenSymbol.toUpperCase(); + }); return tokenContractAddress[0]; } getERC20TokenByAddress(tokenAddress) { - const tokenContract = this.erc20TokenList.tokens.filter( - (obj) => obj.address.toUpperCase() === tokenAddress.toUpperCase() - ); + const tokenContract = this.erc20TokenList.tokens.filter((obj) => { + return obj.address.toUpperCase() === tokenAddress.toUpperCase(); + }); return tokenContract[0]; } } diff --git a/src/services/fees.js b/src/services/fees.js index a75d5a4..79fe725 100644 --- a/src/services/fees.js +++ b/src/services/fees.js @@ -1,6 +1,6 @@ +import { logger } from './logger'; import axios from 'axios'; import BigNumber from 'bignumber.js'; -import { logger } from './logger'; // constants const ethGasStationHost = 'https://ethgasstation.info'; diff --git a/src/services/perpetual_finance.js b/src/services/perpetual_finance.js index 6161076..b4e2d63 100644 --- a/src/services/perpetual_finance.js +++ b/src/services/perpetual_finance.js @@ -54,7 +54,7 @@ export default class PerpetualFinance { ); const layer2 = Object.keys(metadata.layers.layer2.contracts); - for (const key of layer2) { + for (var key of layer2) { if (metadata.layers.layer2.contracts[key].name === 'Amm') { this.amm[key] = metadata.layers.layer2.contracts[key].address; } else { @@ -74,15 +74,15 @@ export default class PerpetualFinance { async update_price_loop() { if (Object.keys(this.cacheExpirary).length > 0) { - for (const pair in this.cacheExpirary) { + for (let pair in this.cacheExpirary) { if (this.cacheExpirary[pair] <= Date.now()) { delete this.cacheExpirary[pair]; delete this.priceCache[pair]; } } - for (const pair in this.cacheExpirary) { - const amm = new Ethers.Contract( + for (let pair in this.cacheExpirary) { + let amm = new Ethers.Contract( this.amm[pair], AmmArtifact.abi, this.provider @@ -139,7 +139,7 @@ export default class PerpetualFinance { TetherTokenArtifact.abi, wallet ); - const layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address); + let layer2UsdcBalance = await layer2Usdc.balanceOf(wallet.address); const layer2UsdcDecimals = await layer2Usdc.decimals(); return Ethers.utils.formatUnits(layer2UsdcBalance, layer2UsdcDecimals); } catch (err) { @@ -200,7 +200,7 @@ export default class PerpetualFinance { } } - // open Position + //open Position async openPosition(side, margin, levrg, pair, minBaseAmount, wallet) { try { const quoteAssetAmount = { @@ -232,7 +232,7 @@ export default class PerpetualFinance { } } - // close Position + //close Position async closePosition(wallet, pair, minimalQuote) { try { const minimalQuoteAsset = { @@ -257,7 +257,7 @@ export default class PerpetualFinance { } } - // get active position + //get active position async getPosition(wallet, pair) { try { const positionValues = {}; @@ -323,7 +323,7 @@ export default class PerpetualFinance { } } - // get active margin + //get active margin async getActiveMargin(wallet) { try { const clearingHouseViewer = new Ethers.Contract( @@ -370,10 +370,12 @@ export default class PerpetualFinance { }); price = Ethers.utils.formatUnits(price.d) / amount; } - } else if (side === 'buy') { - price = this.priceCache[pair][0]; } else { - price = this.priceCache[pair][1]; + if (side === 'buy') { + price = this.priceCache[pair][0]; + } else { + price = this.priceCache[pair][1]; + } } return price; } catch (err) { @@ -388,7 +390,7 @@ export default class PerpetualFinance { // get getFundingRate async getFundingRate(pair) { try { - const funding = {}; + let funding = {}; const amm = new Ethers.Contract( this.amm[pair], AmmArtifact.abi, diff --git a/src/services/terra.js b/src/services/terra.js index 18faec6..fe2698f 100644 --- a/src/services/terra.js +++ b/src/services/terra.js @@ -1,3 +1,4 @@ +import { logger } from './logger'; import { LCDClient, Coin, @@ -6,7 +7,6 @@ import { isTxError } from '@terra-money/terra.js'; import BigNumber from 'bignumber.js'; -import { logger } from './logger'; import { getHummingbotMemo } from './utils'; const debug = require('debug')('router'); @@ -93,7 +93,7 @@ export default class Terra { // get Token Symbol getTokenSymbol(denom) { try { - const { symbol } = TERRA_TOKENS[denom]; + const symbol = TERRA_TOKENS[denom].symbol; return symbol; } catch (err) { logger.error(err); @@ -106,7 +106,7 @@ export default class Terra { } getTxAttributes(attributes) { - const attrib = {}; + let attrib = {}; attributes.forEach((item) => { attrib[item.key] = item.value; }); @@ -144,7 +144,7 @@ export default class Terra { async getTxFee() { try { const lunaFee = GAS_PRICE.uluna * GAS_ADJUSTMENT; - const feeList = { uluna: lunaFee }; + let feeList = { uluna: lunaFee }; await this.lcd.oracle.exchangeRates().then((rates) => { Object.keys(rates._coins).forEach((key) => { feeList[key] = rates._coins[key].amount * lunaFee; @@ -166,14 +166,14 @@ export default class Terra { // get Terra Swap Rate async getSwapRate(baseToken, quoteToken, amount, tradeType) { try { - let exchangeRate; - let offerCoin; - let offerDenom; - let swapDenom; - let cost; - let costAmount; - let offer; - const swaps = {}; + let exchangeRate, + offerCoin, + offerDenom, + swapDenom, + cost, + costAmount, + offer; + let swaps = {}; if (tradeType.toLowerCase() === 'sell') { // sell base @@ -184,7 +184,7 @@ export default class Terra { await this.lcd.market .swapRate(offerCoin, swapDenom) .then((swapCoin) => { - offer = { amount }; + offer = { amount: amount }; exchangeRate = { amount: swapCoin.amount / DENOM_UNIT / amount, token: quoteToken @@ -273,11 +273,9 @@ export default class Terra { const baseDenom = this.getTokenDenom(baseToken); const quoteDenom = this.getTokenDenom(quoteToken); - let offerDenom; - let swapDenom; - let swaps; - let txAttributes; - const tokenSwap = {}; + let offerDenom, swapDenom; + let swaps, txAttributes; + let tokenSwap = {}; if (tradeType.toLowerCase() === 'sell') { offerDenom = baseDenom; @@ -309,7 +307,7 @@ export default class Terra { txOptions = { msgs: [msgSwap], gasPrices: { uluna: parseFloat(gasPrice) }, - gasAdjustment, + gasAdjustment: gasAdjustment, memo: this.memo }; } else { @@ -335,8 +333,10 @@ export default class Terra { ); } const txHash = txResult.txhash; - const { events } = JSON.parse(txResult.raw_log)[0]; - const swap = events.find((obj) => obj.type === 'swap'); + const events = JSON.parse(txResult.raw_log)[0].events; + const swap = events.find((obj) => { + return obj.type === 'swap'; + }); txAttributes = this.getTxAttributes(swap.attributes); const offer = Coin.fromString(txAttributes.offer); const ask = Coin.fromString(txAttributes.swap_coin); diff --git a/src/services/uniswap.js b/src/services/uniswap.js index 7d8bf97..cbb0247 100644 --- a/src/services/uniswap.js +++ b/src/services/uniswap.js @@ -56,8 +56,7 @@ export default class Uniswap { } async fetch_route(tIn, tOut) { - let route; - let pair; + var route, pair; try { pair = await uni.Fetcher.fetchPairData(tIn, tOut); @@ -69,19 +68,19 @@ export default class Uniswap { } generate_tokens() { - for (const token of routeTokens[this.network]) { - this.tokenList[token.address] = new uni.Token( + for (let token of routeTokens[this.network]) { + this.tokenList[token['address']] = new uni.Token( this.chainID, - token.address, - token.decimals, - token.symbol, - token.name + token['address'], + token['decimals'], + token['symbol'], + token['name'] ); } } async extend_update_pairs(tokens = []) { - for (const token of tokens) { + for (let token of tokens) { if (!Object.prototype.hasOwnProperty.call(this.tokenList, token)) { this.tokenList[token] = await uni.Fetcher.fetchTokenData( this.chainID, @@ -95,7 +94,7 @@ export default class Uniswap { async update_pairs() { // Remove banned pairs after ban period if (Object.keys(this.zeroReservePairs).length > 0) { - for (const pair in this.zeroReservePairs) { + for (let pair in this.zeroReservePairs) { if (this.zeroReservePairs[pair] <= Date.now()) { delete this.zeroReservePairs[pair]; // delete this.tokenList[token]; @@ -105,21 +104,19 @@ export default class Uniswap { // Generate all possible pair combinations of tokens // This is done by generating an upper triangular matrix or right triangular matrix if (Object.keys(this.tokenSwapList).length > 0) { - for (const token in this.tokenSwapList) { + for (let token in this.tokenSwapList) { if (this.tokenSwapList[token] <= Date.now()) { delete this.tokenSwapList[token]; // delete this.tokenList[token]; } } - const tokens = Object.keys(this.tokenList); - let firstToken; - let secondToken; - let position; - const length = tokens.length; - const pairs = []; - const pairAddressRequests = []; - const pairAddressResponses = []; + let tokens = Object.keys(this.tokenList); + var firstToken, secondToken, position; + let length = tokens.length; + let pairs = []; + let pairAddressRequests = []; + let pairAddressResponses = []; for (firstToken = 0; firstToken < length; firstToken++) { for ( secondToken = firstToken + 1; @@ -127,9 +124,10 @@ export default class Uniswap { secondToken++ ) { try { - const pairString = `${this.tokenList[tokens[firstToken]].address}-${ - this.tokenList[tokens[secondToken]].address - }`; + let pairString = + this.tokenList[tokens[firstToken]].address + + '-' + + this.tokenList[tokens[secondToken]].address; if ( !Object.prototype.hasOwnProperty.call( this.zeroReservePairs, diff --git a/src/services/uniswap_v3.js b/src/services/uniswap_v3.js index 88fe990..12e90fc 100644 --- a/src/services/uniswap_v3.js +++ b/src/services/uniswap_v3.js @@ -12,7 +12,7 @@ const coreArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Fact const nftArtifact = require('@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'); const routerArtifact = require('@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json'); const poolArtifact = require('@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json'); -// const routeTokens = require('../static/uniswap_route_tokens.json') +//const routeTokens = require('../static/uniswap_route_tokens.json') const abiDecoder = require('abi-decoder'); // constants @@ -63,18 +63,17 @@ export default class UniswapV3 { get_contract(contract, wallet) { if (contract === 'core') { return new ethers.Contract(this.core, coreArtifact.abi, wallet); - } - if (contract === 'router') { + } else if (contract === 'router') { return new ethers.Contract(this.router, routerArtifact.abi, wallet); + } else { + return new ethers.Contract(this.nftManager, nftArtifact.abi, wallet); } - return new ethers.Contract(this.nftManager, nftArtifact.abi, wallet); } async currentPrice(wallet, tokenIn, tokenOut) { - let pool; - let poolContract; - const poolPrices = []; - const poolLiquidity = []; + let pool, poolContract; + let poolPrices = []; + let poolLiquidity = []; const keys = ['LOW', 'MEDIUM', 'HIGH']; const coreContract = this.get_contract('core', wallet); @@ -101,7 +100,7 @@ export default class UniswapV3 { for (pool = 0; pool < 3; pool++) { poolPrices[pool] = poolLiquidity[pool] = 0; if (values[pool].value) { - for (const tick of values[pool].value.tickCumulatives) { + for (let tick of values[pool].value.tickCumulatives) { poolPrices[pool] = tick.toNumber() - poolPrices[pool]; } poolPrices[pool] = math.pow(1.0001, poolPrices[pool]); @@ -120,7 +119,7 @@ export default class UniswapV3 { tier, _gasPrice ) { - // sell, In => base, Out => quote + //sell, In => base, Out => quote const minPercentOut = 1 - this.slippage / 100; const amountOutMinimum = Math.floor( @@ -129,7 +128,7 @@ export default class UniswapV3 { minPercentOut * quoteTokenContractInfo.decimals ) / quoteTokenContractInfo.decimals; - // const priceFraction = math.fraction(limitPrice) + //const priceFraction = math.fraction(limitPrice) const contract = this.get_contract('router', wallet); const tx = await contract.exactInputSingle( { @@ -146,9 +145,11 @@ export default class UniswapV3 { amountOutMinimum.toString(), quoteTokenContractInfo.decimals ), + //sqrtPriceLimitX96: encodePriceSqrt(priceFraction.d, priceFraction.n) sqrtPriceLimitX96: 0 }, { + //gasPrice: gasPrice * 1e9, gasLimit: GAS_LIMIT } ); @@ -167,13 +168,13 @@ export default class UniswapV3 { tier, _gasPrice ) { - // buy, In => quote, Out => base + //buy, In => quote, Out => base const maxPercentIn = 1 + this.slippage / 100; const amountInMaximum = Math.ceil( baseAmount * limitPrice * maxPercentIn * quoteTokenContractInfo.decimals ) / quoteTokenContractInfo.decimals; - // const priceFraction = math.fraction(limitPrice) + //const priceFraction = math.fraction(limitPrice) const contract = this.get_contract('router', wallet); const tx = await contract.exactOutputSingle( { @@ -190,9 +191,11 @@ export default class UniswapV3 { amountInMaximum.toString(), quoteTokenContractInfo.decimals ), + //sqrtPriceLimitX96: encodePriceSqrt(priceFraction.d, priceFraction.n) sqrtPriceLimitX96: 0 }, { + //gasPrice: gasPrice * 1e9, gasLimit: GAS_LIMIT } ); @@ -228,8 +231,8 @@ export default class UniswapV3 { 'decreaseLiquidity', [ { - tokenId, - liquidity, + tokenId: tokenId, + liquidity: liquidity, amount0Min: 0, amount1Min: 0, deadline: Date.now() + TTL @@ -238,7 +241,7 @@ export default class UniswapV3 { ); const collectFeesData = contract.interface.encodeFunctionData('collect', [ { - tokenId, + tokenId: tokenId, recipient: wallet.signer.address, amount0Max: MaxUint128, amount1Max: MaxUint128 @@ -321,15 +324,16 @@ export default class UniswapV3 { upperPrice ); - const calls = [mintData]; + let calls = [mintData]; if (pool === ethers.constants.AddressZero) { const tx = await nftContract.multicall([initPoolData, mintData], { gasLimit: GAS_LIMIT }); return tx; + } else { + const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }); + return tx; } - const tx = await nftContract.multicall(calls, { gasLimit: GAS_LIMIT }); - return tx; } async removePosition(wallet, tokenId) { @@ -342,7 +346,7 @@ export default class UniswapV3 { tokenId, positionData.liquidity ); - return contract.multicall(data, { gasLimit: GAS_LIMIT }); + return await contract.multicall(data, { gasLimit: GAS_LIMIT }); } async replacePosition( @@ -357,7 +361,7 @@ export default class UniswapV3 { upperPrice ) { const contract = this.get_contract('nft', wallet); - const positionData = await this.getPosition(wallet, tokenId); + let positionData = await this.getPosition(wallet, tokenId); const removeData = this.getRemoveLiquidityData( wallet, contract, @@ -376,16 +380,49 @@ export default class UniswapV3 { upperPrice ); - return contract.multicall(removeData.concat(mintData), { + return await contract.multicall(removeData.concat(mintData), { gasLimit: GAS_LIMIT }); } + /* + async adjustLiquidity (wallet, action, tokenId, token0, token1, amount0, amount1) { + const contract = this.get_contract("nft", wallet); + const parsedAmount0 = ethers.utils.parseUnits(amount0, token0.decimals) + const parsedAmount1 = ethers.utils.parseUnits(amount1, token1.decimals) + if (action === "INCREASE") { + return await contract.increaseLiquidity({ + tokenId: tokenId, + amount0Desired: parsedAmount0, + amount1Desired: parsedAmount1, + amount0Min: 0, + amount1Min: 0, + deadline: Date.now() + TTL}, + { gasLimit: GAS_LIMIT }); + } else { + //const liquidity = getLiquidity(ethers.utils.parseUnits(amount0, 6), ethers.utils.parseUnits(amount1, 6)) // use method from sdk to calculate liquidity from amount correctly + const liquidity = getLiquidity(amount0, amount1) + const decreaseLiquidityData = contract.interface.encodeFunctionData('decreaseLiquidity', [{ + tokenId: tokenId, + liquidity: liquidity, + amount0Min: 0, + amount1Min: 0, + deadline: Date.now() + TTL}]); + const collectFeesData = contract.interface.encodeFunctionData('collect', [{ + tokenId: tokenId, + recipient: wallet.signer.address, + amount0Max: MaxUint128, + amount1Max: MaxUint128}]); + + //return await contract.multicall([decreaseLiquidityData, collectFeesData], { gasLimit: GAS_LIMIT }); + } + } + */ async collectFees(wallet, tokenId) { const contract = this.get_contract('nft', wallet); - return contract.collect( + return await contract.collect( { - tokenId, + tokenId: tokenId, recipient: wallet.signer.address, amount0Max: MaxUint128, amount1Max: MaxUint128 diff --git a/src/services/utils.js b/src/services/utils.js index 110f170..f26a891 100644 --- a/src/services/utils.js +++ b/src/services/utils.js @@ -1,7 +1,6 @@ /* Hummingbot Utils */ - const config = require('./configuration_manager'); const lodash = require('lodash'); const moment = require('moment'); @@ -24,8 +23,8 @@ export const latency = (startTime, endTime) => export const isValidParams = (params) => { const values = Object.values(params); - // DO NOT use forEach, it returns callback without breaking the loop for (let i = 0; i < values.length; i++) { + // DO NOT use forEach, it returns callback without breaking the loop if (typeof values[i] === 'undefined') { throw new Error('Invalid input params'); } @@ -96,6 +95,11 @@ export const loadConfig = () => { return config.configManagerInstance.readAllConfigs(); }; +export const updateConfig = (data) => { + globalConfig.updateConfig(data); + return true; +}; + export const getLocalDate = () => { const gmtOffset = globalConfig.getConfig('GMT_OFFSET'); let newDate = moment().format('YYYY-MM-DD hh:mm:ss').trim(); @@ -112,11 +116,6 @@ export const getLocalDate = () => { return newDate; }; -export const updateConfig = (data) => { - globalConfig.updateConfig(data); - return true; -}; - export const nonceManagerCache = {}; export const getNonceManager = async (signer) => { diff --git a/src/static/uniswap-v3/helper_functions.js b/src/static/uniswap-v3/helper_functions.js index 7cc3ae1..6bd0603 100644 --- a/src/static/uniswap-v3/helper_functions.js +++ b/src/static/uniswap-v3/helper_functions.js @@ -1,26 +1,11 @@ import bn from 'bignumber.js'; -import JSBI from 'jsbi'; -import { BigNumber, mulShift, Q32, ZERO, ONE, MaxUint256 } from 'ethers'; +import { BigNumber } from 'ethers'; const math = require('mathjs'); - const TICK_SPACINGS = { LOW: 10, MEDIUM: 60, HIGH: 2000 }; bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }); -export function expandTo18Decimals(n) { - return BigNumber.from(n).mul(BigNumber.from(10).pow(18)); -} - -export function toHex(bigintIsh) { - const bigInt = JSBI.BigInt(bigintIsh); - let hex = bigInt.toString(16); - if (hex.length % 2 !== 0) { - hex = `0${hex}`; - } - return `0x${hex}`; -} - // returns the sqrt price as a 64x96 export function encodePriceSqrt(reserve1, reserve0) { return BigNumber.from( @@ -33,159 +18,8 @@ export function encodePriceSqrt(reserve1, reserve0) { ); } -export function getLiquidity(amount0, amount1) { - return BigNumber.from( - new bn(amount0.toString()) - .multipliedBy(amount1.toString()) - .sqrt() - .toString() - ); - /* let tokenPrice0, tokenPrice1, tokenFraction; - tokenFraction = math.fraction(amount1/amount0) - tokenPrice0 = encodePriceSqrt(tokenFraction.n, tokenFraction.d) - tokenPrice1 = encodePriceSqrt(tokenFraction.d, tokenFraction.n) - return tokenPrice0.mul(tokenPrice1) */ -} - -const TWO = JSBI.BigInt(2); -const POWERS_OF_2 = [128, 64, 32, 16, 8, 4, 2, 1].map((pow) => [ - pow, - JSBI.exponentiate(TWO, JSBI.BigInt(pow)) -]); - -export function mostSignificantBit(x) { - let y = x; - let msb = 0; - for (const [power, min] of POWERS_OF_2) { - if (JSBI.greaterThanOrEqual(y, min)) { - y = JSBI.signedRightShift(y, JSBI.BigInt(power)); - msb += power; - } - } - return msb; -} - -export function getSqrtRatioAtTick(tick) { - const absTick = tick < 0 ? tick * -1 : tick; - - let ratio = - (absTick & 0x1) !== 0 - ? JSBI.BigInt('0xfffcb933bd6fad37aa2d162d1a594001') - : JSBI.BigInt('0x100000000000000000000000000000000'); - if ((absTick & 0x2) !== 0) - ratio = mulShift(ratio, '0xfff97272373d413259a46990580e213a'); - if ((absTick & 0x4) !== 0) - ratio = mulShift(ratio, '0xfff2e50f5f656932ef12357cf3c7fdcc'); - if ((absTick & 0x8) !== 0) - ratio = mulShift(ratio, '0xffe5caca7e10e4e61c3624eaa0941cd0'); - if ((absTick & 0x10) !== 0) - ratio = mulShift(ratio, '0xffcb9843d60f6159c9db58835c926644'); - if ((absTick & 0x20) !== 0) - ratio = mulShift(ratio, '0xff973b41fa98c081472e6896dfb254c0'); - if ((absTick & 0x40) !== 0) - ratio = mulShift(ratio, '0xff2ea16466c96a3843ec78b326b52861'); - if ((absTick & 0x80) !== 0) - ratio = mulShift(ratio, '0xfe5dee046a99a2a811c461f1969c3053'); - if ((absTick & 0x100) !== 0) - ratio = mulShift(ratio, '0xfcbe86c7900a88aedcffc83b479aa3a4'); - if ((absTick & 0x200) !== 0) - ratio = mulShift(ratio, '0xf987a7253ac413176f2b074cf7815e54'); - if ((absTick & 0x400) !== 0) - ratio = mulShift(ratio, '0xf3392b0822b70005940c7a398e4b70f3'); - if ((absTick & 0x800) !== 0) - ratio = mulShift(ratio, '0xe7159475a2c29b7443b29c7fa6e889d9'); - if ((absTick & 0x1000) !== 0) - ratio = mulShift(ratio, '0xd097f3bdfd2022b8845ad8f792aa5825'); - if ((absTick & 0x2000) !== 0) - ratio = mulShift(ratio, '0xa9f746462d870fdf8a65dc1f90e061e5'); - if ((absTick & 0x4000) !== 0) - ratio = mulShift(ratio, '0x70d869a156d2a1b890bb3df62baf32f7'); - if ((absTick & 0x8000) !== 0) - ratio = mulShift(ratio, '0x31be135f97d08fd981231505542fcfa6'); - if ((absTick & 0x10000) !== 0) - ratio = mulShift(ratio, '0x9aa508b5b7a84e1c677de54f3e99bc9'); - if ((absTick & 0x20000) !== 0) - ratio = mulShift(ratio, '0x5d6af8dedb81196699c329225ee604'); - if ((absTick & 0x40000) !== 0) - ratio = mulShift(ratio, '0x2216e584f5fa1ea926041bedfe98'); - if ((absTick & 0x80000) !== 0) - ratio = mulShift(ratio, '0x48a170391f7dc42444e8fa2'); - - if (tick > 0) ratio = JSBI.divide(MaxUint256, ratio); - - // back to Q96 - return JSBI.greaterThan(JSBI.remainder(ratio, Q32), ZERO) - ? JSBI.add(JSBI.divide(ratio, Q32), ONE) - : JSBI.divide(ratio, Q32); -} - -export function getTickAtSqrtRatio(sqrtRatioX96) { - const sqrtRatioX128 = JSBI.leftShift(sqrtRatioX96, JSBI.BigInt(32)); - - const msb = mostSignificantBit(sqrtRatioX128); - - let r; - if (JSBI.greaterThanOrEqual(JSBI.BigInt(msb), JSBI.BigInt(128))) { - r = JSBI.signedRightShift(sqrtRatioX128, JSBI.BigInt(msb - 127)); - } else { - r = JSBI.leftShift(sqrtRatioX128, JSBI.BigInt(127 - msb)); - } - - let log_2 = JSBI.leftShift( - JSBI.subtract(JSBI.BigInt(msb), JSBI.BigInt(128)), - JSBI.BigInt(64) - ); - - for (let i = 0; i < 14; i++) { - r = JSBI.signedRightShift(JSBI.multiply(r, r), JSBI.BigInt(127)); - const f = JSBI.signedRightShift(r, JSBI.BigInt(128)); - log_2 = JSBI.bitwiseOr(log_2, JSBI.leftShift(f, JSBI.BigInt(63 - i))); - r = JSBI.signedRightShift(r, f); - } - - const log_sqrt10001 = JSBI.multiply( - log_2, - JSBI.BigInt('255738958999603826347141') - ); - - const tickLow = JSBI.toNumber( - JSBI.signedRightShift( - JSBI.subtract( - log_sqrt10001, - JSBI.BigInt('3402992956809132418596140100660247210') - ), - JSBI.BigInt(128) - ) - ); - const tickHigh = JSBI.toNumber( - JSBI.signedRightShift( - JSBI.add( - log_sqrt10001, - JSBI.BigInt('291339464771989622907027621153398088495') - ), - JSBI.BigInt(128) - ) - ); - - if (tickLow === tickHigh) { - return tickLow; - } - - return JSBI.lessThanOrEqual(getSqrtRatioAtTick(tickHigh), sqrtRatioX96) - ? tickHigh - : tickLow; -} - -export function getMinTick(tier) { - return Math.ceil(-887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; -} - -export function getMaxTick(tier) { - return Math.floor(887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; -} - export function getTickFromPrice(price, tier, side) { - let tick = 0; + var tick = 0; if (side === 'UPPER') { tick = math.ceil(math.log(price, 1.0001) / TICK_SPACINGS[tier]) * @@ -198,9 +32,17 @@ export function getTickFromPrice(price, tier, side) { if (tick >= getMaxTick(tier)) { return getMaxTick(tier); - } - if (tick <= getMinTick(tier)) { + } else if (tick <= getMinTick(tier)) { return getMinTick(tier); + } else { + return tick; } - return tick; +} + +export function getMinTick(tier) { + return Math.ceil(-887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; +} + +export function getMaxTick(tier) { + return Math.floor(887272 / TICK_SPACINGS[tier]) * TICK_SPACINGS[tier]; } diff --git a/yarn.lock b/yarn.lock index 30acb66..365357b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1564,9 +1564,9 @@ ajv@^6.10.0, ajv@^6.12.4: uri-js "^4.2.2" ajv@^8.0.1: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b" - integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== + version "8.6.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.0.tgz#60cc45d9c46a477d80d92c48076d972c342e5720" + integrity sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -4108,9 +4108,9 @@ node-modules-regexp@^1.0.0: integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= node-releases@^1.1.71: - version "1.1.72" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" - integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== + version "1.1.73" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" + integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== nodemon@^2.0.4: version "2.0.7"