mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-22 21:59:44 +03:00
39
.eslintrc.js
39
.eslintrc.js
@@ -6,11 +6,13 @@ module.exports = {
|
|||||||
node: true,
|
node: true,
|
||||||
},
|
},
|
||||||
extends: [
|
extends: [
|
||||||
'standard',
|
'standard-with-typescript',
|
||||||
'eslint:recommended',
|
'eslint:recommended',
|
||||||
'plugin:@typescript-eslint/eslint-recommended',
|
'plugin:@typescript-eslint/eslint-recommended',
|
||||||
'plugin:@typescript-eslint/recommended',
|
'plugin:@typescript-eslint/recommended',
|
||||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||||
|
'plugin:@typescript-eslint/strict',
|
||||||
|
'plugin:import/recommended',
|
||||||
'plugin:import/typescript'
|
'plugin:import/typescript'
|
||||||
],
|
],
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
@@ -26,6 +28,39 @@ module.exports = {
|
|||||||
'@typescript-eslint',
|
'@typescript-eslint',
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
|
"@typescript-eslint/strict-boolean-expressions": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"allowNullableObject": true,
|
||||||
|
"allowString": false,
|
||||||
|
"allowNumber": false,
|
||||||
|
"allowNullableBoolean": false,
|
||||||
|
"allowNullableString": false,
|
||||||
|
"allowNullableNumber": false,
|
||||||
|
"allowAny": false,
|
||||||
|
"allowNullableEnum": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"eqeqeq": "error",
|
||||||
|
"@typescript-eslint/consistent-type-definitions": [
|
||||||
|
"warn",
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"@typescript-eslint/indent": [
|
||||||
|
"error",
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
"SwitchCase": 1,
|
||||||
|
"ignoredNodes": [
|
||||||
|
"TSTypeParameterInstantiation"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@typescript-eslint/promise-function-async": 0,
|
||||||
|
"import/no-cycle": "error",
|
||||||
|
"@typescript-eslint/space-before-function-paren": 0,
|
||||||
|
"@typescript-eslint/comma-dangle": 0,
|
||||||
|
"@typescript-eslint/semi": 0,
|
||||||
"comma-dangle": 0,
|
"comma-dangle": 0,
|
||||||
"semi": 0,
|
"semi": 0,
|
||||||
"space-before-function-paren": 0,
|
"space-before-function-paren": 0,
|
||||||
@@ -61,6 +96,8 @@ module.exports = {
|
|||||||
2,
|
2,
|
||||||
{
|
{
|
||||||
ignoreComments: true,
|
ignoreComments: true,
|
||||||
|
ignoreUrls: true,
|
||||||
|
ignoreTemplateLiterals: true,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'import/extensions': [
|
'import/extensions': [
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
npm test
|
# npm test
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -11,5 +11,6 @@
|
|||||||
"./README.md": [
|
"./README.md": [
|
||||||
"# Orion Protocol SDK"
|
"# Orion Protocol SDK"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"typescript.tsdk": "node_modules/typescript/lib"
|
||||||
}
|
}
|
||||||
296
package-lock.json
generated
296
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@orionprotocol/sdk",
|
"name": "@orionprotocol/sdk",
|
||||||
"version": "0.17.5-rc.0",
|
"version": "0.17.7-rc.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@orionprotocol/sdk",
|
"name": "@orionprotocol/sdk",
|
||||||
"version": "0.17.5-rc.0",
|
"version": "0.17.7-rc.1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ethersproject/abstract-signer": "^5.7.0",
|
"@ethersproject/abstract-signer": "^5.7.0",
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
"eslint-plugin-import": "^2.27.5",
|
"eslint-plugin-import": "^2.27.5",
|
||||||
"eslint-plugin-n": "^15.6.1",
|
"eslint-plugin-n": "^15.6.1",
|
||||||
"eslint-plugin-promise": "^6.1.1",
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
|
"http-terminator": "^3.2.0",
|
||||||
"husky": "^7.0.4",
|
"husky": "^7.0.4",
|
||||||
"is-ci": "^3.0.1",
|
"is-ci": "^3.0.1",
|
||||||
"jest": "^29.4.2",
|
"jest": "^29.4.2",
|
||||||
@@ -3835,6 +3836,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/boolean": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
@@ -4549,6 +4556,18 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/delay": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/delayed-stream": {
|
"node_modules/delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
@@ -5648,12 +5667,39 @@
|
|||||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-json-stringify": {
|
||||||
|
"version": "2.7.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-2.7.13.tgz",
|
||||||
|
"integrity": "sha512-ar+hQ4+OIurUGjSJD1anvYSDcUflywhKjfxnsW4TBTD7+u0tJufv6DKRWoQk3vI6YBOWMoz0TQtfbe7dxbQmvA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": "^6.11.0",
|
||||||
|
"deepmerge": "^4.2.2",
|
||||||
|
"rfdc": "^1.2.0",
|
||||||
|
"string-similarity": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fast-levenshtein": {
|
"node_modules/fast-levenshtein": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||||
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
|
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-printf": {
|
||||||
|
"version": "1.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.9.tgz",
|
||||||
|
"integrity": "sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"boolean": "^3.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fastest-levenshtein": {
|
"node_modules/fastest-levenshtein": {
|
||||||
"version": "1.0.16",
|
"version": "1.0.16",
|
||||||
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
|
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
|
||||||
@@ -5984,6 +6030,21 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/globalthis": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"define-properties": "^1.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/globby": {
|
"node_modules/globby": {
|
||||||
"version": "11.1.0",
|
"version": "11.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
||||||
@@ -6179,6 +6240,33 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/http-terminator": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-terminator/-/http-terminator-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-JLjck1EzPaWjsmIf8bziM3p9fgR1Y3JoUKAkyYEbZmFrIvJM6I8vVJfBGWlEtV9IWOvzNnaTtjuwZeBY2kwB4g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"delay": "^5.0.0",
|
||||||
|
"p-wait-for": "^3.2.0",
|
||||||
|
"roarr": "^7.0.4",
|
||||||
|
"type-fest": "^2.3.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-terminator/node_modules/type-fest": {
|
||||||
|
"version": "2.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||||
|
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/human-signals": {
|
"node_modules/human-signals": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
@@ -9093,6 +9181,15 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/p-finally": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/p-limit": {
|
"node_modules/p-limit": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||||
@@ -9123,6 +9220,18 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/p-timeout": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"p-finally": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/p-try": {
|
"node_modules/p-try": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||||
@@ -9132,6 +9241,21 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/p-wait-for": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"p-timeout": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/parent-module": {
|
"node_modules/parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -9657,6 +9781,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rfdc": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/rimraf": {
|
"node_modules/rimraf": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
@@ -9681,6 +9811,23 @@
|
|||||||
"inherits": "^2.0.1"
|
"inherits": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/roarr": {
|
||||||
|
"version": "7.14.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/roarr/-/roarr-7.14.2.tgz",
|
||||||
|
"integrity": "sha512-9vC/n53oTJEyAl0ZJczKjJ5mJheb2DaqiaNSnxDWrqiRTrozxSvSq05yCTN+Fc7e5mhDRTTZ14RlMu1x4tEc0w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"boolean": "^3.1.4",
|
||||||
|
"fast-json-stringify": "^2.7.10",
|
||||||
|
"fast-printf": "^1.6.9",
|
||||||
|
"globalthis": "^1.0.2",
|
||||||
|
"safe-stable-stringify": "^2.4.1",
|
||||||
|
"semver-compare": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/run-parallel": {
|
"node_modules/run-parallel": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||||
@@ -9746,6 +9893,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/safe-stable-stringify": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/safer-buffer": {
|
"node_modules/safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
@@ -9783,6 +9939,12 @@
|
|||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/semver-compare": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/send": {
|
"node_modules/send": {
|
||||||
"version": "0.18.0",
|
"version": "0.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||||
@@ -10029,6 +10191,12 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/string-similarity": {
|
||||||
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
@@ -13947,6 +14115,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"boolean": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
@@ -14496,6 +14670,12 @@
|
|||||||
"object-keys": "^1.1.1"
|
"object-keys": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"delay": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"delayed-stream": {
|
"delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
@@ -15325,12 +15505,33 @@
|
|||||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"fast-json-stringify": {
|
||||||
|
"version": "2.7.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-2.7.13.tgz",
|
||||||
|
"integrity": "sha512-ar+hQ4+OIurUGjSJD1anvYSDcUflywhKjfxnsW4TBTD7+u0tJufv6DKRWoQk3vI6YBOWMoz0TQtfbe7dxbQmvA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ajv": "^6.11.0",
|
||||||
|
"deepmerge": "^4.2.2",
|
||||||
|
"rfdc": "^1.2.0",
|
||||||
|
"string-similarity": "^4.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fast-levenshtein": {
|
"fast-levenshtein": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||||
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
|
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"fast-printf": {
|
||||||
|
"version": "1.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.9.tgz",
|
||||||
|
"integrity": "sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"boolean": "^3.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fastest-levenshtein": {
|
"fastest-levenshtein": {
|
||||||
"version": "1.0.16",
|
"version": "1.0.16",
|
||||||
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
|
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
|
||||||
@@ -15575,6 +15776,15 @@
|
|||||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"globalthis": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"define-properties": "^1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"globby": {
|
"globby": {
|
||||||
"version": "11.1.0",
|
"version": "11.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
||||||
@@ -15726,6 +15936,26 @@
|
|||||||
"toidentifier": "1.0.1"
|
"toidentifier": "1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"http-terminator": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-terminator/-/http-terminator-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-JLjck1EzPaWjsmIf8bziM3p9fgR1Y3JoUKAkyYEbZmFrIvJM6I8vVJfBGWlEtV9IWOvzNnaTtjuwZeBY2kwB4g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"delay": "^5.0.0",
|
||||||
|
"p-wait-for": "^3.2.0",
|
||||||
|
"roarr": "^7.0.4",
|
||||||
|
"type-fest": "^2.3.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"type-fest": {
|
||||||
|
"version": "2.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||||
|
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"human-signals": {
|
"human-signals": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
@@ -17854,6 +18084,12 @@
|
|||||||
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
|
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"p-finally": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"p-limit": {
|
"p-limit": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||||
@@ -17872,12 +18108,30 @@
|
|||||||
"p-limit": "^3.0.2"
|
"p-limit": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"p-timeout": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"p-finally": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"p-try": {
|
"p-try": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"p-wait-for": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"p-timeout": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"parent-module": {
|
"parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -18261,6 +18515,12 @@
|
|||||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"rfdc": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
@@ -18279,6 +18539,20 @@
|
|||||||
"inherits": "^2.0.1"
|
"inherits": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"roarr": {
|
||||||
|
"version": "7.14.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/roarr/-/roarr-7.14.2.tgz",
|
||||||
|
"integrity": "sha512-9vC/n53oTJEyAl0ZJczKjJ5mJheb2DaqiaNSnxDWrqiRTrozxSvSq05yCTN+Fc7e5mhDRTTZ14RlMu1x4tEc0w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"boolean": "^3.1.4",
|
||||||
|
"fast-json-stringify": "^2.7.10",
|
||||||
|
"fast-printf": "^1.6.9",
|
||||||
|
"globalthis": "^1.0.2",
|
||||||
|
"safe-stable-stringify": "^2.4.1",
|
||||||
|
"semver-compare": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"run-parallel": {
|
"run-parallel": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||||
@@ -18313,6 +18587,12 @@
|
|||||||
"is-regex": "^1.1.4"
|
"is-regex": "^1.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"safe-stable-stringify": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
@@ -18340,6 +18620,12 @@
|
|||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"semver-compare": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"send": {
|
"send": {
|
||||||
"version": "0.18.0",
|
"version": "0.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||||
@@ -18550,6 +18836,12 @@
|
|||||||
"strip-ansi": "^6.0.0"
|
"strip-ansi": "^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"string-similarity": {
|
||||||
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@orionprotocol/sdk",
|
"name": "@orionprotocol/sdk",
|
||||||
"version": "0.17.6",
|
"version": "0.17.7-rc.3",
|
||||||
"description": "Orion Protocol SDK",
|
"description": "Orion Protocol SDK",
|
||||||
"main": "./lib/esm/index.js",
|
"main": "./lib/esm/index.js",
|
||||||
"module": "./lib/esm/index.js",
|
"module": "./lib/esm/index.js",
|
||||||
@@ -59,6 +59,7 @@
|
|||||||
"eslint-plugin-import": "^2.27.5",
|
"eslint-plugin-import": "^2.27.5",
|
||||||
"eslint-plugin-n": "^15.6.1",
|
"eslint-plugin-n": "^15.6.1",
|
||||||
"eslint-plugin-promise": "^6.1.1",
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
|
"http-terminator": "^3.2.0",
|
||||||
"husky": "^7.0.4",
|
"husky": "^7.0.4",
|
||||||
"is-ci": "^3.0.1",
|
"is-ci": "^3.0.1",
|
||||||
"jest": "^29.4.2",
|
"jest": "^29.4.2",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import BigNumber from 'bignumber.js';
|
|||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import clone from 'just-clone';
|
import clone from 'just-clone';
|
||||||
import { ERC20__factory } from '@orionprotocol/contracts';
|
import { ERC20__factory } from '@orionprotocol/contracts';
|
||||||
import { utils } from '.';
|
|
||||||
import { APPROVE_ERC20_GAS_LIMIT, NATIVE_CURRENCY_PRECISION } from './constants';
|
import { APPROVE_ERC20_GAS_LIMIT, NATIVE_CURRENCY_PRECISION } from './constants';
|
||||||
import type {
|
import type {
|
||||||
AggregatedBalanceRequirement, ApproveFix, Asset, BalanceIssue, BalanceRequirement, Source,
|
AggregatedBalanceRequirement, ApproveFix, Asset, BalanceIssue, BalanceRequirement, Source,
|
||||||
@@ -16,7 +15,8 @@ export default class BalanceGuard {
|
|||||||
string,
|
string,
|
||||||
Record<
|
Record<
|
||||||
'exchange' | 'wallet',
|
'exchange' | 'wallet',
|
||||||
BigNumber>
|
BigNumber
|
||||||
|
>
|
||||||
>
|
>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ export default class BalanceGuard {
|
|||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
private fixAllAutofixableBalanceIssues = async (
|
private readonly fixAllAutofixableBalanceIssues = async (
|
||||||
balanceIssues: BalanceIssue[],
|
balanceIssues: BalanceIssue[],
|
||||||
) => {
|
) => {
|
||||||
const fixBalanceIssue = async (issue: BalanceIssue) => {
|
const fixBalanceIssue = async (issue: BalanceIssue) => {
|
||||||
@@ -146,8 +146,8 @@ export default class BalanceGuard {
|
|||||||
};
|
};
|
||||||
await issue.fixes?.reduce(async (promise, item) => {
|
await issue.fixes?.reduce(async (promise, item) => {
|
||||||
await promise;
|
await promise;
|
||||||
if (item.type === 'byApprove') return approve(item);
|
if (item.type === 'byApprove') { await approve(item); return; }
|
||||||
return promise;
|
await promise;
|
||||||
}, Promise.resolve());
|
}, Promise.resolve());
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ export default class BalanceGuard {
|
|||||||
|
|
||||||
await autofixableBalanceIssues.reduce(async (promise, item) => {
|
await autofixableBalanceIssues.reduce(async (promise, item) => {
|
||||||
await promise;
|
await promise;
|
||||||
return fixBalanceIssue(item);
|
await fixBalanceIssue(item);
|
||||||
}, Promise.resolve());
|
}, Promise.resolve());
|
||||||
|
|
||||||
return balanceIssues.filter((item) => !autofixableBalanceIssues.includes(item));
|
return balanceIssues.filter((item) => !autofixableBalanceIssues.includes(item));
|
||||||
@@ -196,18 +196,18 @@ export default class BalanceGuard {
|
|||||||
const remainingBalance = remainingBalances[asset.name];
|
const remainingBalance = remainingBalances[asset.name];
|
||||||
if (!remainingBalance) throw new Error(`No ${asset.name} balance`);
|
if (!remainingBalance) throw new Error(`No ${asset.name} balance`);
|
||||||
const itemsAmountSum = Object.values(items)
|
const itemsAmountSum = Object.values(items)
|
||||||
.reduce<BigNumber>((p, c) => (c ? p.plus(c) : p), new BigNumber(0));
|
.reduce<BigNumber>((p, c) => (c !== undefined ? p.plus(c) : p), new BigNumber(0));
|
||||||
|
|
||||||
remainingBalance.exchange = remainingBalance.exchange.minus(itemsAmountSum);
|
remainingBalance.exchange = remainingBalance.exchange.minus(itemsAmountSum);
|
||||||
if (remainingBalance.exchange.lt(0)) {
|
if (remainingBalance.exchange.lt(0)) {
|
||||||
const lackAmount = remainingBalance.exchange.abs();
|
const lackAmount = remainingBalance.exchange.abs();
|
||||||
const exchangeBalance = this.balances?.[asset.name]?.exchange;
|
const exchangeBalance = this.balances[asset.name]?.exchange;
|
||||||
|
|
||||||
balanceIssues.push({
|
balanceIssues.push({
|
||||||
asset,
|
asset,
|
||||||
sources: ['exchange'],
|
sources: ['exchange'],
|
||||||
message: `Not enough ${asset.name} on exchange balance. ` +
|
message: `Not enough ${asset.name} on exchange balance. ` +
|
||||||
`Needed: ${itemsAmountSum.toString()}, available: ${(exchangeBalance ?? '[UNDEFINED]')?.toString()}. ` +
|
`Needed: ${itemsAmountSum.toString()}, available: ${(exchangeBalance ?? '[UNDEFINED]').toString()}. ` +
|
||||||
`You need to deposit at least ${lackAmount.toString()} ${asset.name} into exchange contract`,
|
`You need to deposit at least ${lackAmount.toString()} ${asset.name} into exchange contract`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ export default class BalanceGuard {
|
|||||||
const remainingBalance = remainingBalances[asset.name];
|
const remainingBalance = remainingBalances[asset.name];
|
||||||
if (!remainingBalance) throw new Error(`No ${asset.name} balance`);
|
if (!remainingBalance) throw new Error(`No ${asset.name} balance`);
|
||||||
const itemsAmountSum = Object.values(items)
|
const itemsAmountSum = Object.values(items)
|
||||||
.reduce<BigNumber>((p, c) => (c ? p.plus(c) : p), new BigNumber(0));
|
.reduce<BigNumber>((p, c) => (c !== undefined ? p.plus(c) : p), new BigNumber(0));
|
||||||
|
|
||||||
remainingBalance.exchange = remainingBalance.exchange.minus(itemsAmountSum);
|
remainingBalance.exchange = remainingBalance.exchange.minus(itemsAmountSum);
|
||||||
if (remainingBalance.exchange.lt(0)) {
|
if (remainingBalance.exchange.lt(0)) {
|
||||||
@@ -233,7 +233,7 @@ export default class BalanceGuard {
|
|||||||
if (asset.address === ethers.constants.AddressZero) {
|
if (asset.address === ethers.constants.AddressZero) {
|
||||||
denormalizedAllowance = remainingBalance.wallet;
|
denormalizedAllowance = remainingBalance.wallet;
|
||||||
} else {
|
} else {
|
||||||
if (!spenderAddress) throw new Error(`Spender address is required for ${asset.name}`);
|
if (spenderAddress === undefined) throw new Error(`Spender address is required for ${asset.name}`);
|
||||||
const tokenContract = ERC20__factory.connect(asset.address, this.provider);
|
const tokenContract = ERC20__factory.connect(asset.address, this.provider);
|
||||||
const tokenDecimals = await tokenContract.decimals();
|
const tokenDecimals = await tokenContract.decimals();
|
||||||
const tokenAllowance = await tokenContract.allowance(walletAddress, spenderAddress);
|
const tokenAllowance = await tokenContract.allowance(walletAddress, spenderAddress);
|
||||||
@@ -257,17 +257,17 @@ export default class BalanceGuard {
|
|||||||
const approveIsHelpful = approveAvailable.gte(lackAmount);
|
const approveIsHelpful = approveAvailable.gte(lackAmount);
|
||||||
const targetApprove = approvedWalletBalance.plus(lackAmount);
|
const targetApprove = approvedWalletBalance.plus(lackAmount);
|
||||||
|
|
||||||
const exchangeBalance = this.balances?.[asset.name]?.exchange;
|
const exchangeBalance = this.balances[asset.name]?.exchange;
|
||||||
const available = exchangeBalance?.plus(approvedWalletBalance);
|
const available = exchangeBalance?.plus(approvedWalletBalance);
|
||||||
|
|
||||||
const issueMessage = `Not enough ${asset.name} on exchange + wallet balance. ` +
|
const issueMessage = `Not enough ${asset.name} on exchange + wallet balance. ` +
|
||||||
`Needed: ${itemsAmountSum.toString()}, available: ${(available ?? '[UNDEFINED]')?.toString()} ` +
|
`Needed: ${itemsAmountSum.toString()}, available: ${(available ?? '[UNDEFINED]').toString()} ` +
|
||||||
`(exchange: ${(exchangeBalance ?? '[UNKNOWN]')?.toString()}, available (approved): ${approvedWalletBalance.toString()}).` +
|
`(exchange: ${(exchangeBalance ?? '[UNKNOWN]').toString()}, available (approved): ${approvedWalletBalance.toString()}).` +
|
||||||
` ${approveIsHelpful
|
` ${approveIsHelpful
|
||||||
? `You need approve at least ${lackAmount.toString()} ${asset.name}`
|
? `You need approve at least ${lackAmount.toString()} ${asset.name}`
|
||||||
: 'Approve is not helpful'}`;
|
: 'Approve is not helpful'}`;
|
||||||
if (approveIsHelpful) {
|
if (approveIsHelpful) {
|
||||||
if (!spenderAddress) throw new Error(`Spender address is required for ${asset.name}`);
|
if (spenderAddress === undefined) throw new Error(`Spender address is required for ${asset.name}`);
|
||||||
const resetRequired = await this.checkResetRequired(
|
const resetRequired = await this.checkResetRequired(
|
||||||
asset.address,
|
asset.address,
|
||||||
spenderAddress,
|
spenderAddress,
|
||||||
@@ -276,8 +276,10 @@ export default class BalanceGuard {
|
|||||||
const approveTransactionCost = ethers.BigNumber
|
const approveTransactionCost = ethers.BigNumber
|
||||||
.from(APPROVE_ERC20_GAS_LIMIT)
|
.from(APPROVE_ERC20_GAS_LIMIT)
|
||||||
.mul(gasPriceWei);
|
.mul(gasPriceWei);
|
||||||
const denormalizedApproveTransactionCost = utils
|
const denormalizedApproveTransactionCost = denormalizeNumber(
|
||||||
.denormalizeNumber(approveTransactionCost, NATIVE_CURRENCY_PRECISION);
|
approveTransactionCost,
|
||||||
|
NATIVE_CURRENCY_PRECISION
|
||||||
|
);
|
||||||
|
|
||||||
requiredApproves.items = {
|
requiredApproves.items = {
|
||||||
...requiredApproves.items,
|
...requiredApproves.items,
|
||||||
@@ -324,13 +326,13 @@ export default class BalanceGuard {
|
|||||||
const remainingBalance = remainingBalances[asset.name];
|
const remainingBalance = remainingBalances[asset.name];
|
||||||
if (!remainingBalance) throw new Error(`No ${asset.name} balance`);
|
if (!remainingBalance) throw new Error(`No ${asset.name} balance`);
|
||||||
const itemsAmountSum = Object.values(items)
|
const itemsAmountSum = Object.values(items)
|
||||||
.reduce<BigNumber>((p, c) => (c ? p.plus(c) : p), new BigNumber(0));
|
.reduce<BigNumber>((p, c) => (c !== undefined ? p.plus(c) : p), new BigNumber(0));
|
||||||
|
|
||||||
let denormalizedAllowance: BigNumber;
|
let denormalizedAllowance: BigNumber;
|
||||||
if (asset.address === ethers.constants.AddressZero) {
|
if (asset.address === ethers.constants.AddressZero) {
|
||||||
denormalizedAllowance = remainingBalance.wallet;
|
denormalizedAllowance = remainingBalance.wallet;
|
||||||
} else {
|
} else {
|
||||||
if (!spenderAddress) throw new Error(`Spender address is required for ${asset.name}`);
|
if (spenderAddress === undefined) throw new Error(`Spender address is required for ${asset.name}`);
|
||||||
const tokenContract = ERC20__factory.connect(asset.address, this.provider);
|
const tokenContract = ERC20__factory.connect(asset.address, this.provider);
|
||||||
const tokenDecimals = await tokenContract.decimals();
|
const tokenDecimals = await tokenContract.decimals();
|
||||||
const tokenAllowance = await tokenContract.allowance(walletAddress, spenderAddress);
|
const tokenAllowance = await tokenContract.allowance(walletAddress, spenderAddress);
|
||||||
@@ -358,7 +360,7 @@ export default class BalanceGuard {
|
|||||||
? `You need approve at least ${lackAmount.toString()} ${asset.name}`
|
? `You need approve at least ${lackAmount.toString()} ${asset.name}`
|
||||||
: 'Approve is not helpful'}`;
|
: 'Approve is not helpful'}`;
|
||||||
if (approveIsHelpful) {
|
if (approveIsHelpful) {
|
||||||
if (!spenderAddress) throw new Error(`Spender address is required for ${asset.name}`);
|
if (spenderAddress === undefined) throw new Error(`Spender address is required for ${asset.name}`);
|
||||||
const resetRequired = await this.checkResetRequired(
|
const resetRequired = await this.checkResetRequired(
|
||||||
asset.address,
|
asset.address,
|
||||||
spenderAddress,
|
spenderAddress,
|
||||||
@@ -367,8 +369,10 @@ export default class BalanceGuard {
|
|||||||
const approveTransactionCost = ethers.BigNumber
|
const approveTransactionCost = ethers.BigNumber
|
||||||
.from(APPROVE_ERC20_GAS_LIMIT)
|
.from(APPROVE_ERC20_GAS_LIMIT)
|
||||||
.mul(gasPriceWei);
|
.mul(gasPriceWei);
|
||||||
const denormalizedApproveTransactionCost = utils
|
const denormalizedApproveTransactionCost = denormalizeNumber(
|
||||||
.denormalizeNumber(approveTransactionCost, NATIVE_CURRENCY_PRECISION);
|
approveTransactionCost,
|
||||||
|
NATIVE_CURRENCY_PRECISION
|
||||||
|
);
|
||||||
|
|
||||||
requiredApproves.items = {
|
requiredApproves.items = {
|
||||||
...requiredApproves.items,
|
...requiredApproves.items,
|
||||||
@@ -414,7 +418,7 @@ export default class BalanceGuard {
|
|||||||
if (!remainingBalance) throw new Error(`No ${asset.name} balance`);
|
if (!remainingBalance) throw new Error(`No ${asset.name} balance`);
|
||||||
|
|
||||||
const itemsAmountSum = Object.values({ ...items, ...requiredApproves.items })
|
const itemsAmountSum = Object.values({ ...items, ...requiredApproves.items })
|
||||||
.reduce<BigNumber>((p, c) => (c ? p.plus(c) : p), new BigNumber(0));
|
.reduce<BigNumber>((p, c) => (c !== undefined ? p.plus(c) : p), new BigNumber(0));
|
||||||
|
|
||||||
remainingBalance.wallet = remainingBalance.wallet.minus(itemsAmountSum);
|
remainingBalance.wallet = remainingBalance.wallet.minus(itemsAmountSum);
|
||||||
if (remainingBalance.wallet.lt(0)) {
|
if (remainingBalance.wallet.lt(0)) {
|
||||||
@@ -428,7 +432,7 @@ export default class BalanceGuard {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (fixAutofixable) {
|
if (fixAutofixable !== undefined && fixAutofixable) {
|
||||||
const unfixed = await this.fixAllAutofixableBalanceIssues(balanceIssues);
|
const unfixed = await this.fixAllAutofixableBalanceIssues(balanceIssues);
|
||||||
if (unfixed.length > 0) throw new Error(`Balance issues: ${unfixed.map((issue, i) => `${i + 1}. ${issue.message}`).join('\n')}`);
|
if (unfixed.length > 0) throw new Error(`Balance issues: ${unfixed.map((issue, i) => `${i + 1}. ${issue.message}`).join('\n')}`);
|
||||||
} else if (balanceIssues.length > 0) {
|
} else if (balanceIssues.length > 0) {
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import { merge } from 'merge-anything';
|
import { merge } from 'merge-anything';
|
||||||
import { chains, envs } from '../config';
|
import { chains, envs } from '../config';
|
||||||
import { networkCodes } from '../constants';
|
import { type networkCodes } from '../constants';
|
||||||
import OrionUnit from '../OrionUnit';
|
import OrionUnit from '../OrionUnit';
|
||||||
import OrionAnalytics from '../services/OrionAnalytics';
|
import OrionAnalytics from '../services/OrionAnalytics';
|
||||||
import { ReferralSystem } from '../services/ReferralSystem';
|
import { ReferralSystem } from '../services/ReferralSystem';
|
||||||
import { DeepPartial, SupportedChainId, VerboseOrionUnitConfig } from '../types';
|
import { type DeepPartial, type SupportedChainId, type VerboseOrionUnitConfig } from '../types';
|
||||||
import { isValidChainId } from '../utils';
|
import { isValidChainId } from '../utils';
|
||||||
|
|
||||||
type EnvConfig = {
|
type EnvConfig = {
|
||||||
analyticsAPI: string;
|
analyticsAPI: string
|
||||||
referralAPI: string;
|
referralAPI: string
|
||||||
networks: Partial<
|
networks: Partial<
|
||||||
Record<
|
Record<
|
||||||
SupportedChainId,
|
SupportedChainId,
|
||||||
VerboseOrionUnitConfig
|
VerboseOrionUnitConfig
|
||||||
>
|
>
|
||||||
>;
|
>
|
||||||
}
|
}
|
||||||
|
|
||||||
type KnownEnv = 'testing' | 'staging' | 'production';
|
type KnownEnv = 'testing' | 'staging' | 'production';
|
||||||
@@ -29,14 +29,6 @@ export default class Orion {
|
|||||||
|
|
||||||
public readonly referralSystem: ReferralSystem;
|
public readonly referralSystem: ReferralSystem;
|
||||||
|
|
||||||
constructor();
|
|
||||||
constructor(
|
|
||||||
env: KnownEnv,
|
|
||||||
overrides?: DeepPartial<EnvConfig>
|
|
||||||
);
|
|
||||||
|
|
||||||
constructor(config: EnvConfig);
|
|
||||||
|
|
||||||
// TODO: get tradable assets (aggregated)
|
// TODO: get tradable assets (aggregated)
|
||||||
|
|
||||||
// TODO: get tradable pairs (aggregated)
|
// TODO: get tradable pairs (aggregated)
|
||||||
@@ -50,7 +42,9 @@ export default class Orion {
|
|||||||
let config: EnvConfig;
|
let config: EnvConfig;
|
||||||
if (typeof envOrConfig === 'string') {
|
if (typeof envOrConfig === 'string') {
|
||||||
const envConfig = envs[envOrConfig];
|
const envConfig = envs[envOrConfig];
|
||||||
if (!envConfig) throw new Error(`Invalid environment: ${envOrConfig}. Available environments: ${Object.keys(envs).join(', ')}`);
|
if (!envConfig) {
|
||||||
|
throw new Error(`Invalid environment: ${envOrConfig}. Available environments: ${Object.keys(envs).join(', ')}`);
|
||||||
|
}
|
||||||
this.env = envOrConfig;
|
this.env = envOrConfig;
|
||||||
config = {
|
config = {
|
||||||
analyticsAPI: envConfig.analyticsAPI,
|
analyticsAPI: envConfig.analyticsAPI,
|
||||||
@@ -58,13 +52,15 @@ export default class Orion {
|
|||||||
networks: Object.entries(envConfig.networks).map(([chainId, networkConfig]) => {
|
networks: Object.entries(envConfig.networks).map(([chainId, networkConfig]) => {
|
||||||
if (!isValidChainId(chainId)) throw new Error(`Invalid chainId: ${chainId}`);
|
if (!isValidChainId(chainId)) throw new Error(`Invalid chainId: ${chainId}`);
|
||||||
const chainConfig = chains[chainId];
|
const chainConfig = chains[chainId];
|
||||||
if (!chainConfig) throw new Error(`Chain config not found: ${chainId}. Available chains: ${Object.keys(chains).join(', ')}`);
|
if (!chainConfig) {
|
||||||
|
throw new Error(`Chain config not found: ${chainId}. Available chains: ${Object.keys(chains).join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
env: envOrConfig,
|
env: envOrConfig,
|
||||||
chainId,
|
chainId,
|
||||||
api: networkConfig.api,
|
api: networkConfig.api,
|
||||||
nodeJsonRpc: networkConfig?.rpc ?? chainConfig.rpc,
|
nodeJsonRpc: networkConfig.rpc ?? chainConfig.rpc,
|
||||||
services: {
|
services: {
|
||||||
orionBlockchain: {
|
orionBlockchain: {
|
||||||
http: networkConfig.api + networkConfig.services.blockchain.http,
|
http: networkConfig.api + networkConfig.services.blockchain.http,
|
||||||
@@ -86,6 +82,7 @@ export default class Orion {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (overrides) {
|
if (overrides) {
|
||||||
|
// Recursive merge of config and overrides. Ignore undefined values.
|
||||||
config = merge(config, overrides);
|
config = merge(config, overrides);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -99,7 +96,7 @@ export default class Orion {
|
|||||||
.reduce<Partial<Record<SupportedChainId, OrionUnit>>>((acc, [chainId, networkConfig]) => {
|
.reduce<Partial<Record<SupportedChainId, OrionUnit>>>((acc, [chainId, networkConfig]) => {
|
||||||
if (!isValidChainId(chainId)) throw new Error(`Invalid chainId: ${chainId}`);
|
if (!isValidChainId(chainId)) throw new Error(`Invalid chainId: ${chainId}`);
|
||||||
const chainConfig = chains[chainId];
|
const chainConfig = chains[chainId];
|
||||||
if (!chainConfig) throw new Error(`Invalid chainId: ${chainId}`);
|
if (!chainConfig) throw new Error(`Chain config not found: ${chainId}`);
|
||||||
|
|
||||||
const orionUnit = new OrionUnit({
|
const orionUnit = new OrionUnit({
|
||||||
// env: networkConfig.env,
|
// env: networkConfig.env,
|
||||||
@@ -119,11 +116,7 @@ export default class Orion {
|
|||||||
return Object.entries(this.units).map(([, unit]) => unit);
|
return Object.entries(this.units).map(([, unit]) => unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUnit(chainId: SupportedChainId): OrionUnit;
|
getUnit(networkCodeOrChainId: typeof networkCodes[number] | SupportedChainId): OrionUnit {
|
||||||
|
|
||||||
getUnit(networkCode: typeof networkCodes[number]): OrionUnit;
|
|
||||||
|
|
||||||
getUnit(networkCodeOrChainId: string): OrionUnit {
|
|
||||||
let unit: OrionUnit | undefined;
|
let unit: OrionUnit | undefined;
|
||||||
if (isValidChainId(networkCodeOrChainId)) {
|
if (isValidChainId(networkCodeOrChainId)) {
|
||||||
unit = this.units[networkCodeOrChainId];
|
unit = this.units[networkCodeOrChainId];
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
/* eslint-disable max-len */
|
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { Exchange__factory } from '@orionprotocol/contracts';
|
import { Exchange__factory } from '@orionprotocol/contracts';
|
||||||
import getBalances from '../../utils/getBalances';
|
import getBalances from '../../utils/getBalances';
|
||||||
import BalanceGuard from '../../BalanceGuard';
|
import BalanceGuard from '../../BalanceGuard';
|
||||||
import OrionUnit from '..';
|
import type OrionUnit from '..';
|
||||||
import { utils } from '../..';
|
|
||||||
import {
|
import {
|
||||||
DEPOSIT_ERC20_GAS_LIMIT, DEPOSIT_ETH_GAS_LIMIT, INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION,
|
DEPOSIT_ERC20_GAS_LIMIT, DEPOSIT_ETH_GAS_LIMIT, INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION,
|
||||||
} from '../../constants';
|
} from '../../constants';
|
||||||
import { normalizeNumber } from '../../utils';
|
import { denormalizeNumber, normalizeNumber } from '../../utils';
|
||||||
import getNativeCryptocurrency from '../../utils/getNativeCryptocurrency';
|
import getNativeCryptocurrency from '../../utils/getNativeCryptocurrency';
|
||||||
import simpleFetch from '../../simpleFetch';
|
import simpleFetch from '../../simpleFetch';
|
||||||
|
|
||||||
export type DepositParams = {
|
export type DepositParams = {
|
||||||
asset: string,
|
asset: string
|
||||||
amount: BigNumber.Value,
|
amount: BigNumber.Value
|
||||||
signer: ethers.Signer,
|
signer: ethers.Signer
|
||||||
orionUnit: OrionUnit,
|
orionUnit: OrionUnit
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function deposit({
|
export default async function deposit({
|
||||||
@@ -29,8 +27,8 @@ export default async function deposit({
|
|||||||
if (asset === '') throw new Error('Asset can not be empty');
|
if (asset === '') throw new Error('Asset can not be empty');
|
||||||
|
|
||||||
const amountBN = new BigNumber(amount);
|
const amountBN = new BigNumber(amount);
|
||||||
if (amountBN.isNaN()) throw new Error(`Amount '${amount.toString()}' is not a number`);
|
if (amountBN.isNaN()) throw new Error(`Amount '${amountBN.toString()}' is not a number`);
|
||||||
if (amountBN.lte(0)) throw new Error(`Amount '${amount.toString()}' should be greater than 0`);
|
if (amountBN.lte(0)) throw new Error(`Amount '${amountBN.toString()}' should be greater than 0`);
|
||||||
|
|
||||||
const walletAddress = await signer.getAddress();
|
const walletAddress = await signer.getAddress();
|
||||||
|
|
||||||
@@ -48,7 +46,7 @@ export default async function deposit({
|
|||||||
const gasPriceWei = await simpleFetch(orionBlockchain.getGasPriceWei)();
|
const gasPriceWei = await simpleFetch(orionBlockchain.getGasPriceWei)();
|
||||||
|
|
||||||
const assetAddress = assetToAddress[asset];
|
const assetAddress = assetToAddress[asset];
|
||||||
if (!assetAddress) throw new Error(`Asset '${asset}' not found`);
|
if (assetAddress === undefined) throw new Error(`Asset '${asset}' not found`);
|
||||||
|
|
||||||
const balances = await getBalances(
|
const balances = await getBalances(
|
||||||
{
|
{
|
||||||
@@ -77,7 +75,7 @@ export default async function deposit({
|
|||||||
name: asset,
|
name: asset,
|
||||||
address: assetAddress,
|
address: assetAddress,
|
||||||
},
|
},
|
||||||
amount: amount.toString(),
|
amount: amountBN.toString(),
|
||||||
spenderAddress: exchangeContractAddress,
|
spenderAddress: exchangeContractAddress,
|
||||||
sources: ['wallet'],
|
sources: ['wallet'],
|
||||||
});
|
});
|
||||||
@@ -96,7 +94,7 @@ export default async function deposit({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const transactionCost = ethers.BigNumber.from(unsignedTx.gasLimit).mul(gasPriceWei);
|
const transactionCost = ethers.BigNumber.from(unsignedTx.gasLimit).mul(gasPriceWei);
|
||||||
const denormalizedTransactionCost = utils.denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
|
const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
|
||||||
|
|
||||||
balanceGuard.registerRequirement({
|
balanceGuard.registerRequirement({
|
||||||
reason: 'Network fee',
|
reason: 'Network fee',
|
||||||
@@ -121,7 +119,7 @@ export default async function deposit({
|
|||||||
const txResponse = await provider.sendTransaction(signedTx);
|
const txResponse = await provider.sendTransaction(signedTx);
|
||||||
console.log(`Deposit tx sent: ${txResponse.hash}. Waiting for confirmation...`);
|
console.log(`Deposit tx sent: ${txResponse.hash}. Waiting for confirmation...`);
|
||||||
const txReceipt = await txResponse.wait();
|
const txReceipt = await txResponse.wait();
|
||||||
if (txReceipt.status) {
|
if (txReceipt.status !== undefined) {
|
||||||
console.log('Deposit tx confirmed');
|
console.log('Deposit tx confirmed');
|
||||||
} else {
|
} else {
|
||||||
console.log('Deposit tx failed');
|
console.log('Deposit tx failed');
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { utils } from '../..';
|
|
||||||
import { NATIVE_CURRENCY_PRECISION, SWAP_THROUGH_ORION_POOL_GAS_LIMIT } from '../../constants';
|
import { NATIVE_CURRENCY_PRECISION, SWAP_THROUGH_ORION_POOL_GAS_LIMIT } from '../../constants';
|
||||||
import { OrionAggregator } from '../../services/OrionAggregator';
|
import { type OrionAggregator } from '../../services/OrionAggregator';
|
||||||
import { OrionBlockchain } from '../../services/OrionBlockchain';
|
import { type OrionBlockchain } from '../../services/OrionBlockchain';
|
||||||
|
|
||||||
import simpleFetch from '../../simpleFetch';
|
import simpleFetch from '../../simpleFetch';
|
||||||
import getNativeCryptocurrency from '../../utils/getNativeCryptocurrency';
|
import { calculateFeeInFeeAsset, denormalizeNumber, getNativeCryptocurrency } from '../../utils';
|
||||||
|
|
||||||
export type GetSwapInfoParams = {
|
export type GetSwapInfoParams = {
|
||||||
type: 'exactSpend' | 'exactReceive',
|
type: 'exactSpend' | 'exactReceive'
|
||||||
assetIn: string,
|
assetIn: string
|
||||||
assetOut: string,
|
assetOut: string
|
||||||
amount: BigNumber.Value,
|
amount: BigNumber.Value
|
||||||
feeAsset: string,
|
feeAsset: string
|
||||||
orionBlockchain: OrionBlockchain,
|
orionBlockchain: OrionBlockchain
|
||||||
orionAggregator: OrionAggregator
|
orionAggregator: OrionAggregator
|
||||||
options?: {
|
options?: {
|
||||||
instantSettlement?: boolean,
|
instantSettlement?: boolean
|
||||||
poolOnly?: boolean,
|
poolOnly?: boolean
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,8 +37,8 @@ export default async function getSwapInfo({
|
|||||||
if (feeAsset === '') throw new Error('Fee asset can not be empty');
|
if (feeAsset === '') throw new Error('Fee asset can not be empty');
|
||||||
|
|
||||||
const amountBN = new BigNumber(amount);
|
const amountBN = new BigNumber(amount);
|
||||||
if (amountBN.isNaN()) throw new Error(`Amount '${amount.toString()}' is not a number`);
|
if (amountBN.isNaN()) throw new Error(`Amount '${amountBN.toString()}' is not a number`);
|
||||||
if (amountBN.lte(0)) throw new Error(`Amount '${amount.toString()}' should be greater than 0`);
|
if (amountBN.lte(0)) throw new Error(`Amount '${amountBN.toString()}' should be greater than 0`);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
assetToAddress,
|
assetToAddress,
|
||||||
@@ -53,17 +52,21 @@ export default async function getSwapInfo({
|
|||||||
const gasPriceGwei = ethers.utils.formatUnits(gasPriceWei, 'gwei').toString();
|
const gasPriceGwei = ethers.utils.formatUnits(gasPriceWei, 'gwei').toString();
|
||||||
|
|
||||||
const assetInAddress = assetToAddress[assetIn];
|
const assetInAddress = assetToAddress[assetIn];
|
||||||
if (!assetInAddress) throw new Error(`Asset '${assetIn}' not found`);
|
if (assetInAddress === undefined) throw new Error(`Asset '${assetIn}' not found`);
|
||||||
const feeAssetAddress = assetToAddress[feeAsset];
|
const feeAssetAddress = assetToAddress[feeAsset];
|
||||||
if (!feeAssetAddress) throw new Error(`Fee asset '${feeAsset}' not found. Available assets: ${Object.keys(feeAssets).join(', ')}`);
|
if (feeAssetAddress === undefined) {
|
||||||
|
throw new Error(`Fee asset '${feeAsset}' not found. Available assets: ${Object.keys(feeAssets).join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
const swapInfo = await simpleFetch(orionAggregator.getSwapInfo)(
|
const swapInfo = await simpleFetch(orionAggregator.getSwapInfo)(
|
||||||
type,
|
type,
|
||||||
assetIn,
|
assetIn,
|
||||||
assetOut,
|
assetOut,
|
||||||
amount.toString(),
|
amountBN.toString(),
|
||||||
options?.instantSettlement,
|
options?.instantSettlement,
|
||||||
options?.poolOnly ? 'pools' : undefined,
|
options?.poolOnly !== undefined && options.poolOnly
|
||||||
|
? 'pools'
|
||||||
|
: undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { exchanges: swapExchanges } = swapInfo;
|
const { exchanges: swapExchanges } = swapInfo;
|
||||||
@@ -82,13 +85,12 @@ export default async function getSwapInfo({
|
|||||||
// if (swapInfo.orderInfo === null) throw new Error(swapInfo.executionInfo);
|
// if (swapInfo.orderInfo === null) throw new Error(swapInfo.executionInfo);
|
||||||
|
|
||||||
let route: 'pool' | 'aggregator';
|
let route: 'pool' | 'aggregator';
|
||||||
if (options?.poolOnly) {
|
if (options?.poolOnly !== undefined && options.poolOnly) {
|
||||||
route = 'pool';
|
route = 'pool';
|
||||||
} else if (
|
} else if (
|
||||||
swapExchanges !== undefined &&
|
|
||||||
poolExchangesList.length > 0 &&
|
poolExchangesList.length > 0 &&
|
||||||
swapExchanges.length === 1 &&
|
swapExchanges.length === 1 &&
|
||||||
firstSwapExchange &&
|
firstSwapExchange !== undefined &&
|
||||||
poolExchangesList.some((poolExchange) => poolExchange === firstSwapExchange)
|
poolExchangesList.some((poolExchange) => poolExchange === firstSwapExchange)
|
||||||
) {
|
) {
|
||||||
route = 'pool';
|
route = 'pool';
|
||||||
@@ -98,7 +100,7 @@ export default async function getSwapInfo({
|
|||||||
|
|
||||||
if (route === 'pool') {
|
if (route === 'pool') {
|
||||||
const transactionCost = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT).mul(gasPriceWei);
|
const transactionCost = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT).mul(gasPriceWei);
|
||||||
const denormalizedTransactionCost = utils.denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
|
const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
route,
|
route,
|
||||||
@@ -112,26 +114,26 @@ export default async function getSwapInfo({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swapInfo.orderInfo) {
|
if (swapInfo.orderInfo !== null) {
|
||||||
const [baseAssetName] = swapInfo.orderInfo.assetPair.split('-');
|
const [baseAssetName] = swapInfo.orderInfo.assetPair.split('-');
|
||||||
if (baseAssetName === undefined) throw new Error('Base asset name is undefined');
|
if (baseAssetName === undefined) throw new Error('Base asset name is undefined');
|
||||||
const baseAssetAddress = assetToAddress[baseAssetName];
|
const baseAssetAddress = assetToAddress[baseAssetName];
|
||||||
if (!baseAssetAddress) throw new Error(`No asset address for ${baseAssetName}`);
|
if (baseAssetAddress === undefined) throw new Error(`No asset address for ${baseAssetName}`);
|
||||||
|
|
||||||
// Fee calculation
|
// Fee calculation
|
||||||
const baseAssetPriceInOrn = pricesInOrn?.[baseAssetAddress];
|
const baseAssetPriceInOrn = pricesInOrn[baseAssetAddress];
|
||||||
if (!baseAssetPriceInOrn) throw new Error(`Base asset price ${baseAssetName} in ORN not found`);
|
if (baseAssetPriceInOrn === undefined) throw new Error(`Base asset price ${baseAssetName} in ORN not found`);
|
||||||
const baseCurrencyPriceInOrn = pricesInOrn[ethers.constants.AddressZero];
|
const baseCurrencyPriceInOrn = pricesInOrn[ethers.constants.AddressZero];
|
||||||
if (!baseCurrencyPriceInOrn) throw new Error('Base currency price in ORN not found');
|
if (baseCurrencyPriceInOrn === undefined) throw new Error('Base currency price in ORN not found');
|
||||||
const feeAssetPriceInOrn = pricesInOrn[feeAssetAddress];
|
const feeAssetPriceInOrn = pricesInOrn[feeAssetAddress];
|
||||||
if (!feeAssetPriceInOrn) throw new Error(`Fee asset price ${feeAsset} in ORN not found`);
|
if (feeAssetPriceInOrn === undefined) throw new Error(`Fee asset price ${feeAsset} in ORN not found`);
|
||||||
const feePercent = feeAssets?.[feeAsset];
|
const feePercent = feeAssets[feeAsset];
|
||||||
if (!feePercent) throw new Error(`Fee asset ${feeAsset} not available`);
|
if (feePercent === undefined) throw new Error(`Fee asset ${feeAsset} not available`);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
orionFeeInFeeAsset,
|
orionFeeInFeeAsset,
|
||||||
networkFeeInFeeAsset,
|
networkFeeInFeeAsset,
|
||||||
} = utils.calculateFeeInFeeAsset(
|
} = calculateFeeInFeeAsset(
|
||||||
swapInfo.orderInfo.amount,
|
swapInfo.orderInfo.amount,
|
||||||
feeAssetPriceInOrn,
|
feeAssetPriceInOrn,
|
||||||
baseAssetPriceInOrn,
|
baseAssetPriceInOrn,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import OrionUnit from '..';
|
import type OrionUnit from '..';
|
||||||
import deposit, { DepositParams } from './deposit';
|
import deposit, { type DepositParams } from './deposit';
|
||||||
import getSwapInfo, { GetSwapInfoParams } from './getSwapInfo';
|
import getSwapInfo, { type GetSwapInfoParams } from './getSwapInfo';
|
||||||
import swapMarket, { SwapMarketParams } from './swapMarket';
|
import swapMarket, { type SwapMarketParams } from './swapMarket';
|
||||||
import withdraw, { WithdrawParams } from './withdraw';
|
import withdraw, { type WithdrawParams } from './withdraw';
|
||||||
|
|
||||||
type PureSwapMarketParams = Omit<SwapMarketParams, 'orionUnit'>
|
type PureSwapMarketParams = Omit<SwapMarketParams, 'orionUnit'>
|
||||||
type PureDepositParams = Omit<DepositParams, 'orionUnit'>
|
type PureDepositParams = Omit<DepositParams, 'orionUnit'>
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
/* eslint-disable max-len */
|
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { Exchange__factory } from '@orionprotocol/contracts';
|
import { Exchange__factory } from '@orionprotocol/contracts';
|
||||||
import getBalances from '../../utils/getBalances';
|
import getBalances from '../../utils/getBalances';
|
||||||
import BalanceGuard from '../../BalanceGuard';
|
import BalanceGuard from '../../BalanceGuard';
|
||||||
import getAvailableSources from '../../utils/getAvailableFundsSources';
|
import getAvailableSources from '../../utils/getAvailableFundsSources';
|
||||||
import OrionUnit from '..';
|
import type OrionUnit from '..';
|
||||||
import { crypt, utils } from '../..';
|
|
||||||
import { INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION, SWAP_THROUGH_ORION_POOL_GAS_LIMIT } from '../../constants';
|
import { INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION, SWAP_THROUGH_ORION_POOL_GAS_LIMIT } from '../../constants';
|
||||||
import getNativeCryptocurrency from '../../utils/getNativeCryptocurrency';
|
import getNativeCryptocurrency from '../../utils/getNativeCryptocurrency';
|
||||||
import simpleFetch from '../../simpleFetch';
|
import simpleFetch from '../../simpleFetch';
|
||||||
|
import { calculateFeeInFeeAsset, denormalizeNumber, normalizeNumber } from '../../utils';
|
||||||
|
import { signOrder } from '../../crypt';
|
||||||
|
|
||||||
export type SwapMarketParams = {
|
export type SwapMarketParams = {
|
||||||
type: 'exactSpend' | 'exactReceive',
|
type: 'exactSpend' | 'exactReceive'
|
||||||
assetIn: string,
|
assetIn: string
|
||||||
assetOut: string,
|
assetOut: string
|
||||||
amount: BigNumber.Value,
|
amount: BigNumber.Value
|
||||||
feeAsset: string,
|
feeAsset: string
|
||||||
slippagePercent: BigNumber.Value,
|
slippagePercent: BigNumber.Value
|
||||||
signer: ethers.Signer,
|
signer: ethers.Signer
|
||||||
orionUnit: OrionUnit,
|
orionUnit: OrionUnit
|
||||||
options?: {
|
options?: {
|
||||||
poolOnly?: boolean,
|
poolOnly?: boolean
|
||||||
instantSettlement?: boolean,
|
instantSettlement?: boolean
|
||||||
logger?: (message: string) => void,
|
logger?: (message: string) => void
|
||||||
autoApprove?: boolean,
|
autoApprove?: boolean
|
||||||
developer?: {
|
developer?: {
|
||||||
route?: 'aggregator' | 'pool',
|
route?: 'aggregator' | 'pool'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type AggregatorOrder = {
|
type AggregatorOrder = {
|
||||||
through: 'aggregator'
|
through: 'aggregator'
|
||||||
id: string,
|
id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type PoolSwap = {
|
type PoolSwap = {
|
||||||
through: 'orion_pool'
|
through: 'orion_pool'
|
||||||
txHash: string,
|
txHash: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Swap = AggregatorOrder | PoolSwap;
|
export type Swap = AggregatorOrder | PoolSwap;
|
||||||
|
|
||||||
export default async function swapMarket({
|
export default async function swapMarket({
|
||||||
type,
|
type,
|
||||||
@@ -54,7 +54,7 @@ export default async function swapMarket({
|
|||||||
orionUnit,
|
orionUnit,
|
||||||
options,
|
options,
|
||||||
}: SwapMarketParams): Promise<Swap> {
|
}: SwapMarketParams): Promise<Swap> {
|
||||||
if (options?.developer) options?.logger?.('YOU SPECIFIED A DEVELOPER OPTIONS. BE CAREFUL!');
|
if (options?.developer) options.logger?.('YOU SPECIFIED A DEVELOPER OPTIONS. BE CAREFUL!');
|
||||||
if (amount === '') throw new Error('Amount can not be empty');
|
if (amount === '') throw new Error('Amount can not be empty');
|
||||||
if (assetIn === '') throw new Error('AssetIn can not be empty');
|
if (assetIn === '') throw new Error('AssetIn can not be empty');
|
||||||
if (assetOut === '') throw new Error('AssetOut can not be empty');
|
if (assetOut === '') throw new Error('AssetOut can not be empty');
|
||||||
@@ -62,11 +62,11 @@ export default async function swapMarket({
|
|||||||
if (slippagePercent === '') throw new Error('Slippage percent can not be empty');
|
if (slippagePercent === '') throw new Error('Slippage percent can not be empty');
|
||||||
|
|
||||||
const amountBN = new BigNumber(amount);
|
const amountBN = new BigNumber(amount);
|
||||||
if (amountBN.isNaN()) throw new Error(`Amount '${amount.toString()}' is not a number`);
|
if (amountBN.isNaN()) throw new Error(`Amount '${amountBN.toString()}' is not a number`);
|
||||||
if (amountBN.lte(0)) throw new Error(`Amount '${amount.toString()}' should be greater than 0`);
|
if (amountBN.lte(0)) throw new Error(`Amount '${amountBN.toString()}' should be greater than 0`);
|
||||||
|
|
||||||
const slippagePercentBN = new BigNumber(slippagePercent);
|
const slippagePercentBN = new BigNumber(slippagePercent);
|
||||||
if (slippagePercentBN.isNaN()) throw new Error(`Slippage percent '${slippagePercent.toString()}' is not a number`);
|
if (slippagePercentBN.isNaN()) throw new Error(`Slippage percent '${slippagePercentBN.toString()}' is not a number`);
|
||||||
if (slippagePercentBN.lte(0)) throw new Error('Slippage percent should be greater than 0');
|
if (slippagePercentBN.lte(0)) throw new Error('Slippage percent should be greater than 0');
|
||||||
if (slippagePercentBN.gte(50)) throw new Error('Slippage percent should be less than 50');
|
if (slippagePercentBN.gte(50)) throw new Error('Slippage percent should be less than 50');
|
||||||
|
|
||||||
@@ -93,9 +93,11 @@ export default async function swapMarket({
|
|||||||
const gasPriceGwei = ethers.utils.formatUnits(gasPriceWei, 'gwei').toString();
|
const gasPriceGwei = ethers.utils.formatUnits(gasPriceWei, 'gwei').toString();
|
||||||
|
|
||||||
const assetInAddress = assetToAddress[assetIn];
|
const assetInAddress = assetToAddress[assetIn];
|
||||||
if (!assetInAddress) throw new Error(`Asset '${assetIn}' not found`);
|
if (assetInAddress === undefined) throw new Error(`Asset '${assetIn}' not found`);
|
||||||
const feeAssetAddress = assetToAddress[feeAsset];
|
const feeAssetAddress = assetToAddress[feeAsset];
|
||||||
if (!feeAssetAddress) throw new Error(`Fee asset '${feeAsset}' not found. Available assets: ${Object.keys(feeAssets).join(', ')}`);
|
if (feeAssetAddress === undefined) {
|
||||||
|
throw new Error(`Fee asset '${feeAsset}' not found. Available assets: ${Object.keys(feeAssets).join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
const balances = await getBalances(
|
const balances = await getBalances(
|
||||||
{
|
{
|
||||||
@@ -124,16 +126,18 @@ export default async function swapMarket({
|
|||||||
type,
|
type,
|
||||||
assetIn,
|
assetIn,
|
||||||
assetOut,
|
assetOut,
|
||||||
amount.toString(),
|
amountBN.toString(),
|
||||||
options?.instantSettlement,
|
options?.instantSettlement,
|
||||||
options?.poolOnly ? 'pools' : undefined,
|
options?.poolOnly !== undefined && options.poolOnly
|
||||||
|
? 'pools'
|
||||||
|
: undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { exchanges: swapExchanges } = swapInfo;
|
const { exchanges: swapExchanges } = swapInfo;
|
||||||
|
|
||||||
const [firstSwapExchange] = swapExchanges;
|
const [firstSwapExchange] = swapExchanges;
|
||||||
|
|
||||||
if (swapExchanges) options?.logger?.(`Swap exchanges: ${swapExchanges.join(', ')}`);
|
if (swapExchanges.length > 0) options?.logger?.(`Swap exchanges: ${swapExchanges.join(', ')}`);
|
||||||
|
|
||||||
if (swapInfo.type === 'exactReceive' && amountBN.lt(swapInfo.minAmountOut)) {
|
if (swapInfo.type === 'exactReceive' && amountBN.lt(swapInfo.minAmountOut)) {
|
||||||
throw new Error(`Amount is too low. Min amountOut is ${swapInfo.minAmountOut} ${assetOut}`);
|
throw new Error(`Amount is too low. Min amountOut is ${swapInfo.minAmountOut} ${assetOut}`);
|
||||||
@@ -150,14 +154,16 @@ export default async function swapMarket({
|
|||||||
if (quoteAssetName === undefined) throw new Error('Quote asset name is undefined');
|
if (quoteAssetName === undefined) throw new Error('Quote asset name is undefined');
|
||||||
|
|
||||||
const pairConfig = await simpleFetch(orionAggregator.getPairConfig)(`${baseAssetName}-${quoteAssetName}`);
|
const pairConfig = await simpleFetch(orionAggregator.getPairConfig)(`${baseAssetName}-${quoteAssetName}`);
|
||||||
if (!pairConfig) throw new Error(`Pair config ${baseAssetName}-${quoteAssetName} not found`);
|
|
||||||
|
|
||||||
const qtyPrecisionBN = new BigNumber(pairConfig.qtyPrecision);
|
const qtyPrecisionBN = new BigNumber(pairConfig.qtyPrecision);
|
||||||
const qtyDecimalPlaces = amountBN.dp();
|
const qtyDecimalPlaces = amountBN.dp();
|
||||||
|
|
||||||
if (qtyDecimalPlaces === null) throw new Error('Qty decimal places is null. Likely amount is -Infinity, +Infinity or NaN');
|
if (qtyDecimalPlaces === null) throw new Error('Qty decimal places is null. Likely amount is -Infinity, +Infinity or NaN');
|
||||||
|
|
||||||
if (qtyPrecisionBN.lt(qtyDecimalPlaces)) throw new Error(`Actual amount decimal places (${qtyDecimalPlaces}) is greater than max allowed decimal places (${qtyPrecisionBN.toString()}) on pair ${baseAssetName}-${quoteAssetName}`);
|
if (qtyPrecisionBN.lt(qtyDecimalPlaces)) {
|
||||||
|
throw new Error(
|
||||||
|
`Actual amount decimal places (${qtyDecimalPlaces}) is greater than max allowed decimal places (${qtyPrecisionBN.toString()}) on pair ${baseAssetName}-${quoteAssetName}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let route: 'aggregator' | 'pool';
|
let route: 'aggregator' | 'pool';
|
||||||
|
|
||||||
@@ -165,15 +171,14 @@ export default async function swapMarket({
|
|||||||
|
|
||||||
if (options?.developer?.route !== undefined) {
|
if (options?.developer?.route !== undefined) {
|
||||||
route = options.developer.route;
|
route = options.developer.route;
|
||||||
options?.logger?.(`Swap is through ${route} (because route forced to ${route})`);
|
options.logger?.(`Swap is through ${route} (because route forced to ${route})`);
|
||||||
} else if (options?.poolOnly) {
|
} else if (options?.poolOnly !== undefined && options.poolOnly) {
|
||||||
options?.logger?.('Swap is through pool (because "poolOnly" option is true)');
|
options.logger?.('Swap is through pool (because "poolOnly" option is true)');
|
||||||
route = 'pool';
|
route = 'pool';
|
||||||
} else if (
|
} else if (
|
||||||
swapExchanges !== undefined &&
|
|
||||||
poolExchangesList.length > 0 &&
|
poolExchangesList.length > 0 &&
|
||||||
swapExchanges.length === 1 &&
|
swapExchanges.length === 1 &&
|
||||||
firstSwapExchange &&
|
firstSwapExchange !== undefined &&
|
||||||
poolExchangesList.some((poolExchange) => poolExchange === firstSwapExchange)
|
poolExchangesList.some((poolExchange) => poolExchange === firstSwapExchange)
|
||||||
) {
|
) {
|
||||||
options?.logger?.(`Swap is through pool [via ${firstSwapExchange}] (detected by "exchanges" field)`);
|
options?.logger?.(`Swap is through pool [via ${firstSwapExchange}] (detected by "exchanges" field)`);
|
||||||
@@ -184,14 +189,14 @@ export default async function swapMarket({
|
|||||||
|
|
||||||
if (route === 'pool') {
|
if (route === 'pool') {
|
||||||
let factoryAddress: string | undefined;
|
let factoryAddress: string | undefined;
|
||||||
if (factories && firstSwapExchange) {
|
if (factories && firstSwapExchange !== undefined) {
|
||||||
factoryAddress = factories?.[firstSwapExchange];
|
factoryAddress = factories[firstSwapExchange];
|
||||||
if (factoryAddress) options?.logger?.(`Factory address is ${factoryAddress}. Exchange is ${firstSwapExchange}`);
|
if (factoryAddress !== undefined) options?.logger?.(`Factory address is ${factoryAddress}. Exchange is ${firstSwapExchange}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const pathAddresses = swapInfo.path.map((name) => {
|
const pathAddresses = swapInfo.path.map((name) => {
|
||||||
const assetAddress = assetToAddress?.[name];
|
const assetAddress = assetToAddress[name];
|
||||||
if (!assetAddress) throw new Error(`No asset address for ${name}`);
|
if (assetAddress === undefined) throw new Error(`No asset address for ${name}`);
|
||||||
return assetAddress;
|
return assetAddress;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -216,12 +221,12 @@ export default async function swapMarket({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const amountReceive = swapInfo.type === 'exactReceive' ? swapInfo.amountOut : amountOutWithSlippage;
|
const amountReceive = swapInfo.type === 'exactReceive' ? swapInfo.amountOut : amountOutWithSlippage;
|
||||||
const amountSpendBlockchainParam = utils.normalizeNumber(
|
const amountSpendBlockchainParam = normalizeNumber(
|
||||||
amountSpend,
|
amountSpend,
|
||||||
INTERNAL_ORION_PRECISION,
|
INTERNAL_ORION_PRECISION,
|
||||||
BigNumber.ROUND_CEIL,
|
BigNumber.ROUND_CEIL,
|
||||||
);
|
);
|
||||||
const amountReceiveBlockchainParam = utils.normalizeNumber(
|
const amountReceiveBlockchainParam = normalizeNumber(
|
||||||
amountReceive,
|
amountReceive,
|
||||||
INTERNAL_ORION_PRECISION,
|
INTERNAL_ORION_PRECISION,
|
||||||
BigNumber.ROUND_FLOOR,
|
BigNumber.ROUND_FLOOR,
|
||||||
@@ -229,7 +234,9 @@ export default async function swapMarket({
|
|||||||
const unsignedSwapThroughOrionPoolTx = await exchangeContract.populateTransaction.swapThroughOrionPool(
|
const unsignedSwapThroughOrionPoolTx = await exchangeContract.populateTransaction.swapThroughOrionPool(
|
||||||
amountSpendBlockchainParam,
|
amountSpendBlockchainParam,
|
||||||
amountReceiveBlockchainParam,
|
amountReceiveBlockchainParam,
|
||||||
factoryAddress ? [factoryAddress, ...pathAddresses] : pathAddresses,
|
factoryAddress !== undefined
|
||||||
|
? [factoryAddress, ...pathAddresses]
|
||||||
|
: pathAddresses,
|
||||||
type === 'exactSpend',
|
type === 'exactSpend',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -241,11 +248,11 @@ export default async function swapMarket({
|
|||||||
|
|
||||||
let value = new BigNumber(0);
|
let value = new BigNumber(0);
|
||||||
const denormalizedAssetInExchangeBalance = balances[assetIn]?.exchange;
|
const denormalizedAssetInExchangeBalance = balances[assetIn]?.exchange;
|
||||||
if (!denormalizedAssetInExchangeBalance) throw new Error(`Asset '${assetIn}' exchange balance is not found`);
|
if (denormalizedAssetInExchangeBalance === undefined) throw new Error(`Asset '${assetIn}' exchange balance is not found`);
|
||||||
if (assetIn === nativeCryptocurrency && amountSpendBN.gt(denormalizedAssetInExchangeBalance)) {
|
if (assetIn === nativeCryptocurrency && amountSpendBN.gt(denormalizedAssetInExchangeBalance)) {
|
||||||
value = amountSpendBN.minus(denormalizedAssetInExchangeBalance);
|
value = amountSpendBN.minus(denormalizedAssetInExchangeBalance);
|
||||||
}
|
}
|
||||||
unsignedSwapThroughOrionPoolTx.value = utils.normalizeNumber(
|
unsignedSwapThroughOrionPoolTx.value = normalizeNumber(
|
||||||
value.dp(INTERNAL_ORION_PRECISION, BigNumber.ROUND_CEIL),
|
value.dp(INTERNAL_ORION_PRECISION, BigNumber.ROUND_CEIL),
|
||||||
NATIVE_CURRENCY_PRECISION,
|
NATIVE_CURRENCY_PRECISION,
|
||||||
BigNumber.ROUND_CEIL,
|
BigNumber.ROUND_CEIL,
|
||||||
@@ -253,7 +260,7 @@ export default async function swapMarket({
|
|||||||
unsignedSwapThroughOrionPoolTx.gasLimit = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT);
|
unsignedSwapThroughOrionPoolTx.gasLimit = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT);
|
||||||
|
|
||||||
const transactionCost = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT).mul(gasPriceWei);
|
const transactionCost = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT).mul(gasPriceWei);
|
||||||
const denormalizedTransactionCost = utils.denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
|
const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
|
||||||
|
|
||||||
balanceGuard.registerRequirement({
|
balanceGuard.registerRequirement({
|
||||||
reason: 'Network fee',
|
reason: 'Network fee',
|
||||||
@@ -305,9 +312,9 @@ export default async function swapMarket({
|
|||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
const baseAssetAddress = assetToAddress[baseAssetName];
|
const baseAssetAddress = assetToAddress[baseAssetName];
|
||||||
if (!baseAssetAddress) throw new Error(`No asset address for ${baseAssetName}`);
|
if (baseAssetAddress === undefined) throw new Error(`No asset address for ${baseAssetName}`);
|
||||||
const quoteAssetAddress = assetToAddress[quoteAssetName];
|
const quoteAssetAddress = assetToAddress[quoteAssetName];
|
||||||
if (!quoteAssetAddress) throw new Error(`No asset address for ${quoteAssetName}`);
|
if (quoteAssetAddress === undefined) throw new Error(`No asset address for ${quoteAssetName}`);
|
||||||
|
|
||||||
const safePriceWithAppliedPrecision = new BigNumber(safePriceWithDeviation)
|
const safePriceWithAppliedPrecision = new BigNumber(safePriceWithDeviation)
|
||||||
.decimalPlaces(
|
.decimalPlaces(
|
||||||
@@ -331,16 +338,16 @@ export default async function swapMarket({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Fee calculation
|
// Fee calculation
|
||||||
const baseAssetPriceInOrn = pricesInOrn?.[baseAssetAddress];
|
const baseAssetPriceInOrn = pricesInOrn[baseAssetAddress];
|
||||||
if (!baseAssetPriceInOrn) throw new Error(`Base asset price ${baseAssetName} in ORN not found`);
|
if (baseAssetPriceInOrn === undefined) throw new Error(`Base asset price ${baseAssetName} in ORN not found`);
|
||||||
const baseCurrencyPriceInOrn = pricesInOrn[ethers.constants.AddressZero];
|
const baseCurrencyPriceInOrn = pricesInOrn[ethers.constants.AddressZero];
|
||||||
if (!baseCurrencyPriceInOrn) throw new Error('Base currency price in ORN not found');
|
if (baseCurrencyPriceInOrn === undefined) throw new Error('Base currency price in ORN not found');
|
||||||
const feeAssetPriceInOrn = pricesInOrn[feeAssetAddress];
|
const feeAssetPriceInOrn = pricesInOrn[feeAssetAddress];
|
||||||
if (!feeAssetPriceInOrn) throw new Error(`Fee asset price ${feeAsset} in ORN not found`);
|
if (feeAssetPriceInOrn === undefined) throw new Error(`Fee asset price ${feeAsset} in ORN not found`);
|
||||||
const feePercent = feeAssets?.[feeAsset];
|
const feePercent = feeAssets[feeAsset];
|
||||||
if (!feePercent) throw new Error(`Fee asset ${feeAsset} not available`);
|
if (feePercent === undefined) throw new Error(`Fee asset ${feeAsset} not available`);
|
||||||
|
|
||||||
const { orionFeeInFeeAsset, networkFeeInFeeAsset, totalFeeInFeeAsset } = utils.calculateFeeInFeeAsset(
|
const { orionFeeInFeeAsset, networkFeeInFeeAsset, totalFeeInFeeAsset } = calculateFeeInFeeAsset(
|
||||||
swapInfo.orderInfo.amount,
|
swapInfo.orderInfo.amount,
|
||||||
feeAssetPriceInOrn,
|
feeAssetPriceInOrn,
|
||||||
baseAssetPriceInOrn,
|
baseAssetPriceInOrn,
|
||||||
@@ -380,7 +387,7 @@ export default async function swapMarket({
|
|||||||
|
|
||||||
await balanceGuard.check(options?.autoApprove);
|
await balanceGuard.check(options?.autoApprove);
|
||||||
|
|
||||||
const signedOrder = await crypt.signOrder(
|
const signedOrder = await signOrder(
|
||||||
baseAssetAddress,
|
baseAssetAddress,
|
||||||
quoteAssetAddress,
|
quoteAssetAddress,
|
||||||
swapInfo.orderInfo.side,
|
swapInfo.orderInfo.side,
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
/* eslint-disable max-len */
|
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { Exchange__factory } from '@orionprotocol/contracts';
|
import { Exchange__factory } from '@orionprotocol/contracts';
|
||||||
import getBalances from '../../utils/getBalances';
|
import getBalances from '../../utils/getBalances';
|
||||||
import BalanceGuard from '../../BalanceGuard';
|
import BalanceGuard from '../../BalanceGuard';
|
||||||
import OrionUnit from '..';
|
import type OrionUnit from '..';
|
||||||
import { utils } from '../..';
|
|
||||||
import {
|
import {
|
||||||
INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION, WITHDRAW_GAS_LIMIT,
|
INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION, WITHDRAW_GAS_LIMIT,
|
||||||
} from '../../constants';
|
} from '../../constants';
|
||||||
import { normalizeNumber } from '../../utils';
|
import { denormalizeNumber, normalizeNumber } from '../../utils';
|
||||||
import getNativeCryptocurrency from '../../utils/getNativeCryptocurrency';
|
import getNativeCryptocurrency from '../../utils/getNativeCryptocurrency';
|
||||||
import simpleFetch from '../../simpleFetch';
|
import simpleFetch from '../../simpleFetch';
|
||||||
|
|
||||||
export type WithdrawParams = {
|
export type WithdrawParams = {
|
||||||
asset: string,
|
asset: string
|
||||||
amount: BigNumber.Value,
|
amount: BigNumber.Value
|
||||||
signer: ethers.Signer,
|
signer: ethers.Signer
|
||||||
orionUnit: OrionUnit,
|
orionUnit: OrionUnit
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function withdraw({
|
export default async function withdraw({
|
||||||
@@ -29,8 +27,8 @@ export default async function withdraw({
|
|||||||
if (asset === '') throw new Error('Asset can not be empty');
|
if (asset === '') throw new Error('Asset can not be empty');
|
||||||
|
|
||||||
const amountBN = new BigNumber(amount);
|
const amountBN = new BigNumber(amount);
|
||||||
if (amountBN.isNaN()) throw new Error(`Amount '${amount.toString()}' is not a number`);
|
if (amountBN.isNaN()) throw new Error(`Amount '${amountBN.toString()}' is not a number`);
|
||||||
if (amountBN.lte(0)) throw new Error(`Amount '${amount.toString()}' should be greater than 0`);
|
if (amountBN.lte(0)) throw new Error(`Amount '${amountBN.toString()}' should be greater than 0`);
|
||||||
|
|
||||||
const walletAddress = await signer.getAddress();
|
const walletAddress = await signer.getAddress();
|
||||||
|
|
||||||
@@ -47,7 +45,7 @@ export default async function withdraw({
|
|||||||
const gasPriceWei = await simpleFetch(orionBlockchain.getGasPriceWei)();
|
const gasPriceWei = await simpleFetch(orionBlockchain.getGasPriceWei)();
|
||||||
|
|
||||||
const assetAddress = assetToAddress[asset];
|
const assetAddress = assetToAddress[asset];
|
||||||
if (!assetAddress) throw new Error(`Asset '${asset}' not found`);
|
if (assetAddress === undefined) throw new Error(`Asset '${asset}' not found`);
|
||||||
|
|
||||||
const balances = await getBalances(
|
const balances = await getBalances(
|
||||||
{
|
{
|
||||||
@@ -76,7 +74,7 @@ export default async function withdraw({
|
|||||||
name: asset,
|
name: asset,
|
||||||
address: assetAddress,
|
address: assetAddress,
|
||||||
},
|
},
|
||||||
amount: amount.toString(),
|
amount: amountBN.toString(),
|
||||||
sources: ['exchange'],
|
sources: ['exchange'],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -87,7 +85,7 @@ export default async function withdraw({
|
|||||||
unsignedTx.gasLimit = ethers.BigNumber.from(WITHDRAW_GAS_LIMIT);
|
unsignedTx.gasLimit = ethers.BigNumber.from(WITHDRAW_GAS_LIMIT);
|
||||||
|
|
||||||
const transactionCost = ethers.BigNumber.from(unsignedTx.gasLimit).mul(gasPriceWei);
|
const transactionCost = ethers.BigNumber.from(unsignedTx.gasLimit).mul(gasPriceWei);
|
||||||
const denormalizedTransactionCost = utils.denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
|
const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
|
||||||
|
|
||||||
balanceGuard.registerRequirement({
|
balanceGuard.registerRequirement({
|
||||||
reason: 'Network fee',
|
reason: 'Network fee',
|
||||||
@@ -112,7 +110,7 @@ export default async function withdraw({
|
|||||||
const txResponse = await provider.sendTransaction(signedTx);
|
const txResponse = await provider.sendTransaction(signedTx);
|
||||||
console.log(`Withdraw tx sent: ${txResponse.hash}. Waiting for confirmation...`);
|
console.log(`Withdraw tx sent: ${txResponse.hash}. Waiting for confirmation...`);
|
||||||
const txReceipt = await txResponse.wait();
|
const txReceipt = await txResponse.wait();
|
||||||
if (txReceipt.status) {
|
if (txReceipt.status !== undefined) {
|
||||||
console.log('Withdraw tx confirmed');
|
console.log('Withdraw tx confirmed');
|
||||||
} else {
|
} else {
|
||||||
console.log('Withdraw tx failed');
|
console.log('Withdraw tx failed');
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Exchange__factory, IUniswapV2Pair__factory, IUniswapV2Router__factory } from '@orionprotocol/contracts';
|
import { Exchange__factory, IUniswapV2Pair__factory, IUniswapV2Router__factory } from '@orionprotocol/contracts';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import OrionUnit from '..';
|
import type OrionUnit from '..';
|
||||||
import BalanceGuard from '../../BalanceGuard';
|
import BalanceGuard from '../../BalanceGuard';
|
||||||
import { ADD_LIQUIDITY_GAS_LIMIT, INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION } from '../../constants';
|
import { ADD_LIQUIDITY_GAS_LIMIT, INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION } from '../../constants';
|
||||||
import simpleFetch from '../../simpleFetch';
|
import simpleFetch from '../../simpleFetch';
|
||||||
@@ -12,14 +12,14 @@ import getNativeCryptocurrency from '../../utils/getNativeCryptocurrency';
|
|||||||
const ADD_LIQUIDITY_SLIPPAGE = 0.05;
|
const ADD_LIQUIDITY_SLIPPAGE = 0.05;
|
||||||
|
|
||||||
export type AddLiquidityParams = {
|
export type AddLiquidityParams = {
|
||||||
poolName: string,
|
poolName: string
|
||||||
amountAsset: string,
|
amountAsset: string
|
||||||
amount: BigNumber.Value,
|
amount: BigNumber.Value
|
||||||
signer: ethers.Signer
|
signer: ethers.Signer
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RemoveAllLiquidityParams = {
|
export type RemoveAllLiquidityParams = {
|
||||||
poolName: string,
|
poolName: string
|
||||||
signer: ethers.Signer
|
signer: ethers.Signer
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,14 +57,14 @@ export default class FarmingManager {
|
|||||||
.connect(exchangeContractAddress, this.orionUnit.provider);
|
.connect(exchangeContractAddress, this.orionUnit.provider);
|
||||||
|
|
||||||
const assetAAddress = assetToAddress[assetA];
|
const assetAAddress = assetToAddress[assetA];
|
||||||
if (!assetAAddress) throw new Error(`Asset '${assetA}' not found`);
|
if (assetAAddress === undefined) throw new Error(`Asset '${assetA}' not found`);
|
||||||
const assetBAddress = assetToAddress[assetB];
|
const assetBAddress = assetToAddress[assetB];
|
||||||
if (!assetBAddress) throw new Error(`Asset '${assetB}' not found`);
|
if (assetBAddress === undefined) throw new Error(`Asset '${assetB}' not found`);
|
||||||
|
|
||||||
const assetADecimals = assetToDecimals[assetA];
|
const assetADecimals = assetToDecimals[assetA];
|
||||||
if (!assetADecimals) throw new Error(`Decimals for asset '${assetA}' not found`);
|
if (assetADecimals === undefined) throw new Error(`Decimals for asset '${assetA}' not found`);
|
||||||
const assetBDecimals = assetToDecimals[assetB];
|
const assetBDecimals = assetToDecimals[assetB];
|
||||||
if (!assetBDecimals) throw new Error(`Decimals for asset '${assetB}' not found`);
|
if (assetBDecimals === undefined) throw new Error(`Decimals for asset '${assetB}' not found`);
|
||||||
|
|
||||||
const nativeCryptocurrency = getNativeCryptocurrency(assetToAddress);
|
const nativeCryptocurrency = getNativeCryptocurrency(assetToAddress);
|
||||||
const balances = await getBalances(
|
const balances = await getBalances(
|
||||||
@@ -145,7 +145,7 @@ export default class FarmingManager {
|
|||||||
sources: ['exchange', 'wallet'],
|
sources: ['exchange', 'wallet'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const unsignedTx = await exchangeContract?.populateTransaction.withdrawToPool(
|
const unsignedTx = await exchangeContract.populateTransaction.withdrawToPool(
|
||||||
assetBIsNativeCurrency ? assetBAddress : assetAAddress,
|
assetBIsNativeCurrency ? assetBAddress : assetAAddress,
|
||||||
assetBIsNativeCurrency ? assetAAddress : assetBAddress,
|
assetBIsNativeCurrency ? assetAAddress : assetBAddress,
|
||||||
assetBIsNativeCurrency
|
assetBIsNativeCurrency
|
||||||
@@ -231,14 +231,14 @@ export default class FarmingManager {
|
|||||||
} = await simpleFetch(this.orionUnit.orionBlockchain.getInfo)();
|
} = await simpleFetch(this.orionUnit.orionBlockchain.getInfo)();
|
||||||
|
|
||||||
const assetAAddress = assetToAddress[assetA];
|
const assetAAddress = assetToAddress[assetA];
|
||||||
if (!assetAAddress) throw new Error(`Asset '${assetA}' not found`);
|
if (assetAAddress === undefined) throw new Error(`Asset '${assetA}' not found`);
|
||||||
const assetBAddress = assetToAddress[assetB];
|
const assetBAddress = assetToAddress[assetB];
|
||||||
if (!assetBAddress) throw new Error(`Asset '${assetB}' not found`);
|
if (assetBAddress === undefined) throw new Error(`Asset '${assetB}' not found`);
|
||||||
|
|
||||||
const assetADecimals = assetToDecimals[assetA];
|
const assetADecimals = assetToDecimals[assetA];
|
||||||
if (!assetADecimals) throw new Error(`Decimals for asset '${assetA}' not found`);
|
if (assetADecimals === undefined) throw new Error(`Decimals for asset '${assetA}' not found`);
|
||||||
const assetBDecimals = assetToDecimals[assetB];
|
const assetBDecimals = assetToDecimals[assetB];
|
||||||
if (!assetBDecimals) throw new Error(`Decimals for asset '${assetB}' not found`);
|
if (assetBDecimals === undefined) throw new Error(`Decimals for asset '${assetB}' not found`);
|
||||||
|
|
||||||
const poolsConfig = await simpleFetch(this.orionUnit.orionBlockchain.getPoolsConfig)();
|
const poolsConfig = await simpleFetch(this.orionUnit.orionBlockchain.getPoolsConfig)();
|
||||||
const pool = poolsConfig.pools[poolName];
|
const pool = poolsConfig.pools[poolName];
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type { SupportedChainId, VerboseOrionUnitConfig } from '../types';
|
|||||||
import Exchange from './Exchange';
|
import Exchange from './Exchange';
|
||||||
import FarmingManager from './FarmingManager';
|
import FarmingManager from './FarmingManager';
|
||||||
import { chains } from '../config';
|
import { chains } from '../config';
|
||||||
import { networkCodes } from '../constants';
|
import { type networkCodes } from '../constants';
|
||||||
|
|
||||||
// type KnownConfig = {
|
// type KnownConfig = {
|
||||||
// env: string;
|
// env: string;
|
||||||
|
|||||||
@@ -8,14 +8,23 @@ import express from 'express';
|
|||||||
import WebSocket from 'ws';
|
import WebSocket from 'ws';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import httpToWS from '../utils/httpToWS';
|
import httpToWS from '../utils/httpToWS';
|
||||||
|
import {
|
||||||
|
createHttpTerminator,
|
||||||
|
} from 'http-terminator';
|
||||||
|
|
||||||
|
jest.setTimeout(10000);
|
||||||
|
|
||||||
const createServer = (externalHost: string) => {
|
const createServer = (externalHost: string) => {
|
||||||
const app = express();
|
const app = express();
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
|
|
||||||
|
const httpTerminator = createHttpTerminator({ server });
|
||||||
const wss = new WebSocket.Server({ server });
|
const wss = new WebSocket.Server({ server });
|
||||||
|
|
||||||
let externalWs: WebSocket | null = null;
|
let externalWs: WebSocket | null = null;
|
||||||
|
|
||||||
wss.on('connection', (ws, req) => {
|
wss.on('connection', (ws, req) => {
|
||||||
|
if (req.url === undefined) throw new Error('req.url is undefined');
|
||||||
const targetUrl = httpToWS(`${externalHost}${req.url}`);
|
const targetUrl = httpToWS(`${externalHost}${req.url}`);
|
||||||
externalWs = new WebSocket(targetUrl);
|
externalWs = new WebSocket(targetUrl);
|
||||||
|
|
||||||
@@ -32,7 +41,8 @@ const createServer = (externalHost: string) => {
|
|||||||
|
|
||||||
app.get(
|
app.get(
|
||||||
'*',
|
'*',
|
||||||
async (req, res) => {
|
(req, res) => {
|
||||||
|
(async () => {
|
||||||
const routeFromURL = req.url;
|
const routeFromURL = req.url;
|
||||||
try {
|
try {
|
||||||
const targetUrl = `${externalHost}${routeFromURL}`;
|
const targetUrl = `${externalHost}${routeFromURL}`;
|
||||||
@@ -44,21 +54,27 @@ const createServer = (externalHost: string) => {
|
|||||||
error: 'Failed to retrieve data from external resource'
|
error: 'Failed to retrieve data from external resource'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
})().catch(console.error)
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(0);
|
server.listen(0);
|
||||||
|
|
||||||
const address = server.address();
|
const address = server.address();
|
||||||
|
|
||||||
if (typeof address === 'string') {
|
if (typeof address === 'string') {
|
||||||
throw new Error(`Server address is a string: ${address}`);
|
throw new Error(`Server address is a string: ${address}`);
|
||||||
}
|
}
|
||||||
|
const closeWS = () => new Promise((resolve) => {
|
||||||
|
wss.close(resolve);
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
port: address?.port,
|
port: address?.port,
|
||||||
close: () => new Promise((resolve) => {
|
terminate: async () => {
|
||||||
externalWs?.close();
|
externalWs?.close();
|
||||||
server.close(resolve);
|
await closeWS();
|
||||||
}),
|
await httpTerminator.terminate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +153,10 @@ describe('Orion', () => {
|
|||||||
const server1 = createServer('https://trade.orionprotocol.io');
|
const server1 = createServer('https://trade.orionprotocol.io');
|
||||||
const server2 = createServer('https://trade.orionprotocol.io');
|
const server2 = createServer('https://trade.orionprotocol.io');
|
||||||
|
|
||||||
|
if (server0.port === undefined || server1.port === undefined || server2.port === undefined) {
|
||||||
|
throw new Error('Server port is undefined');
|
||||||
|
}
|
||||||
|
|
||||||
const orionBlockchainAPI = `http://localhost:${server0.port}`;
|
const orionBlockchainAPI = `http://localhost:${server0.port}`;
|
||||||
const orionAggregatorAPI = `http://localhost:${server1.port}`;
|
const orionAggregatorAPI = `http://localhost:${server1.port}`;
|
||||||
const orionPriceFeedAPI = `http://localhost:${server2.port}`;
|
const orionPriceFeedAPI = `http://localhost:${server2.port}`;
|
||||||
@@ -165,7 +185,7 @@ describe('Orion', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const orionUnit = orion.unitsArray[0];
|
const [orionUnit] = orion.unitsArray;
|
||||||
if (!orionUnit) {
|
if (!orionUnit) {
|
||||||
throw new Error('Orion unit is not defined');
|
throw new Error('Orion unit is not defined');
|
||||||
}
|
}
|
||||||
@@ -197,10 +217,6 @@ describe('Orion', () => {
|
|||||||
expect(priceData).toBeDefined();
|
expect(priceData).toBeDefined();
|
||||||
|
|
||||||
const allTickersDone = await new Promise<boolean>((resolve, reject) => {
|
const allTickersDone = await new Promise<boolean>((resolve, reject) => {
|
||||||
const timeout = setTimeout(() => {
|
|
||||||
reject(new Error('Timeout'));
|
|
||||||
}, 10000);
|
|
||||||
|
|
||||||
const { unsubscribe } = orionUnit.priceFeed.ws.subscribe(
|
const { unsubscribe } = orionUnit.priceFeed.ws.subscribe(
|
||||||
'allTickers',
|
'allTickers',
|
||||||
{
|
{
|
||||||
@@ -211,12 +227,16 @@ describe('Orion', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
unsubscribe();
|
||||||
|
reject(new Error(`Timeout: ${orionUnit.priceFeed.wsUrl}`));
|
||||||
|
}, 10000);
|
||||||
});
|
});
|
||||||
expect(allTickersDone).toBe(true);
|
expect(allTickersDone).toBe(true);
|
||||||
|
|
||||||
await server0.close();
|
await server0.terminate();
|
||||||
await server1.close();
|
await server1.terminate();
|
||||||
await server2.close();
|
await server2.terminate();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Init Orion testing with overrides', () => {
|
test('Init Orion testing with overrides', () => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import exchanges from './exchanges';
|
import type exchanges from './exchanges';
|
||||||
|
|
||||||
const mapping: Record<
|
const mapping: Record<
|
||||||
typeof exchanges[number],
|
typeof exchanges[number],
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { SupportedChainId } from '../types';
|
import { type SupportedChainId } from '../types';
|
||||||
import eip712DomainData from '../config/eip712DomainData.json';
|
import eip712DomainData from '../config/eip712DomainData.json';
|
||||||
import eip712DomainSchema from '../config/schemas/eip712DomainSchema';
|
import eip712DomainSchema from '../config/schemas/eip712DomainSchema';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { CFDOrder } from '../types';
|
import { type CFDOrder } from '../types';
|
||||||
|
|
||||||
const hashCFDOrder = (order: CFDOrder) => ethers.utils.solidityKeccak256(
|
const hashCFDOrder = (order: CFDOrder) => ethers.utils.solidityKeccak256(
|
||||||
[
|
[
|
||||||
@@ -24,7 +24,7 @@ const hashCFDOrder = (order: CFDOrder) => ethers.utils.solidityKeccak256(
|
|||||||
order.matcherFee,
|
order.matcherFee,
|
||||||
order.nonce,
|
order.nonce,
|
||||||
order.expiration,
|
order.expiration,
|
||||||
order.buySide ? '0x01' : '0x00',
|
order.buySide === 1 ? '0x01' : '0x00',
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { Order } from '../types';
|
import { type Order } from '../types';
|
||||||
|
|
||||||
const hashOrder = (order: Order) => ethers.utils.solidityKeccak256(
|
const hashOrder = (order: Order) => ethers.utils.solidityKeccak256(
|
||||||
[
|
[
|
||||||
@@ -28,7 +28,7 @@ const hashOrder = (order: Order) => ethers.utils.solidityKeccak256(
|
|||||||
order.matcherFee,
|
order.matcherFee,
|
||||||
order.nonce,
|
order.nonce,
|
||||||
order.expiration,
|
order.expiration,
|
||||||
order.buySide ? '0x01' : '0x00',
|
order.buySide === 1 ? '0x01' : '0x00',
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
/* eslint-disable no-underscore-dangle */
|
import { type TypedDataSigner } from '@ethersproject/abstract-signer';
|
||||||
import { TypedDataSigner } from '@ethersproject/abstract-signer';
|
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { type ethers } from 'ethers';
|
||||||
import { joinSignature, splitSignature } from 'ethers/lib/utils';
|
import { joinSignature, splitSignature } from 'ethers/lib/utils';
|
||||||
import { INTERNAL_ORION_PRECISION } from '../constants';
|
import { INTERNAL_ORION_PRECISION } from '../constants';
|
||||||
import { CFDOrder, SignedCFDOrder, SupportedChainId } from '../types';
|
import { type CFDOrder, type SignedCFDOrder, type SupportedChainId } from '../types';
|
||||||
import normalizeNumber from '../utils/normalizeNumber';
|
import normalizeNumber from '../utils/normalizeNumber';
|
||||||
import getDomainData from './getDomainData';
|
import getDomainData from './getDomainData';
|
||||||
import signCFDOrderPersonal from './signCFDOrderPersonal';
|
import signCFDOrderPersonal from './signCFDOrderPersonal';
|
||||||
@@ -69,7 +68,7 @@ export const signCFDOrder = async (
|
|||||||
// "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1"
|
// "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1"
|
||||||
const fixedSignature = joinSignature(splitSignature(signature));
|
const fixedSignature = joinSignature(splitSignature(signature));
|
||||||
|
|
||||||
if (!fixedSignature) throw new Error("Can't sign order");
|
// if (!fixedSignature) throw new Error("Can't sign order");
|
||||||
|
|
||||||
const signedOrder: SignedCFDOrder = {
|
const signedOrder: SignedCFDOrder = {
|
||||||
...order,
|
...order,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { CFDOrder } from '../types';
|
import { type CFDOrder } from '../types';
|
||||||
|
|
||||||
const { arrayify, joinSignature, splitSignature } = ethers.utils;
|
const { arrayify, joinSignature, splitSignature } = ethers.utils;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
/* eslint-disable no-underscore-dangle */
|
import { type TypedDataSigner } from '@ethersproject/abstract-signer';
|
||||||
import { TypedDataSigner } from '@ethersproject/abstract-signer';
|
import { type ethers } from 'ethers';
|
||||||
import { ethers } from 'ethers';
|
|
||||||
import { joinSignature, splitSignature } from 'ethers/lib/utils';
|
import { joinSignature, splitSignature } from 'ethers/lib/utils';
|
||||||
import CANCEL_ORDER_TYPES from '../constants/cancelOrderTypes';
|
import CANCEL_ORDER_TYPES from '../constants/cancelOrderTypes';
|
||||||
import { CancelOrderRequest, SignedCancelOrderRequest, SupportedChainId } from '../types';
|
import { type CancelOrderRequest, type SignedCancelOrderRequest, type SupportedChainId } from '../types';
|
||||||
import getDomainData from './getDomainData';
|
import getDomainData from './getDomainData';
|
||||||
import signCancelOrderPersonal from './signCancelOrderPersonal';
|
import signCancelOrderPersonal from './signCancelOrderPersonal';
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ const signCancelOrder = async (
|
|||||||
// "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1"
|
// "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1"
|
||||||
const fixedSignature = joinSignature(splitSignature(signature));
|
const fixedSignature = joinSignature(splitSignature(signature));
|
||||||
|
|
||||||
if (!fixedSignature) throw new Error("Can't sign order cancel");
|
// if (!fixedSignature) throw new Error("Can't sign order cancel");
|
||||||
|
|
||||||
const signedCancelOrderReqeust: SignedCancelOrderRequest = {
|
const signedCancelOrderReqeust: SignedCancelOrderRequest = {
|
||||||
...cancelOrderRequest,
|
...cancelOrderRequest,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { arrayify, joinSignature, splitSignature } from 'ethers/lib/utils';
|
import { arrayify, joinSignature, splitSignature } from 'ethers/lib/utils';
|
||||||
import { CancelOrderRequest } from '../types';
|
import { type CancelOrderRequest } from '../types';
|
||||||
|
|
||||||
const signCancelOrderPersonal = async (
|
const signCancelOrderPersonal = async (
|
||||||
cancelOrderRequest: CancelOrderRequest,
|
cancelOrderRequest: CancelOrderRequest,
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
/* eslint-disable no-underscore-dangle */
|
import { type TypedDataSigner } from '@ethersproject/abstract-signer';
|
||||||
import { TypedDataSigner } from '@ethersproject/abstract-signer';
|
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { type ethers } from 'ethers';
|
||||||
import { joinSignature, splitSignature } from 'ethers/lib/utils';
|
import { joinSignature, splitSignature } from 'ethers/lib/utils';
|
||||||
import { INTERNAL_ORION_PRECISION } from '../constants';
|
import { INTERNAL_ORION_PRECISION } from '../constants';
|
||||||
import ORDER_TYPES from '../constants/orderTypes';
|
import ORDER_TYPES from '../constants/orderTypes';
|
||||||
import { Order, SignedOrder, SupportedChainId } from '../types';
|
import { type Order, type SignedOrder, type SupportedChainId } from '../types';
|
||||||
import normalizeNumber from '../utils/normalizeNumber';
|
import normalizeNumber from '../utils/normalizeNumber';
|
||||||
import getDomainData from './getDomainData';
|
import getDomainData from './getDomainData';
|
||||||
import hashOrder from './hashOrder';
|
import hashOrder from './hashOrder';
|
||||||
@@ -74,7 +73,7 @@ export const signOrder = async (
|
|||||||
// "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1"
|
// "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1"
|
||||||
const fixedSignature = joinSignature(splitSignature(signature));
|
const fixedSignature = joinSignature(splitSignature(signature));
|
||||||
|
|
||||||
if (!fixedSignature) throw new Error("Can't sign order");
|
// if (!fixedSignature) throw new Error("Can't sign order");
|
||||||
|
|
||||||
const signedOrder: SignedOrder = {
|
const signedOrder: SignedOrder = {
|
||||||
...order,
|
...order,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { Order } from '../types';
|
import { type Order } from '../types';
|
||||||
|
|
||||||
const { arrayify, joinSignature, splitSignature } = ethers.utils;
|
const { arrayify, joinSignature, splitSignature } = ethers.utils;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Schema, z } from 'zod';
|
import { type Schema, type z } from 'zod';
|
||||||
import fetch from 'isomorphic-unfetch';
|
import fetch from 'isomorphic-unfetch';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -26,7 +26,7 @@ export default async function fetchWithValidation<DataOut, DataIn, ErrorOut, Err
|
|||||||
// payload
|
// payload
|
||||||
|
|
||||||
const fetchResult = await fromPromise(fetch(url, {
|
const fetchResult = await fromPromise(fetch(url, {
|
||||||
...options || {},
|
...options ?? {},
|
||||||
headers: {
|
headers: {
|
||||||
'Cache-Control': 'no-store, max-age=0',
|
'Cache-Control': 'no-store, max-age=0',
|
||||||
...(options ? options.headers : {}),
|
...(options ? options.headers : {}),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import type BigNumber from 'bignumber.js';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import fetchWithValidation from '../../fetchWithValidation';
|
import fetchWithValidation from '../../fetchWithValidation';
|
||||||
import swapInfoSchema from './schemas/swapInfoSchema';
|
import swapInfoSchema from './schemas/swapInfoSchema';
|
||||||
@@ -9,12 +9,12 @@ import errorSchema from './schemas/errorSchema';
|
|||||||
import placeAtomicSwapSchema from './schemas/placeAtomicSwapSchema';
|
import placeAtomicSwapSchema from './schemas/placeAtomicSwapSchema';
|
||||||
import { OrionAggregatorWS } from './ws';
|
import { OrionAggregatorWS } from './ws';
|
||||||
import { atomicSwapHistorySchema } from './schemas/atomicSwapHistorySchema';
|
import { atomicSwapHistorySchema } from './schemas/atomicSwapHistorySchema';
|
||||||
import { Exchange, SignedCancelOrderRequest, SignedCFDOrder, SignedOrder } from '../../types';
|
import { type Exchange, type SignedCancelOrderRequest, type SignedCFDOrder, type SignedOrder } from '../../types';
|
||||||
import { pairConfigSchema } from './schemas';
|
import { pairConfigSchema } from './schemas';
|
||||||
import {
|
import {
|
||||||
aggregatedOrderbookSchema, exchangeOrderbookSchema, poolReservesSchema,
|
aggregatedOrderbookSchema, exchangeOrderbookSchema, poolReservesSchema,
|
||||||
} from './schemas/aggregatedOrderbookSchema';
|
} from './schemas/aggregatedOrderbookSchema';
|
||||||
import networkCodes from '../../constants/networkCodes';
|
import type networkCodes from '../../constants/networkCodes';
|
||||||
import toUpperCase from '../../utils/toUpperCase';
|
import toUpperCase from '../../utils/toUpperCase';
|
||||||
import httpToWS from '../../utils/httpToWS';
|
import httpToWS from '../../utils/httpToWS';
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ class OrionAggregator {
|
|||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
...partnerId && { 'X-Partner-Id': partnerId },
|
...(partnerId !== undefined) && { 'X-Partner-Id': partnerId },
|
||||||
};
|
};
|
||||||
|
|
||||||
return fetchWithValidation(
|
return fetchWithValidation(
|
||||||
@@ -232,7 +232,7 @@ class OrionAggregator {
|
|||||||
} else {
|
} else {
|
||||||
url.searchParams.append('amountOut', amount);
|
url.searchParams.append('amountOut', amount);
|
||||||
}
|
}
|
||||||
if (exchanges) {
|
if (exchanges !== undefined) {
|
||||||
if (Array.isArray(exchanges)) {
|
if (Array.isArray(exchanges)) {
|
||||||
exchanges.forEach((exchange) => {
|
exchanges.forEach((exchange) => {
|
||||||
url.searchParams.append('exchanges', exchange);
|
url.searchParams.append('exchanges', exchange);
|
||||||
@@ -241,7 +241,7 @@ class OrionAggregator {
|
|||||||
url.searchParams.append('exchanges', exchanges);
|
url.searchParams.append('exchanges', exchanges);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (instantSettlement) {
|
if (instantSettlement !== undefined && instantSettlement) {
|
||||||
url.searchParams.append('instantSettlement', 'true');
|
url.searchParams.append('instantSettlement', 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import {
|
|||||||
} from './schemas';
|
} from './schemas';
|
||||||
import UnsubscriptionType from './UnsubscriptionType';
|
import UnsubscriptionType from './UnsubscriptionType';
|
||||||
import {
|
import {
|
||||||
SwapInfoBase, AssetPairUpdate, OrderbookItem, Balance,
|
type SwapInfoBase, type AssetPairUpdate, type OrderbookItem,
|
||||||
Exchange, CFDBalance, SwapInfo, FuturesTradeInfo,
|
type Balance, type Exchange, type CFDBalance, type FuturesTradeInfo, type SwapInfo,
|
||||||
} from '../../../types';
|
} from '../../../types';
|
||||||
import unsubscriptionDoneSchema from './schemas/unsubscriptionDoneSchema';
|
import unsubscriptionDoneSchema from './schemas/unsubscriptionDoneSchema';
|
||||||
import assetPairConfigSchema from './schemas/assetPairConfigSchema';
|
import assetPairConfigSchema from './schemas/assetPairConfigSchema';
|
||||||
import { fullOrderSchema, orderUpdateSchema } from './schemas/addressUpdateSchema';
|
import { type fullOrderSchema, type orderUpdateSchema } from './schemas/addressUpdateSchema';
|
||||||
import cfdAddressUpdateSchema from './schemas/cfdAddressUpdateSchema';
|
import cfdAddressUpdateSchema from './schemas/cfdAddressUpdateSchema';
|
||||||
import futuresTradeInfoSchema from './schemas/futuresTradeInfoSchema';
|
import futuresTradeInfoSchema from './schemas/futuresTradeInfoSchema';
|
||||||
// import errorSchema from './schemas/errorSchema';
|
// import errorSchema from './schemas/errorSchema';
|
||||||
@@ -25,108 +25,108 @@ const UNSUBSCRIBE = 'u';
|
|||||||
// https://github.com/orionprotocol/orion-aggregator/tree/feature/OP-1752-symmetric-swap#swap-info-subscribe
|
// https://github.com/orionprotocol/orion-aggregator/tree/feature/OP-1752-symmetric-swap#swap-info-subscribe
|
||||||
type SwapSubscriptionRequest = {
|
type SwapSubscriptionRequest = {
|
||||||
// d: string, // swap request UUID, set by client side
|
// d: string, // swap request UUID, set by client side
|
||||||
i: string, // asset in
|
i: string // asset in
|
||||||
o: string, // asset out
|
o: string // asset out
|
||||||
a: number // amount IN/OUT
|
a: number // amount IN/OUT
|
||||||
es?: Exchange[] | 'cex' | 'pools', // exchange list of all cex or all pools (ORION_POOL, UNISWAP, PANCAKESWAP etc)
|
es?: Exchange[] | 'cex' | 'pools' // exchange list of all cex or all pools (ORION_POOL, UNISWAP, PANCAKESWAP etc)
|
||||||
e?: boolean; // is amount IN? Value `false` means a = amount OUT, `true` if omitted
|
e?: boolean // is amount IN? Value `false` means a = amount OUT, `true` if omitted
|
||||||
is?: boolean; // instant settlement
|
is?: boolean // instant settlement
|
||||||
}
|
}
|
||||||
|
|
||||||
type BrokerTradableAtomicSwapBalanceSubscription = {
|
type BrokerTradableAtomicSwapBalanceSubscription = {
|
||||||
callback: (balances: Partial<Record<string, number>>) => void,
|
callback: (balances: Partial<Record<string, number>>) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type PairsConfigSubscription = {
|
type PairsConfigSubscription = {
|
||||||
callback: ({ kind, data }: {
|
callback: ({ kind, data }: {
|
||||||
kind: 'initial' | 'update',
|
kind: 'initial' | 'update'
|
||||||
data: Partial<Record<string, AssetPairUpdate>>,
|
data: Partial<Record<string, AssetPairUpdate>>
|
||||||
}) => void,
|
}) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type PairConfigSubscription = {
|
type PairConfigSubscription = {
|
||||||
payload: string,
|
payload: string
|
||||||
callback: ({ kind, data }: {
|
callback: ({ kind, data }: {
|
||||||
kind: 'initial' | 'update',
|
kind: 'initial' | 'update'
|
||||||
data: AssetPairUpdate,
|
data: AssetPairUpdate
|
||||||
}) => void,
|
}) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type AggregatedOrderbookSubscription = {
|
type AggregatedOrderbookSubscription = {
|
||||||
payload: string,
|
payload: string
|
||||||
callback: (
|
callback: (
|
||||||
asks: OrderbookItem[],
|
asks: OrderbookItem[],
|
||||||
bids: OrderbookItem[],
|
bids: OrderbookItem[],
|
||||||
pair: string
|
pair: string
|
||||||
) => void,
|
) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type SwapInfoSubscription = {
|
type SwapInfoSubscription = {
|
||||||
payload: SwapSubscriptionRequest,
|
payload: SwapSubscriptionRequest
|
||||||
callback: (swapInfo: SwapInfo) => void,
|
callback: (swapInfo: SwapInfo) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type FuturesTradeInfoSubscription = {
|
type FuturesTradeInfoSubscription = {
|
||||||
payload: {
|
payload: {
|
||||||
s: string,
|
s: string
|
||||||
i: string,
|
i: string
|
||||||
a: number,
|
a: number
|
||||||
p?: number,
|
p?: number
|
||||||
},
|
}
|
||||||
callback: (futuresTradeInfo: FuturesTradeInfo) => void,
|
callback: (futuresTradeInfo: FuturesTradeInfo) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddressUpdateUpdate = {
|
type AddressUpdateUpdate = {
|
||||||
kind: 'update',
|
kind: 'update'
|
||||||
balances: Partial<
|
balances: Partial<
|
||||||
Record<
|
Record<
|
||||||
string,
|
string,
|
||||||
Balance
|
Balance
|
||||||
>
|
>
|
||||||
>,
|
>
|
||||||
order?: z.infer<typeof orderUpdateSchema> | z.infer<typeof fullOrderSchema>
|
order?: z.infer<typeof orderUpdateSchema> | z.infer<typeof fullOrderSchema>
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddressUpdateInitial = {
|
type AddressUpdateInitial = {
|
||||||
kind: 'initial',
|
kind: 'initial'
|
||||||
balances: Partial<
|
balances: Partial<
|
||||||
Record<
|
Record<
|
||||||
string,
|
string,
|
||||||
Balance
|
Balance
|
||||||
>
|
>
|
||||||
>,
|
>
|
||||||
orders?: z.infer<typeof fullOrderSchema>[] // The field is not defined if the user has no orders
|
orders?: Array<z.infer<typeof fullOrderSchema>> // The field is not defined if the user has no orders
|
||||||
}
|
}
|
||||||
|
|
||||||
type CfdAddressUpdateUpdate = {
|
type CfdAddressUpdateUpdate = {
|
||||||
kind: 'update',
|
kind: 'update'
|
||||||
balances?: CFDBalance[],
|
balances?: CFDBalance[]
|
||||||
order?: z.infer<typeof orderUpdateSchema> | z.infer<typeof fullOrderSchema>
|
order?: z.infer<typeof orderUpdateSchema> | z.infer<typeof fullOrderSchema>
|
||||||
}
|
}
|
||||||
|
|
||||||
type CfdAddressUpdateInitial = {
|
type CfdAddressUpdateInitial = {
|
||||||
kind: 'initial',
|
kind: 'initial'
|
||||||
balances: CFDBalance[],
|
balances: CFDBalance[]
|
||||||
orders?: z.infer<typeof fullOrderSchema>[] // The field is not defined if the user has no orders
|
orders?: Array<z.infer<typeof fullOrderSchema>> // The field is not defined if the user has no orders
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddressUpdateSubscription = {
|
type AddressUpdateSubscription = {
|
||||||
payload: string,
|
payload: string
|
||||||
callback: (data: AddressUpdateUpdate | AddressUpdateInitial) => void,
|
callback: (data: AddressUpdateUpdate | AddressUpdateInitial) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type CfdAddressUpdateSubscription = {
|
type CfdAddressUpdateSubscription = {
|
||||||
payload: string,
|
payload: string
|
||||||
callback: (data: CfdAddressUpdateUpdate | CfdAddressUpdateInitial) => void,
|
callback: (data: CfdAddressUpdateUpdate | CfdAddressUpdateInitial) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type Subscription = {
|
type Subscription = {
|
||||||
[SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE]: AddressUpdateSubscription,
|
[SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE]: AddressUpdateSubscription
|
||||||
[SubscriptionType.CFD_ADDRESS_UPDATES_SUBSCRIBE]: CfdAddressUpdateSubscription,
|
[SubscriptionType.CFD_ADDRESS_UPDATES_SUBSCRIBE]: CfdAddressUpdateSubscription
|
||||||
[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE]: AggregatedOrderbookSubscription,
|
[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE]: AggregatedOrderbookSubscription
|
||||||
[SubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_SUBSCRIBE]: PairsConfigSubscription,
|
[SubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_SUBSCRIBE]: PairsConfigSubscription
|
||||||
[SubscriptionType.ASSET_PAIR_CONFIG_UPDATES_SUBSCRIBE]: PairConfigSubscription,
|
[SubscriptionType.ASSET_PAIR_CONFIG_UPDATES_SUBSCRIBE]: PairConfigSubscription
|
||||||
[SubscriptionType.BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE]: BrokerTradableAtomicSwapBalanceSubscription,
|
[SubscriptionType.BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE]: BrokerTradableAtomicSwapBalanceSubscription
|
||||||
[SubscriptionType.SWAP_SUBSCRIBE]: SwapInfoSubscription
|
[SubscriptionType.SWAP_SUBSCRIBE]: SwapInfoSubscription
|
||||||
[SubscriptionType.FUTURES_TRADE_INFO_SUBSCRIBE]: FuturesTradeInfoSubscription
|
[SubscriptionType.FUTURES_TRADE_INFO_SUBSCRIBE]: FuturesTradeInfoSubscription
|
||||||
}
|
}
|
||||||
@@ -145,14 +145,14 @@ type BufferLike =
|
|||||||
| Uint8Array
|
| Uint8Array
|
||||||
| ArrayBuffer
|
| ArrayBuffer
|
||||||
| SharedArrayBuffer
|
| SharedArrayBuffer
|
||||||
| ReadonlyArray<unknown>
|
| readonly unknown[]
|
||||||
| ReadonlyArray<number>
|
| readonly number[]
|
||||||
| { valueOf(): ArrayBuffer }
|
| { valueOf: () => ArrayBuffer }
|
||||||
| { valueOf(): SharedArrayBuffer }
|
| { valueOf: () => SharedArrayBuffer }
|
||||||
| { valueOf(): Uint8Array }
|
| { valueOf: () => Uint8Array }
|
||||||
| { valueOf(): ReadonlyArray<number> }
|
| { valueOf: () => readonly number[] }
|
||||||
| { valueOf(): string }
|
| { valueOf: () => string }
|
||||||
| { [Symbol.toPrimitive](hint: string): string };
|
| { [Symbol.toPrimitive]: (hint: string) => string };
|
||||||
|
|
||||||
const isSubType = (subType: string): subType is keyof Subscription => Object.values(SubscriptionType).some((t) => t === subType);
|
const isSubType = (subType: string): subType is keyof Subscription => Object.values(SubscriptionType).some((t) => t === subType);
|
||||||
class OrionAggregatorWS {
|
class OrionAggregatorWS {
|
||||||
@@ -339,8 +339,9 @@ class OrionAggregatorWS {
|
|||||||
};
|
};
|
||||||
this.ws.onmessage = (e) => {
|
this.ws.onmessage = (e) => {
|
||||||
const { data } = e;
|
const { data } = e;
|
||||||
this.logger?.(`OrionAggregatorWS: received message: ${e.data.toString()}`);
|
if (typeof data !== 'string') throw new Error('OrionAggregatorWS: received non-string message');
|
||||||
const rawJson: unknown = JSON.parse(data.toString());
|
this.logger?.(`OrionAggregatorWS: received message: ${data}`);
|
||||||
|
const rawJson: unknown = JSON.parse(data);
|
||||||
|
|
||||||
const messageSchema = z.union([
|
const messageSchema = z.union([
|
||||||
initMessageSchema,
|
initMessageSchema,
|
||||||
@@ -385,7 +386,7 @@ class OrionAggregatorWS {
|
|||||||
path: json.ps,
|
path: json.ps,
|
||||||
exchanges: json.e,
|
exchanges: json.e,
|
||||||
poolOptimal: json.po,
|
poolOptimal: json.po,
|
||||||
...json.oi && {
|
...(json.oi) && {
|
||||||
orderInfo: {
|
orderInfo: {
|
||||||
pair: json.oi.p,
|
pair: json.oi.p,
|
||||||
side: json.oi.s,
|
side: json.oi.s,
|
||||||
@@ -511,8 +512,8 @@ class OrionAggregatorWS {
|
|||||||
case MessageType.CFD_ADDRESS_UPDATE:
|
case MessageType.CFD_ADDRESS_UPDATE:
|
||||||
switch (json.k) { // message kind
|
switch (json.k) { // message kind
|
||||||
case 'i': { // initial
|
case 'i': { // initial
|
||||||
const fullOrders = json.o
|
const fullOrders = (json.o)
|
||||||
? json.o.reduce<z.infer<typeof fullOrderSchema>[]>((prev, o) => {
|
? json.o.reduce<Array<z.infer<typeof fullOrderSchema>>>((prev, o) => {
|
||||||
prev.push(o);
|
prev.push(o);
|
||||||
|
|
||||||
return prev;
|
return prev;
|
||||||
@@ -524,7 +525,7 @@ class OrionAggregatorWS {
|
|||||||
]?.[json.id]?.callback({
|
]?.[json.id]?.callback({
|
||||||
kind: 'initial',
|
kind: 'initial',
|
||||||
orders: fullOrders,
|
orders: fullOrders,
|
||||||
balances: json.b ?? [],
|
balances: json.b,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -549,7 +550,7 @@ class OrionAggregatorWS {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MessageType.ADDRESS_UPDATE: {
|
case MessageType.ADDRESS_UPDATE: {
|
||||||
const balances = json.b
|
const balances = (json.b)
|
||||||
? Object.entries(json.b)
|
? Object.entries(json.b)
|
||||||
.reduce<Partial<Record<string, Balance>>>((prev, [asset, assetBalances]) => {
|
.reduce<Partial<Record<string, Balance>>>((prev, [asset, assetBalances]) => {
|
||||||
if (!assetBalances) return prev;
|
if (!assetBalances) return prev;
|
||||||
@@ -565,7 +566,7 @@ class OrionAggregatorWS {
|
|||||||
switch (json.k) { // message kind
|
switch (json.k) { // message kind
|
||||||
case 'i': { // initial
|
case 'i': { // initial
|
||||||
const fullOrders = json.o
|
const fullOrders = json.o
|
||||||
? json.o.reduce<z.infer<typeof fullOrderSchema>[]>((prev, o) => {
|
? json.o.reduce<Array<z.infer<typeof fullOrderSchema>>>((prev, o) => {
|
||||||
prev.push(o);
|
prev.push(o);
|
||||||
|
|
||||||
return prev;
|
return prev;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import fetchWithValidation from '../../fetchWithValidation';
|
|||||||
import overviewSchema from './schemas/overviewSchema';
|
import overviewSchema from './schemas/overviewSchema';
|
||||||
|
|
||||||
export default class OrionAnalytics {
|
export default class OrionAnalytics {
|
||||||
private apiUrl: string;
|
private readonly apiUrl: string;
|
||||||
|
|
||||||
constructor(apiUrl: string) {
|
constructor(apiUrl: string) {
|
||||||
this.apiUrl = apiUrl;
|
this.apiUrl = apiUrl;
|
||||||
|
|||||||
@@ -3,63 +3,63 @@ import fetchWithValidation from '../../fetchWithValidation';
|
|||||||
import {
|
import {
|
||||||
IDOSchema, atomicHistorySchema,
|
IDOSchema, atomicHistorySchema,
|
||||||
poolsConfigSchema, poolsInfoSchema, infoSchema, historySchema,
|
poolsConfigSchema, poolsInfoSchema, infoSchema, historySchema,
|
||||||
addPoolSchema, adminPoolsListSchema, adminPoolSchema,
|
type addPoolSchema, adminPoolsListSchema, adminPoolSchema,
|
||||||
atomicSummarySchema,
|
atomicSummarySchema,
|
||||||
poolsLpAndStakedSchema,
|
poolsLpAndStakedSchema,
|
||||||
userVotesSchema,
|
userVotesSchema,
|
||||||
userEarnedSchema,
|
userEarnedSchema,
|
||||||
PairStatusEnum,
|
type PairStatusEnum,
|
||||||
pairStatusSchema,
|
pairStatusSchema,
|
||||||
cfdContractsSchema,
|
cfdContractsSchema,
|
||||||
cfdHistorySchema,
|
cfdHistorySchema,
|
||||||
} from './schemas';
|
} from './schemas';
|
||||||
import redeemOrderSchema from '../OrionAggregator/schemas/redeemOrderSchema';
|
import type redeemOrderSchema from '../OrionAggregator/schemas/redeemOrderSchema';
|
||||||
import { sourceAtomicHistorySchema, targetAtomicHistorySchema } from './schemas/atomicHistorySchema';
|
import { sourceAtomicHistorySchema, targetAtomicHistorySchema } from './schemas/atomicHistorySchema';
|
||||||
import { makePartial } from '../../utils';
|
import { makePartial } from '../../utils';
|
||||||
import { networkCodes } from '../../constants';
|
import { type networkCodes } from '../../constants';
|
||||||
|
|
||||||
interface IAdminAuthHeaders {
|
type IAdminAuthHeaders = {
|
||||||
auth: string;
|
auth: string
|
||||||
[key: string]: string
|
[key: string]: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEditPool {
|
export type IEditPool = {
|
||||||
tokenAIcon?: string;
|
tokenAIcon?: string
|
||||||
tokenBIcon?: string;
|
tokenBIcon?: string
|
||||||
symbol?: string;
|
symbol?: string
|
||||||
status: PairStatusEnum;
|
status: PairStatusEnum
|
||||||
minQty?: number;
|
minQty?: number
|
||||||
tokenASymbol?: string;
|
tokenASymbol?: string
|
||||||
tokenBSymbol?: string;
|
tokenBSymbol?: string
|
||||||
tokensReversed?: boolean;
|
tokensReversed?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type AtomicSwapHistoryBaseQuery = {
|
type AtomicSwapHistoryBaseQuery = {
|
||||||
limit?: number
|
limit?: number
|
||||||
sender?: string,
|
sender?: string
|
||||||
receiver?: string,
|
receiver?: string
|
||||||
used?: 0 | 1,
|
used?: 0 | 1
|
||||||
page?: number,
|
page?: number
|
||||||
sourceNetworkCode?: typeof networkCodes[number],
|
sourceNetworkCode?: typeof networkCodes[number]
|
||||||
}
|
} & Partial<Record<string, string | number>>
|
||||||
|
|
||||||
type AtomicSwapHistorySourceQuery = AtomicSwapHistoryBaseQuery & {
|
type AtomicSwapHistorySourceQuery = AtomicSwapHistoryBaseQuery & {
|
||||||
type?: 'source',
|
type?: 'source'
|
||||||
expiredLock?: 0 | 1,
|
expiredLock?: 0 | 1
|
||||||
state?: 'LOCKED' | 'CLAIMED' |'REFUNDED',
|
state?: 'LOCKED' | 'CLAIMED' | 'REFUNDED'
|
||||||
|
|
||||||
}
|
}
|
||||||
type AtomicSwapHistoryTargetQuery = AtomicSwapHistoryBaseQuery & {
|
type AtomicSwapHistoryTargetQuery = AtomicSwapHistoryBaseQuery & {
|
||||||
type?: 'target',
|
type?: 'target'
|
||||||
expiredRedeem?: 0 | 1,
|
expiredRedeem?: 0 | 1
|
||||||
state?: 'REDEEMED' | 'BEFORE-REDEEM',
|
state?: 'REDEEMED' | 'BEFORE-REDEEM'
|
||||||
}
|
}
|
||||||
|
|
||||||
type CfdHistoryQuery = {
|
type CfdHistoryQuery = {
|
||||||
instrument?: string,
|
instrument?: string
|
||||||
page?: number,
|
page?: number
|
||||||
limit?: number,
|
limit?: number
|
||||||
}
|
} & Partial<Record<string, string | number>>
|
||||||
class OrionBlockchain {
|
class OrionBlockchain {
|
||||||
private readonly apiUrl: string;
|
private readonly apiUrl: string;
|
||||||
|
|
||||||
@@ -110,12 +110,12 @@ class OrionBlockchain {
|
|||||||
return `${this.apiUrl}/`;
|
return `${this.apiUrl}/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSummaryRedeem = (brokerAddress: string, unshifted?: 1 | 0, sourceNetworkCode?: typeof networkCodes[number]) => {
|
private readonly getSummaryRedeem = (brokerAddress: string, unshifted?: 1 | 0, sourceNetworkCode?: typeof networkCodes[number]) => {
|
||||||
const url = new URL(`${this.apiUrl}/api/atomic/summary-redeem/${brokerAddress}`);
|
const url = new URL(`${this.apiUrl}/api/atomic/summary-redeem/${brokerAddress}`);
|
||||||
if (unshifted) {
|
if (unshifted !== undefined && unshifted === 1) {
|
||||||
url.searchParams.append('unshifted', unshifted.toString());
|
url.searchParams.append('unshifted', unshifted.toString());
|
||||||
}
|
}
|
||||||
if (sourceNetworkCode) {
|
if (sourceNetworkCode !== undefined) {
|
||||||
url.searchParams.append('sourceNetworkCode', sourceNetworkCode);
|
url.searchParams.append('sourceNetworkCode', sourceNetworkCode);
|
||||||
}
|
}
|
||||||
return fetchWithValidation(
|
return fetchWithValidation(
|
||||||
@@ -124,12 +124,12 @@ class OrionBlockchain {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
private getSummaryClaim = (brokerAddress: string) => fetchWithValidation(
|
private readonly getSummaryClaim = (brokerAddress: string) => fetchWithValidation(
|
||||||
`${this.apiUrl}/api/atomic/summary-claim/${brokerAddress}`,
|
`${this.apiUrl}/api/atomic/summary-claim/${brokerAddress}`,
|
||||||
atomicSummarySchema,
|
atomicSummarySchema,
|
||||||
);
|
);
|
||||||
|
|
||||||
private getQueueLength = () => fetchWithValidation(
|
private readonly getQueueLength = () => fetchWithValidation(
|
||||||
`${this.apiUrl}/api/queueLength`,
|
`${this.apiUrl}/api/queueLength`,
|
||||||
z.number().int(),
|
z.number().int(),
|
||||||
);
|
);
|
||||||
@@ -357,7 +357,10 @@ class OrionBlockchain {
|
|||||||
const url = new URL(`${this.apiUrl}/api/atomic/history/`);
|
const url = new URL(`${this.apiUrl}/api/atomic/history/`);
|
||||||
|
|
||||||
Object.entries(query)
|
Object.entries(query)
|
||||||
.forEach(([key, value]) => url.searchParams.append(key, value.toString()));
|
.forEach(([key, value]) => {
|
||||||
|
if (value === undefined) throw new Error('Value must be defined');
|
||||||
|
url.searchParams.append(key, value.toString());
|
||||||
|
});
|
||||||
|
|
||||||
return fetchWithValidation(url.toString(), atomicHistorySchema);
|
return fetchWithValidation(url.toString(), atomicHistorySchema);
|
||||||
};
|
};
|
||||||
@@ -366,9 +369,12 @@ class OrionBlockchain {
|
|||||||
const url = new URL(`${this.apiUrl}/api/atomic/history/`);
|
const url = new URL(`${this.apiUrl}/api/atomic/history/`);
|
||||||
|
|
||||||
Object.entries(query)
|
Object.entries(query)
|
||||||
.forEach(([key, value]) => url.searchParams.append(key, value.toString()));
|
.forEach(([key, value]) => {
|
||||||
|
if (value === undefined) throw new Error('Value must be defined');
|
||||||
|
url.searchParams.append(key, value.toString());
|
||||||
|
});
|
||||||
|
|
||||||
if (!query.type) url.searchParams.append('type', 'source');
|
if (query.type !== undefined) url.searchParams.append('type', 'source');
|
||||||
|
|
||||||
return fetchWithValidation(url.toString(), sourceAtomicHistorySchema);
|
return fetchWithValidation(url.toString(), sourceAtomicHistorySchema);
|
||||||
};
|
};
|
||||||
@@ -377,9 +383,12 @@ class OrionBlockchain {
|
|||||||
const url = new URL(`${this.apiUrl}/api/atomic/history/`);
|
const url = new URL(`${this.apiUrl}/api/atomic/history/`);
|
||||||
|
|
||||||
Object.entries(query)
|
Object.entries(query)
|
||||||
.forEach(([key, value]) => url.searchParams.append(key, value.toString()));
|
.forEach(([key, value]) => {
|
||||||
|
if (value === undefined) throw new Error('Value must be defined');
|
||||||
|
url.searchParams.append(key, value.toString());
|
||||||
|
});
|
||||||
|
|
||||||
if (!query.type) url.searchParams.append('type', 'target');
|
if (query.type !== undefined) url.searchParams.append('type', 'target');
|
||||||
|
|
||||||
return fetchWithValidation(url.toString(), targetAtomicHistorySchema);
|
return fetchWithValidation(url.toString(), targetAtomicHistorySchema);
|
||||||
};
|
};
|
||||||
@@ -406,7 +415,10 @@ class OrionBlockchain {
|
|||||||
const url = new URL(`${this.apiUrl}/api/cfd/deposit-withdraw/${address}`);
|
const url = new URL(`${this.apiUrl}/api/cfd/deposit-withdraw/${address}`);
|
||||||
|
|
||||||
Object.entries(query)
|
Object.entries(query)
|
||||||
.forEach(([key, value]) => url.searchParams.append(key, value.toString()));
|
.forEach(([key, value]) => {
|
||||||
|
if (value === undefined) throw new Error('Value must be defined');
|
||||||
|
url.searchParams.append(key, value.toString());
|
||||||
|
});
|
||||||
|
|
||||||
return fetchWithValidation(url.toString(), cfdHistorySchema);
|
return fetchWithValidation(url.toString(), cfdHistorySchema);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import fetchWithValidation from '../../fetchWithValidation';
|
import fetchWithValidation from '../../fetchWithValidation';
|
||||||
import { Exchange } from '../../types';
|
import { type Exchange } from '../../types';
|
||||||
import { statisticsOverviewSchema, topPairsStatisticsSchema } from './schemas';
|
import { statisticsOverviewSchema, topPairsStatisticsSchema } from './schemas';
|
||||||
import candlesSchema from './schemas/candlesSchema';
|
import candlesSchema from './schemas/candlesSchema';
|
||||||
import { PriceFeedWS } from './ws';
|
import { PriceFeedWS } from './ws';
|
||||||
|
|
||||||
class PriceFeed {
|
class PriceFeed {
|
||||||
private apiUrl: string;
|
private readonly apiUrl: string;
|
||||||
|
|
||||||
readonly ws: PriceFeedWS;
|
readonly ws: PriceFeedWS;
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import { tickerInfoSchema, candleSchema } from './schemas';
|
|||||||
import priceSchema from './schemas/priceSchema';
|
import priceSchema from './schemas/priceSchema';
|
||||||
|
|
||||||
type TickerInfo = {
|
type TickerInfo = {
|
||||||
pairName: string;
|
pairName: string
|
||||||
lastPrice: string;
|
lastPrice: string
|
||||||
openPrice: string;
|
openPrice: string
|
||||||
highPrice: string;
|
highPrice: string
|
||||||
lowPrice: string;
|
lowPrice: string
|
||||||
volume24h: string;
|
volume24h: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const allTickersSchema = z.unknown().array()
|
const allTickersSchema = z.unknown().array()
|
||||||
@@ -57,10 +57,10 @@ export type Subscription<
|
|||||||
Schema = z.infer<typeof subscriptions[T]['schema']>
|
Schema = z.infer<typeof subscriptions[T]['schema']>
|
||||||
> = typeof subscriptions[T] extends { payload: true }
|
> = typeof subscriptions[T] extends { payload: true }
|
||||||
? {
|
? {
|
||||||
callback: (data: Schema) => void,
|
callback: (data: Schema) => void
|
||||||
payload: string,
|
payload: string
|
||||||
} : {
|
} : {
|
||||||
callback: (data: Schema) => void,
|
callback: (data: Schema) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class PriceFeedSubscription<T extends SubscriptionType = SubscriptionType> {
|
export default class PriceFeedSubscription<T extends SubscriptionType = SubscriptionType> {
|
||||||
@@ -104,16 +104,23 @@ export default class PriceFeedSubscription<T extends SubscriptionType = Subscrip
|
|||||||
this.isClosedIntentionally = false;
|
this.isClosedIntentionally = false;
|
||||||
|
|
||||||
const { payload, url, type } = this;
|
const { payload, url, type } = this;
|
||||||
this.ws = new WebSocket(`${url}/${type}${payload ? `/${payload.toString()}` : ''}`);
|
this.ws = new WebSocket(`${url}/${type}${payload !== undefined ? `/${payload.toString()}` : ''}`);
|
||||||
|
|
||||||
this.ws.onmessage = (e) => {
|
this.ws.onmessage = (e) => {
|
||||||
if (e.data === 'pong') return;
|
const { data } = e;
|
||||||
const json: unknown = JSON.parse(e.data.toString());
|
|
||||||
|
// const isBufferArray = Array.isArray(data);
|
||||||
|
// const isArrayBuffer = data instanceof ArrayBuffer;
|
||||||
|
const isBuffer = Buffer.isBuffer(data);
|
||||||
|
if (!isBuffer) throw new Error('Not a buffer');
|
||||||
|
const dataString = data.toString();
|
||||||
|
if (dataString === 'pong') return;
|
||||||
|
const json: unknown = JSON.parse(dataString);
|
||||||
const subscription = subscriptions[type];
|
const subscription = subscriptions[type];
|
||||||
const parseResult = subscription.schema.safeParse(json);
|
const parseResult = subscription.schema.safeParse(json);
|
||||||
if (parseResult.success === false) {
|
if (!parseResult.success) {
|
||||||
const errorsMessage = parseResult.error.errors.map((error) => `[${error.path.join('.')}] ${error.message}`).join(', ');
|
const errorsMessage = parseResult.error.errors.map((error) => `[${error.path.join('.')}] ${error.message}`).join(', ');
|
||||||
throw new Error(`Can't recognize PriceFeed "${type}" subscription message "${e.data.toString()}": ${errorsMessage}`);
|
throw new Error(`Can't recognize PriceFeed "${type}" subscription message "${dataString}": ${errorsMessage}`);
|
||||||
}
|
}
|
||||||
this.callback(parseResult.data);
|
this.callback(parseResult.data);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import PriceFeedSubscription, { SubscriptionType, Subscription } from './PriceFeedSubscription';
|
import PriceFeedSubscription, { type SubscriptionType, type Subscription } from './PriceFeedSubscription';
|
||||||
|
|
||||||
export * as schemas from './schemas';
|
export * as schemas from './schemas';
|
||||||
export class PriceFeedWS {
|
export class PriceFeedWS {
|
||||||
@@ -11,7 +11,7 @@ export class PriceFeedWS {
|
|||||||
>;
|
>;
|
||||||
}> = {};
|
}> = {};
|
||||||
|
|
||||||
private url: string;
|
private readonly url: string;
|
||||||
|
|
||||||
constructor(url: string) {
|
constructor(url: string) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
@@ -36,7 +36,7 @@ export class PriceFeedWS {
|
|||||||
return {
|
return {
|
||||||
type: sub.type,
|
type: sub.type,
|
||||||
id: sub.id,
|
id: sub.id,
|
||||||
unsubscribe: () => this.unsubscribe(sub.type, sub.id),
|
unsubscribe: () => { this.unsubscribe(sub.type, sub.id); },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,21 +6,21 @@ import globalAnalyticsSchema from './schemas/globalAnalyticsSchema';
|
|||||||
import linkSchema from './schemas/linkSchema';
|
import linkSchema from './schemas/linkSchema';
|
||||||
|
|
||||||
type CreateLinkPayloadType = {
|
type CreateLinkPayloadType = {
|
||||||
referer: string;
|
referer: string
|
||||||
link_option: number;
|
link_option: number
|
||||||
};
|
}
|
||||||
|
|
||||||
type SubscribePayloadType = {
|
type SubscribePayloadType = {
|
||||||
ref_target: string;
|
ref_target: string
|
||||||
referral: string;
|
referral: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SignatureType = {
|
type SignatureType = {
|
||||||
signature: string;
|
signature: string
|
||||||
};
|
}
|
||||||
|
|
||||||
class ReferralSystem {
|
class ReferralSystem {
|
||||||
private apiUrl: string;
|
private readonly apiUrl: string;
|
||||||
|
|
||||||
get api() {
|
get api() {
|
||||||
return this.apiUrl;
|
return this.apiUrl;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Schema, z } from 'zod';
|
import { type Schema, type z } from 'zod';
|
||||||
import fetchWithValidation from './fetchWithValidation';
|
import fetchWithValidation from './fetchWithValidation';
|
||||||
|
|
||||||
// https://stackoverflow.com/a/64919133
|
// https://stackoverflow.com/a/64919133
|
||||||
|
|||||||
324
src/types.ts
324
src/types.ts
@@ -1,117 +1,117 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import type BigNumber from 'bignumber.js';
|
||||||
import exchanges from './constants/exchanges';
|
import type exchanges from './constants/exchanges';
|
||||||
import subOrderStatuses from './constants/subOrderStatuses';
|
import type subOrderStatuses from './constants/subOrderStatuses';
|
||||||
import positionStatuses from './constants/positionStatuses';
|
import type positionStatuses from './constants/positionStatuses';
|
||||||
|
|
||||||
export type DeepPartial<T> = T extends object ? {
|
export type DeepPartial<T> = T extends object ? {
|
||||||
[P in keyof T]?: DeepPartial<T[P]>;
|
[P in keyof T]?: DeepPartial<T[P]>;
|
||||||
} : T;
|
} : T;
|
||||||
|
|
||||||
export type AssetPairUpdate = {
|
export type AssetPairUpdate = {
|
||||||
minQty: number,
|
minQty: number
|
||||||
pricePrecision: number,
|
pricePrecision: number
|
||||||
}
|
}
|
||||||
export type SubOrder = {
|
export type SubOrder = {
|
||||||
pair: string,
|
pair: string
|
||||||
exchange: string,
|
exchange: string
|
||||||
id: number,
|
id: number
|
||||||
amount: number,
|
amount: number
|
||||||
settledAmount: number,
|
settledAmount: number
|
||||||
price: number,
|
price: number
|
||||||
status: typeof subOrderStatuses[number],
|
status: typeof subOrderStatuses[number]
|
||||||
side: 'BUY' | 'SELL',
|
side: 'BUY' | 'SELL'
|
||||||
subOrdQty: number
|
subOrdQty: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Balance = {
|
export type Balance = {
|
||||||
tradable: string,
|
tradable: string
|
||||||
reserved: string,
|
reserved: string
|
||||||
contract: string,
|
contract: string
|
||||||
wallet: string,
|
wallet: string
|
||||||
allowance: string,
|
allowance: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PositionStatus = typeof positionStatuses[number];
|
export type PositionStatus = typeof positionStatuses[number];
|
||||||
|
|
||||||
export type CFDBalance = {
|
export type CFDBalance = {
|
||||||
instrument: string,
|
instrument: string
|
||||||
balance: string,
|
balance: string
|
||||||
profitLoss: string,
|
profitLoss: string
|
||||||
fundingRate: string,
|
fundingRate: string
|
||||||
equity: string,
|
equity: string
|
||||||
position: string,
|
position: string
|
||||||
currentPrice: string,
|
currentPrice: string
|
||||||
positionPrice: string,
|
positionPrice: string
|
||||||
reserves: string,
|
reserves: string
|
||||||
margin: string,
|
margin: string
|
||||||
marginUSD: string,
|
marginUSD: string
|
||||||
freeMarginUSD: string,
|
freeMarginUSD: string
|
||||||
availableWithdrawBalance: string,
|
availableWithdrawBalance: string
|
||||||
leverage: string,
|
leverage: string
|
||||||
status: PositionStatus,
|
status: PositionStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Order {
|
export type Order = {
|
||||||
senderAddress: string; // address
|
senderAddress: string // address
|
||||||
matcherAddress: string; // address
|
matcherAddress: string // address
|
||||||
baseAsset: string; // address
|
baseAsset: string // address
|
||||||
quoteAsset: string; // address
|
quoteAsset: string // address
|
||||||
matcherFeeAsset: string; // address
|
matcherFeeAsset: string // address
|
||||||
amount: number; // uint64
|
amount: number // uint64
|
||||||
price: number; // uint64
|
price: number // uint64
|
||||||
matcherFee: number; // uint64
|
matcherFee: number // uint64
|
||||||
nonce: number; // uint64
|
nonce: number // uint64
|
||||||
expiration: number; // uint64
|
expiration: number // uint64
|
||||||
buySide: number; // uint8, 1=buy, 0=sell
|
buySide: 0 | 1 // uint8, 1=buy, 0=sell
|
||||||
isPersonalSign: boolean; // bool
|
isPersonalSign: boolean // bool
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CFDOrder {
|
export type CFDOrder = {
|
||||||
senderAddress: string; // address
|
senderAddress: string // address
|
||||||
matcherAddress: string; // address
|
matcherAddress: string // address
|
||||||
instrumentAddress: string; // address
|
instrumentAddress: string // address
|
||||||
amount: number; // uint64
|
amount: number // uint64
|
||||||
price: number; // uint64
|
price: number // uint64
|
||||||
matcherFee: number; // uint64
|
matcherFee: number // uint64
|
||||||
nonce: number; // uint64
|
nonce: number // uint64
|
||||||
expiration: number; // uint64
|
expiration: number // uint64
|
||||||
buySide: number; // uint8, 1=buy, 0=sell
|
buySide: 0 | 1 // uint8, 1=buy, 0=sell
|
||||||
isPersonalSign: boolean; // bool
|
isPersonalSign: boolean // bool
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SignedCFDOrder extends CFDOrder {
|
export type SignedCFDOrder = {
|
||||||
id: string; // hash of Order (it's not part of order structure in smart-contract)
|
id: string // hash of Order (it's not part of order structure in smart-contract)
|
||||||
signature: string; // bytes
|
signature: string // bytes
|
||||||
|
} & CFDOrder
|
||||||
|
|
||||||
|
export type SignedOrder = {
|
||||||
|
id: string // hash of Order (it's not part of order structure in smart-contract)
|
||||||
|
signature: string // bytes
|
||||||
|
needWithdraw?: boolean // bool (not supported yet by smart-contract)
|
||||||
|
} & Order
|
||||||
|
|
||||||
|
export type CancelOrderRequest = {
|
||||||
|
id: number | string
|
||||||
|
senderAddress: string
|
||||||
|
isPersonalSign: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SignedOrder extends Order {
|
export type SignedCancelOrderRequest = {
|
||||||
id: string; // hash of Order (it's not part of order structure in smart-contract)
|
id: number | string
|
||||||
signature: string; // bytes
|
senderAddress: string
|
||||||
needWithdraw?: boolean; // bool (not supported yet by smart-contract)
|
signature: string
|
||||||
}
|
} & CancelOrderRequest
|
||||||
|
|
||||||
export interface CancelOrderRequest {
|
export type Pair = {
|
||||||
id: number | string;
|
name: string
|
||||||
senderAddress: string;
|
baseCurrency: string
|
||||||
isPersonalSign: boolean;
|
quoteCurrency: string
|
||||||
}
|
lastPrice: string
|
||||||
|
openPrice: string
|
||||||
export interface SignedCancelOrderRequest extends CancelOrderRequest {
|
change24h: string
|
||||||
id: number | string;
|
high: string
|
||||||
senderAddress: string;
|
low: string
|
||||||
signature: string;
|
vol24h: string
|
||||||
}
|
|
||||||
|
|
||||||
export interface Pair {
|
|
||||||
name: string;
|
|
||||||
baseCurrency: string;
|
|
||||||
quoteCurrency: string;
|
|
||||||
lastPrice: string;
|
|
||||||
openPrice: string;
|
|
||||||
change24h: string;
|
|
||||||
high: string;
|
|
||||||
low: string;
|
|
||||||
vol24h: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SupportedChainId {
|
export enum SupportedChainId {
|
||||||
@@ -135,114 +135,114 @@ const balanceTypes = ['exchange', 'wallet'] as const;
|
|||||||
|
|
||||||
export type Source = typeof balanceTypes[number];
|
export type Source = typeof balanceTypes[number];
|
||||||
export type Asset = {
|
export type Asset = {
|
||||||
name: string;
|
name: string
|
||||||
address: string;
|
address: string
|
||||||
}
|
}
|
||||||
export type BalanceRequirement = {
|
export type BalanceRequirement = {
|
||||||
readonly reason: string,
|
readonly reason: string
|
||||||
readonly asset: Asset,
|
readonly asset: Asset
|
||||||
readonly amount: string,
|
readonly amount: string
|
||||||
readonly sources: Source[],
|
readonly sources: Source[]
|
||||||
readonly spenderAddress?: string;
|
readonly spenderAddress?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AggregatedBalanceRequirement = {
|
export type AggregatedBalanceRequirement = {
|
||||||
readonly asset: Asset,
|
readonly asset: Asset
|
||||||
readonly sources: Source[],
|
readonly sources: Source[]
|
||||||
readonly spenderAddress?: string;
|
readonly spenderAddress?: string
|
||||||
items: Partial<Record<string, string>>,
|
items: Partial<Record<string, string>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ApproveFix = {
|
export type ApproveFix = {
|
||||||
readonly type: 'byApprove',
|
readonly type: 'byApprove'
|
||||||
readonly targetAmount: BigNumber.Value,
|
readonly targetAmount: BigNumber.Value
|
||||||
readonly spenderAddress: string
|
readonly spenderAddress: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DepositFix = {
|
export type DepositFix = {
|
||||||
readonly type: 'byDeposit',
|
readonly type: 'byDeposit'
|
||||||
readonly amount: BigNumber.Value,
|
readonly amount: BigNumber.Value
|
||||||
readonly asset: string
|
readonly asset: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Fix = ApproveFix | DepositFix;
|
type Fix = ApproveFix | DepositFix;
|
||||||
|
|
||||||
export type BalanceIssue = {
|
export type BalanceIssue = {
|
||||||
readonly asset: Asset,
|
readonly asset: Asset
|
||||||
readonly message: string;
|
readonly message: string
|
||||||
readonly sources: Source[],
|
readonly sources: Source[]
|
||||||
readonly fixes?: Fix[],
|
readonly fixes?: Fix[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Exchange = typeof exchanges[number];
|
export type Exchange = typeof exchanges[number];
|
||||||
|
|
||||||
export type OrderbookItem = {
|
export type OrderbookItem = {
|
||||||
price: string,
|
price: string
|
||||||
amount: string,
|
amount: string
|
||||||
exchanges: Exchange[],
|
exchanges: Exchange[]
|
||||||
vob: {
|
vob: Array<{
|
||||||
side: 'BUY' | 'SELL',
|
side: 'BUY' | 'SELL'
|
||||||
pairName: string
|
pairName: string
|
||||||
}[]
|
}>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SwapInfoAlternative = {
|
export type SwapInfoAlternative = {
|
||||||
exchanges: Exchange[],
|
exchanges: Exchange[]
|
||||||
path: string[],
|
path: string[]
|
||||||
marketAmountOut?: number,
|
marketAmountOut?: number
|
||||||
marketAmountIn?: number,
|
marketAmountIn?: number
|
||||||
marketPrice: number,
|
marketPrice: number
|
||||||
availableAmountIn?: number,
|
availableAmountIn?: number
|
||||||
availableAmountOut?: number,
|
availableAmountOut?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SwapInfoBase = {
|
export type SwapInfoBase = {
|
||||||
swapRequestId: string,
|
swapRequestId: string
|
||||||
assetIn: string,
|
assetIn: string
|
||||||
assetOut: string,
|
assetOut: string
|
||||||
amountIn: number,
|
amountIn: number
|
||||||
amountOut: number,
|
amountOut: number
|
||||||
minAmountIn: number,
|
minAmountIn: number
|
||||||
minAmountOut: number,
|
minAmountOut: number
|
||||||
|
|
||||||
path: string[],
|
path: string[]
|
||||||
exchanges?: Exchange[],
|
exchanges?: Exchange[]
|
||||||
poolOptimal: boolean,
|
poolOptimal: boolean
|
||||||
|
|
||||||
price?: number,
|
price?: number
|
||||||
marketPrice?: number,
|
marketPrice?: number
|
||||||
orderInfo?: {
|
orderInfo?: {
|
||||||
pair: string,
|
pair: string
|
||||||
side: 'BUY' | 'SELL',
|
side: 'BUY' | 'SELL'
|
||||||
amount: number,
|
amount: number
|
||||||
safePrice: number,
|
safePrice: number
|
||||||
},
|
}
|
||||||
alternatives: SwapInfoAlternative[],
|
alternatives: SwapInfoAlternative[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SwapInfoByAmountIn = SwapInfoBase & {
|
export type SwapInfoByAmountIn = SwapInfoBase & {
|
||||||
kind: 'exactSpend',
|
kind: 'exactSpend'
|
||||||
availableAmountIn?: number,
|
availableAmountIn?: number
|
||||||
marketAmountOut?: number,
|
marketAmountOut?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SwapInfoByAmountOut = SwapInfoBase & {
|
export type SwapInfoByAmountOut = SwapInfoBase & {
|
||||||
kind: 'exactReceive',
|
kind: 'exactReceive'
|
||||||
marketAmountIn?: number,
|
marketAmountIn?: number
|
||||||
availableAmountOut?: number,
|
availableAmountOut?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SwapInfo = SwapInfoByAmountIn | SwapInfoByAmountOut;
|
export type SwapInfo = SwapInfoByAmountIn | SwapInfoByAmountOut;
|
||||||
|
|
||||||
export type FuturesTradeInfo = {
|
export type FuturesTradeInfo = {
|
||||||
futuresTradeRequestId: string,
|
futuresTradeRequestId: string
|
||||||
sender: string,
|
sender: string
|
||||||
instrument: string,
|
instrument: string
|
||||||
buyPrice: number,
|
buyPrice: number
|
||||||
sellPrice: number,
|
sellPrice: number
|
||||||
buyPower: number,
|
buyPower: number
|
||||||
sellPower: number,
|
sellPower: number
|
||||||
minAmount: number,
|
minAmount: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum HistoryTransactionStatus {
|
export enum HistoryTransactionStatus {
|
||||||
@@ -255,30 +255,30 @@ export enum HistoryTransactionStatus {
|
|||||||
export type VerboseOrionUnitConfig = {
|
export type VerboseOrionUnitConfig = {
|
||||||
// env?: string;
|
// env?: string;
|
||||||
// api: string;
|
// api: string;
|
||||||
chainId: SupportedChainId;
|
chainId: SupportedChainId
|
||||||
nodeJsonRpc: string;
|
nodeJsonRpc: string
|
||||||
services: {
|
services: {
|
||||||
orionBlockchain: {
|
orionBlockchain: {
|
||||||
http: string;
|
http: string
|
||||||
// For example:
|
// For example:
|
||||||
// http://localhost:3001/,
|
// http://localhost:3001/,
|
||||||
// http://10.123.34.23:3001/,
|
// http://10.123.34.23:3001/,
|
||||||
// https://blockchain.orionprotocol.io/
|
// https://blockchain.orionprotocol.io/
|
||||||
},
|
}
|
||||||
orionAggregator: {
|
orionAggregator: {
|
||||||
http: string;
|
http: string
|
||||||
ws: string;
|
ws: string
|
||||||
// For example:
|
// For example:
|
||||||
// http://localhost:3002/,
|
// http://localhost:3002/,
|
||||||
// http://10.34.23.5:3002/,
|
// http://10.34.23.5:3002/,
|
||||||
// shttps://aggregator.orionprotocol.io/
|
// shttps://aggregator.orionprotocol.io/
|
||||||
},
|
}
|
||||||
priceFeed: {
|
priceFeed: {
|
||||||
api: string;
|
api: string
|
||||||
// For example:
|
// For example:
|
||||||
// http://localhost:3003/,
|
// http://localhost:3003/,
|
||||||
// http://10.23.5.11:3003/,
|
// http://10.23.5.11:3003/,
|
||||||
// https://price-feed.orionprotocol.io/
|
// https://price-feed.orionprotocol.io/
|
||||||
},
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable camelcase */
|
|
||||||
import { ERC20__factory } from '@orionprotocol/contracts';
|
import { ERC20__factory } from '@orionprotocol/contracts';
|
||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import invariant from 'tiny-invariant';
|
import invariant from 'tiny-invariant';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { type ethers } from 'ethers';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts normalized blockchain ("machine-readable") number to denormalized ("human-readable") number.
|
* Converts normalized blockchain ("machine-readable") number to denormalized ("human-readable") number.
|
||||||
@@ -9,6 +9,6 @@ import { ethers } from 'ethers';
|
|||||||
*/
|
*/
|
||||||
export default function denormalizeNumber(input: ethers.BigNumber, decimals: BigNumber.Value) {
|
export default function denormalizeNumber(input: ethers.BigNumber, decimals: BigNumber.Value) {
|
||||||
const decimalsBN = new BigNumber(decimals);
|
const decimalsBN = new BigNumber(decimals);
|
||||||
if (!decimalsBN.isInteger()) throw new Error(`Decimals '${decimals.toString()}' is not an integer`);
|
if (!decimalsBN.isInteger()) throw new Error(`Decimals '${decimalsBN.toString()}' is not an integer`);
|
||||||
return new BigNumber(input.toString()).div(new BigNumber(10).pow(decimalsBN));
|
return new BigNumber(input.toString()).div(new BigNumber(10).pow(decimalsBN));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { Source } from '../types';
|
import { type Source } from '../types';
|
||||||
|
|
||||||
export default function getAvailableFundsSources(
|
export default function getAvailableFundsSources(
|
||||||
expenseType: 'amount' | 'network_fee' | 'orion_fee',
|
expenseType: 'amount' | 'network_fee' | 'orion_fee',
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { ERC20__factory, Exchange } from '@orionprotocol/contracts';
|
import { ERC20__factory, type Exchange } from '@orionprotocol/contracts';
|
||||||
|
|
||||||
import BigNumber from 'bignumber.js';
|
import type BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { utils } from '..';
|
|
||||||
import { INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION } from '../constants';
|
import { INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION } from '../constants';
|
||||||
import { OrionAggregator } from '../services/OrionAggregator';
|
import { type OrionAggregator } from '../services/OrionAggregator';
|
||||||
|
import denormalizeNumber from './denormalizeNumber';
|
||||||
|
|
||||||
export default async function getBalance(
|
export default async function getBalance(
|
||||||
orionAggregator: OrionAggregator,
|
orionAggregator: OrionAggregator,
|
||||||
@@ -25,13 +25,13 @@ export default async function getBalance(
|
|||||||
const assetDecimals = await assetContract.decimals();
|
const assetDecimals = await assetContract.decimals();
|
||||||
assetWalletBalance = await assetContract.balanceOf(walletAddress);
|
assetWalletBalance = await assetContract.balanceOf(walletAddress);
|
||||||
|
|
||||||
denormalizedAssetInWalletBalance = utils.denormalizeNumber(assetWalletBalance, assetDecimals);
|
denormalizedAssetInWalletBalance = denormalizeNumber(assetWalletBalance, assetDecimals);
|
||||||
} else {
|
} else {
|
||||||
assetWalletBalance = await provider.getBalance(walletAddress);
|
assetWalletBalance = await provider.getBalance(walletAddress);
|
||||||
denormalizedAssetInWalletBalance = utils.denormalizeNumber(assetWalletBalance, NATIVE_CURRENCY_PRECISION);
|
denormalizedAssetInWalletBalance = denormalizeNumber(assetWalletBalance, NATIVE_CURRENCY_PRECISION);
|
||||||
}
|
}
|
||||||
const assetContractBalance = await exchangeContract.getBalance(assetAddress, walletAddress);
|
const assetContractBalance = await exchangeContract.getBalance(assetAddress, walletAddress);
|
||||||
const denormalizedAssetInContractBalance = utils.denormalizeNumber(assetContractBalance, INTERNAL_ORION_PRECISION);
|
const denormalizedAssetInContractBalance = denormalizeNumber(assetContractBalance, INTERNAL_ORION_PRECISION);
|
||||||
const denormalizedAssetLockedBalanceResult = await orionAggregator.getLockedBalance(walletAddress, asset);
|
const denormalizedAssetLockedBalanceResult = await orionAggregator.getLockedBalance(walletAddress, asset);
|
||||||
if (denormalizedAssetLockedBalanceResult.isErr()) {
|
if (denormalizedAssetLockedBalanceResult.isErr()) {
|
||||||
throw new Error(denormalizedAssetLockedBalanceResult.error.message);
|
throw new Error(denormalizedAssetLockedBalanceResult.error.message);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Exchange } from '@orionprotocol/contracts';
|
import { type Exchange } from '@orionprotocol/contracts';
|
||||||
import BigNumber from 'bignumber.js';
|
import type BigNumber from 'bignumber.js';
|
||||||
import { ethers } from 'ethers';
|
import { type ethers } from 'ethers';
|
||||||
import { OrionAggregator } from '../services/OrionAggregator';
|
import { type OrionAggregator } from '../services/OrionAggregator';
|
||||||
import getBalance from './getBalance';
|
import getBalance from './getBalance';
|
||||||
|
|
||||||
export default async (
|
export default async (
|
||||||
@@ -14,7 +14,7 @@ export default async (
|
|||||||
const balances = await Promise.all(
|
const balances = await Promise.all(
|
||||||
Object.entries(balancesRequired)
|
Object.entries(balancesRequired)
|
||||||
.map(async ([asset, assetAddress]) => {
|
.map(async ([asset, assetAddress]) => {
|
||||||
if (!assetAddress) throw new Error(`Asset address of ${asset} not found`);
|
if (assetAddress === undefined) throw new Error(`Asset address of ${asset} not found`);
|
||||||
const balance = await getBalance(
|
const balance = await getBalance(
|
||||||
orionAggregator,
|
orionAggregator,
|
||||||
asset,
|
asset,
|
||||||
@@ -31,8 +31,8 @@ export default async (
|
|||||||
);
|
);
|
||||||
|
|
||||||
return balances.reduce<Partial<Record<string, {
|
return balances.reduce<Partial<Record<string, {
|
||||||
exchange: BigNumber,
|
exchange: BigNumber
|
||||||
wallet: BigNumber,
|
wallet: BigNumber
|
||||||
}>>>((prev, curr) => ({
|
}>>>((prev, curr) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[curr.asset]: curr.amount,
|
[curr.asset]: curr.amount,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const getNativeCryptocurrency = (assetToAddress: Partial<Record<string, string>>
|
|||||||
const addressToAsset = Object
|
const addressToAsset = Object
|
||||||
.entries(assetToAddress)
|
.entries(assetToAddress)
|
||||||
.reduce<Partial<Record<string, string>>>((prev, [asset, address]) => {
|
.reduce<Partial<Record<string, string>>>((prev, [asset, address]) => {
|
||||||
if (!address) return prev;
|
if (address === undefined) return prev;
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
[address]: asset,
|
[address]: asset,
|
||||||
@@ -12,7 +12,7 @@ const getNativeCryptocurrency = (assetToAddress: Partial<Record<string, string>>
|
|||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const nativeCryptocurrency = addressToAsset[ethers.constants.AddressZero];
|
const nativeCryptocurrency = addressToAsset[ethers.constants.AddressZero];
|
||||||
if (!nativeCryptocurrency) throw new Error('Native cryptocurrency asset is not found');
|
if (nativeCryptocurrency === undefined) throw new Error('Native cryptocurrency asset is not found');
|
||||||
return nativeCryptocurrency;
|
return nativeCryptocurrency;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default class HttpError extends Error {
|
|||||||
public type: string;
|
public type: string;
|
||||||
|
|
||||||
constructor(code: number, message: string | null, type: string, statusText: string) {
|
constructor(code: number, message: string | null, type: string, statusText: string) {
|
||||||
super(message || '');
|
super(message ?? '');
|
||||||
this.errorMessage = message;
|
this.errorMessage = message;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.statusText = statusText;
|
this.statusText = statusText;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export { default as parseExchangeTradeTransaction } from './parseExchangeTradeTr
|
|||||||
export { default as toUpperCase } from './toUpperCase';
|
export { default as toUpperCase } from './toUpperCase';
|
||||||
export { default as toLowerCase } from './toLowerCase';
|
export { default as toLowerCase } from './toLowerCase';
|
||||||
export { default as isUppercasedNetworkCode } from './isUppercasedNetworkCode';
|
export { default as isUppercasedNetworkCode } from './isUppercasedNetworkCode';
|
||||||
|
export { default as getNativeCryptocurrency } from './getNativeCryptocurrency';
|
||||||
|
|
||||||
// export { default as HttpError } from './httpError';
|
// export { default as HttpError } from './httpError';
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export default function isNetworkCodeInEnvironment(networkCode: string, env: str
|
|||||||
}
|
}
|
||||||
const envInfo = envs[env];
|
const envInfo = envs[env];
|
||||||
const envNetworks = envInfo?.networks;
|
const envNetworks = envInfo?.networks;
|
||||||
if (envNetworks === undefined) throw new Error('Env networks is undefined (isNetworkCodeInEnvironment)');
|
if (!envNetworks) throw new Error('Env networks is undefined (isNetworkCodeInEnvironment)');
|
||||||
|
|
||||||
return Object.values(chains)
|
return Object.values(chains)
|
||||||
.some((chain) => chain.code.toLowerCase() === networkCode.toLowerCase() &&
|
.some((chain) => chain.code.toLowerCase() === networkCode.toLowerCase() &&
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default function normalizeNumber(
|
|||||||
roundingMode: BigNumber.RoundingMode,
|
roundingMode: BigNumber.RoundingMode,
|
||||||
) {
|
) {
|
||||||
const decimalsBN = new BigNumber(decimals);
|
const decimalsBN = new BigNumber(decimals);
|
||||||
if (!decimalsBN.isInteger()) throw new Error(`Decimals '${decimals.toString()}' is not an integer`);
|
if (!decimalsBN.isInteger()) throw new Error(`Decimals '${decimalsBN.toString()}' is not an integer`);
|
||||||
const inputBN = new BigNumber(input);
|
const inputBN = new BigNumber(input);
|
||||||
return ethers.BigNumber.from(
|
return ethers.BigNumber.from(
|
||||||
inputBN
|
inputBN
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ const untypedItems = Object.keys(items); // => Array<string>
|
|||||||
@category Type guard
|
@category Type guard
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
export const objectKeys = Object.keys as <Type extends object>(value: Type) => ObjectKeys<Type>[];
|
export const objectKeys = Object.keys as <Type extends object>(value: Type) => Array<ObjectKeys<Type>>;
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
type WithReason = {
|
type WithReason = {
|
||||||
reason: string;
|
reason: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type WithCodeError = Error & {
|
type WithCodeError = Error & {
|
||||||
code: number | string;
|
code: number | string
|
||||||
}
|
}
|
||||||
|
|
||||||
type WithMessage = {
|
type WithMessage = {
|
||||||
message: string;
|
message: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type WithDataError = Error & {
|
type WithDataError = Error & {
|
||||||
data: Record<string, unknown>;
|
data: Record<string, unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
type WithError = {
|
type WithError = {
|
||||||
error: Record<string | number | symbol, unknown>;
|
error: Record<string | number | symbol, unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const makePartial = <Key extends string | number | symbol, Value>(value: Record<Key, Value>): Partial<Record<Key, Value>> => value;
|
export const makePartial = <Key extends string | number | symbol, Value>(value: Record<Key, Value>): Partial<Record<Key, Value>> => value;
|
||||||
|
|||||||
Reference in New Issue
Block a user