@galacticcouncil/sdk 0.0.1-beta.1 → 0.0.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{dist/cjs → cjs}/hydra_dx_wasm_bg-ZX7K4FM7.wasm +0 -0
- package/{dist/cjs → cjs}/index.js +0 -0
- package/{dist/cjs → cjs}/index.js.map +0 -0
- package/{dist/esm → esm}/hydra_dx_wasm_bg-ZX7K4FM7.wasm +0 -0
- package/{dist/esm → esm}/index.js +0 -0
- package/{dist/esm → esm}/index.js.map +0 -0
- package/package.json +3 -2
- package/{dist/types → types}/api/index.d.ts +0 -0
- package/{dist/types → types}/api/router.d.ts +0 -0
- package/{dist/types → types}/api/trader.d.ts +0 -0
- package/{dist/types → types}/client/capi.d.ts +0 -0
- package/{dist/types → types}/client/index.d.ts +0 -0
- package/{dist/types → types}/client/polkadot.d.ts +0 -0
- package/{dist/types → types}/client/types.d.ts +0 -0
- package/{dist/types → types}/index.d.ts +0 -0
- package/{dist/types → types}/pool/index.d.ts +0 -0
- package/{dist/types → types}/pool/polkadotPoolService.d.ts +0 -0
- package/{dist/types → types}/pool/poolFactory.d.ts +0 -0
- package/{dist/types → types}/pool/xyk/math/bundler.d.ts +0 -0
- package/{dist/types → types}/pool/xyk/math/nodejs.d.ts +0 -0
- package/{dist/types → types}/pool/xyk/xykPolkadotClient.d.ts +0 -0
- package/{dist/types → types}/pool/xyk/xykPool.d.ts +0 -0
- package/{dist/types → types}/suggester/bfs.d.ts +0 -0
- package/{dist/types → types}/suggester/graph.d.ts +0 -0
- package/{dist/types → types}/suggester/index.d.ts +0 -0
- package/{dist/types → types}/suggester/suggester.d.ts +0 -0
- package/{dist/types → types}/types.d.ts +0 -0
- package/{dist/types → types}/utils/bignumber.d.ts +0 -0
- package/{dist/types → types}/utils/math.d.ts +0 -0
- package/{dist/types → types}/utils/queue.d.ts +0 -0
- package/{dist/types → types}/utils/stack.d.ts +0 -0
- package/{dist/types → types}/utils/traversal/bfs.d.ts +0 -0
- package/.eslintignore +0 -1
- package/.eslintrc.json +0 -20
- package/.nvmrc +0 -1
- package/.prettierrc.json +0 -12
- package/.vscode/settings.json +0 -15
- package/README.md +0 -101
- package/esbuild.mjs +0 -36
- package/jest.config.mjs +0 -16
- package/src/api/index.ts +0 -1
- package/src/api/router.ts +0 -359
- package/src/api/trader.ts +0 -0
- package/src/client/capi.ts +0 -0
- package/src/client/index.ts +0 -1
- package/src/client/polkadot.ts +0 -47
- package/src/client/types.ts +0 -8
- package/src/index.ts +0 -4
- package/src/pool/index.ts +0 -3
- package/src/pool/polkadotPoolService.ts +0 -19
- package/src/pool/poolFactory.ts +0 -14
- package/src/pool/xyk/math/bundler.ts +0 -19
- package/src/pool/xyk/math/nodejs.ts +0 -19
- package/src/pool/xyk/xykPolkadotClient.ts +0 -58
- package/src/pool/xyk/xykPool.ts +0 -82
- package/src/suggester/bfs.ts +0 -106
- package/src/suggester/graph.ts +0 -31
- package/src/suggester/index.ts +0 -3
- package/src/suggester/suggester.ts +0 -66
- package/src/types.ts +0 -61
- package/src/utils/bignumber.ts +0 -25
- package/src/utils/math.ts +0 -24
- package/src/utils/queue.ts +0 -26
- package/src/utils/stack.ts +0 -31
- package/src/utils/traversal/bfs.ts +0 -74
- package/test/api/router.spec.ts +0 -87
- package/test/data/xykPool.ts +0 -21
- package/test/data/xykPools.ts +0 -61
- package/test/lib/mockXykPoolService.ts +0 -8
- package/test/pool/xyk/xykPool.spec.ts +0 -26
- package/test/script/examples/router/getAllAssets.ts +0 -14
- package/test/script/examples/router/getAllPaths.ts +0 -14
- package/test/script/examples/router/getAssetPairs.ts +0 -14
- package/test/script/examples/router/getBestBuyPrice.ts +0 -19
- package/test/script/examples/router/getBestSellPrice.ts +0 -19
- package/test/script/executor.ts +0 -45
- package/test/suggester/bfs.spec.ts +0 -34
- package/test/suggester/graph.spec.ts +0 -30
- package/test/suggester/suggester.spec.ts +0 -25
- package/test/utils/traversal/bfs.spec.ts +0 -28
- package/tsconfig.json +0 -14
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@galacticcouncil/sdk",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Galactic SDK",
|
|
6
6
|
"author": "Pavol Noha <palo@hydradx.io>",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "jest",
|
|
12
12
|
"build": "node ./esbuild.mjs && tsc --emitDeclarationOnly --outDir dist/types/",
|
|
13
|
-
"cleanup": "rimraf out && rimraf dist"
|
|
13
|
+
"cleanup": "rimraf out && rimraf dist",
|
|
14
|
+
"publish": "cp ./package.json ./dist/package.json && cd dist && npm publish"
|
|
14
15
|
},
|
|
15
16
|
"devDependencies": {
|
|
16
17
|
"@types/jest": "^28.1.8",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/.eslintignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
node_modules/
|
package/.eslintrc.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"root": true,
|
|
3
|
-
"env": {
|
|
4
|
-
"browser": true,
|
|
5
|
-
"es6": true,
|
|
6
|
-
"node": true
|
|
7
|
-
},
|
|
8
|
-
"plugins": [
|
|
9
|
-
"es",
|
|
10
|
-
"prettier",
|
|
11
|
-
"promise"
|
|
12
|
-
],
|
|
13
|
-
"extends": [
|
|
14
|
-
"prettier",
|
|
15
|
-
"plugin:promise/recommended"
|
|
16
|
-
],
|
|
17
|
-
"rules": {
|
|
18
|
-
"prettier/prettier": "error"
|
|
19
|
-
}
|
|
20
|
-
}
|
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
18
|
package/.prettierrc.json
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"trailingComma": "es5",
|
|
3
|
-
"printWidth": 80,
|
|
4
|
-
"tabWidth": 2,
|
|
5
|
-
"singleQuote": true,
|
|
6
|
-
"bracketSpacing": true,
|
|
7
|
-
"arrowParens": "always",
|
|
8
|
-
"semi": true,
|
|
9
|
-
"newline-before-return": true,
|
|
10
|
-
"no-duplicate-variable": [true, "check-parameters"],
|
|
11
|
-
"no-var-keyword": true
|
|
12
|
-
}
|
package/.vscode/settings.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"[jsonc]": {
|
|
3
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
4
|
-
},
|
|
5
|
-
"[yaml]": {
|
|
6
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
7
|
-
},
|
|
8
|
-
"[typescript]": {
|
|
9
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
10
|
-
},
|
|
11
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
12
|
-
"editor.formatOnSave": true,
|
|
13
|
-
"editor.tabSize": 2,
|
|
14
|
-
"prettier.printWidth": 100
|
|
15
|
-
}
|
package/README.md
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
<h1><code>Galactic SDK</code></h1>
|
|
2
|
-
Galactic SDK is collection of components crafted to ease Basilisk & HydraDX chains integration.
|
|
3
|
-
<br />
|
|
4
|
-
<br />
|
|
5
|
-
Table of content:
|
|
6
|
-
|
|
7
|
-
- [Components](#components)
|
|
8
|
-
- [Router](#router)
|
|
9
|
-
- [Trader](#trader)
|
|
10
|
-
- [Examples](#examples)
|
|
11
|
-
- [Packaging](#packaging)
|
|
12
|
-
- [Roadmap](#roadmap)
|
|
13
|
-
- [Issue reporting](#issue-reporting)
|
|
14
|
-
|
|
15
|
-
## Components
|
|
16
|
-
|
|
17
|
-
### Router
|
|
18
|
-
|
|
19
|
-
Off-chain optimization of orders across pools for best price execution. Router does not perform any on-chain transations.
|
|
20
|
-
|
|
21
|
-
#### API
|
|
22
|
-
|
|
23
|
-
```typescript
|
|
24
|
-
getPools(): PoolBase[]
|
|
25
|
-
getAllAssets(): PoolAsset[]
|
|
26
|
-
getAssetPairs(token: string): PoolAsset[]
|
|
27
|
-
getAllPaths(tokenIn: string, tokenOut: string): Hop[][]
|
|
28
|
-
getBestSellPrice(tokenIn: string, tokenOut: string, amountIn: BigNumber): Swap[]
|
|
29
|
-
getBestBuyPrice(tokenIn: string, tokenOut: string, amountOut: BigNumber): Swap[]
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
For type signature visit [types.ts](src/types.ts)<br />
|
|
33
|
-
**Note:** All amount args are formatted as bignumber 1^12!!!
|
|
34
|
-
|
|
35
|
-
#### Usage
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
// Import
|
|
39
|
-
import { ApiPromise, WsProvider } from '@polkadot/api';
|
|
40
|
-
import { PolkadotPoolService } from '@galactic/pool';
|
|
41
|
-
import { Router } from '@galactic/api';
|
|
42
|
-
|
|
43
|
-
// Initialize Polkadot API
|
|
44
|
-
const wsProvider = new WsProvider('wss://rpc.basilisk.cloud');
|
|
45
|
-
const api = await ApiPromise.create({ provider: wsProvider });
|
|
46
|
-
|
|
47
|
-
// Initialize Router
|
|
48
|
-
const poolService = new PolkadotPoolService(api);
|
|
49
|
-
const router = new Router(poolService);
|
|
50
|
-
|
|
51
|
-
// Do something
|
|
52
|
-
const result = await router.getAllAssets();
|
|
53
|
-
console.log(result);
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Trader
|
|
57
|
-
|
|
58
|
-
On-chain transaction executor using data from router to perform best possible trade.
|
|
59
|
-
|
|
60
|
-
Not supported yet. 🛠
|
|
61
|
-
|
|
62
|
-
## Examples
|
|
63
|
-
|
|
64
|
-
SDK Examples and testing helpers.
|
|
65
|
-
|
|
66
|
-
### Run
|
|
67
|
-
|
|
68
|
-
Run: `$ npx tsx ./test/script/examples/${{examplePackage}}/${{exampleName}}.ts` with valid example package & name.
|
|
69
|
-
|
|
70
|
-
To demonstrate full working examples on real chain see [script](test/script/examples) section.
|
|
71
|
-
|
|
72
|
-
## Packaging
|
|
73
|
-
|
|
74
|
-
- api - Router & Trader impl
|
|
75
|
-
- client - Substrate chain based clients
|
|
76
|
-
- pool - Pool specific logic, math, clients
|
|
77
|
-
- suggester - Route proposing, graph utils, BFS, DFS
|
|
78
|
-
- utils - bignumber, math, collections
|
|
79
|
-
|
|
80
|
-
## Roadmap
|
|
81
|
-
|
|
82
|
-
Component list and current status ⬇️
|
|
83
|
-
|
|
84
|
-
- 🧪 Done
|
|
85
|
-
- 🛠 Work in progress
|
|
86
|
-
- ⏳ Planning to build
|
|
87
|
-
|
|
88
|
-
| Name | Type | |
|
|
89
|
-
| -------- | :----: | --: |
|
|
90
|
-
| Router | API | 🧪 |
|
|
91
|
-
| Trader | API | 🛠 |
|
|
92
|
-
| Polkadot | Client | 🧪 |
|
|
93
|
-
| Capi | Client | ⏳ |
|
|
94
|
-
| XYK | Pool | 🧪 |
|
|
95
|
-
| LBP | Pool | ⏳ |
|
|
96
|
-
| Stable | Pool | ⏳ |
|
|
97
|
-
| Omni | Pool | ⏳ |
|
|
98
|
-
|
|
99
|
-
## Issue reporting
|
|
100
|
-
|
|
101
|
-
In case of unexpected sdk behaviour, please create well-written issue [here](https://https://github.com/nohaapav/router-sdk/issues/new). It makes it easier to find & fix the problem accordingly.
|
package/esbuild.mjs
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import esbuild from 'esbuild';
|
|
2
|
-
import resolve from 'esbuild-plugin-resolve';
|
|
3
|
-
import { wasmLoader } from 'esbuild-plugin-wasm';
|
|
4
|
-
|
|
5
|
-
// ESM bundle
|
|
6
|
-
esbuild
|
|
7
|
-
.build({
|
|
8
|
-
entryPoints: ['src/index.ts'],
|
|
9
|
-
outdir: 'dist/esm',
|
|
10
|
-
bundle: true,
|
|
11
|
-
sourcemap: true,
|
|
12
|
-
minify: true,
|
|
13
|
-
splitting: true,
|
|
14
|
-
plugins: [
|
|
15
|
-
resolve({
|
|
16
|
-
'./math/nodejs': './math/bundler',
|
|
17
|
-
}),
|
|
18
|
-
wasmLoader({ mode: 'deferred' }),
|
|
19
|
-
],
|
|
20
|
-
format: 'esm',
|
|
21
|
-
target: ['esnext'],
|
|
22
|
-
})
|
|
23
|
-
.catch(() => process.exit(1));
|
|
24
|
-
|
|
25
|
-
// CJS bundle
|
|
26
|
-
esbuild
|
|
27
|
-
.build({
|
|
28
|
-
entryPoints: ['src/index.ts'],
|
|
29
|
-
outfile: 'dist/cjs/index.js',
|
|
30
|
-
bundle: true,
|
|
31
|
-
sourcemap: true,
|
|
32
|
-
minify: true,
|
|
33
|
-
platform: 'node',
|
|
34
|
-
target: ['node18'],
|
|
35
|
-
})
|
|
36
|
-
.catch(() => process.exit(1));
|
package/jest.config.mjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
roots: ['<rootDir>/test'],
|
|
3
|
-
modulePaths: ['<rootDir>'],
|
|
4
|
-
moduleDirectories: ['node_modules'],
|
|
5
|
-
moduleNameMapper: {},
|
|
6
|
-
testMatch: ['**/__tests__/**/*.+(ts|js)', '**/?(*.)+(spec|test).+(ts|js)'],
|
|
7
|
-
transform: {
|
|
8
|
-
'^.+\\.(ts)$': 'es-jest',
|
|
9
|
-
},
|
|
10
|
-
collectCoverageFrom: ['**/*.{js,ts}', '!**/*.d.ts', '!**/node_modules/**'],
|
|
11
|
-
globals: {
|
|
12
|
-
'ts-jest': {
|
|
13
|
-
tsconfig: 'tsconfig.json',
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
};
|
package/src/api/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Router } from './router';
|
package/src/api/router.ts
DELETED
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
import { PoolService, PoolBase, Hop, Pool, PoolAsset, Swap } from '../types';
|
|
2
|
-
import { RouteSuggester } from '../suggester';
|
|
3
|
-
import { Edge } from '../suggester';
|
|
4
|
-
import { PoolFactory } from '../pool';
|
|
5
|
-
import { BigNumber } from '../utils/bignumber';
|
|
6
|
-
import { calculateTradeFee } from '../utils/math';
|
|
7
|
-
|
|
8
|
-
export class Router {
|
|
9
|
-
private readonly routeSuggester: RouteSuggester;
|
|
10
|
-
private readonly poolService: PoolService;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @param poolService - Fetch pool data from substrate based pools
|
|
14
|
-
*/
|
|
15
|
-
constructor(poolService: PoolService) {
|
|
16
|
-
this.poolService = poolService;
|
|
17
|
-
this.routeSuggester = new RouteSuggester();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Return all pools
|
|
22
|
-
*
|
|
23
|
-
* @returns {PoolBase[]} List of all substrate based pools
|
|
24
|
-
*/
|
|
25
|
-
getPools(): Promise<PoolBase[]> {
|
|
26
|
-
return this.poolService.getPools();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Return list of all available assets from substrate based pools
|
|
31
|
-
*
|
|
32
|
-
* @returns {PoolAsset[]} List of all available assets
|
|
33
|
-
*/
|
|
34
|
-
async getAllAssets(): Promise<PoolAsset[]> {
|
|
35
|
-
const asset = await this.getAssets();
|
|
36
|
-
return [...new Map(asset).values()];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Calculate and return list of all assets, given token can be trade with
|
|
41
|
-
*
|
|
42
|
-
* @param {string} token - Storage key of token
|
|
43
|
-
* @returns {PoolAsset[]} List of all available assets, given token can be trade with
|
|
44
|
-
*/
|
|
45
|
-
async getAssetPairs(token: string): Promise<PoolAsset[]> {
|
|
46
|
-
const pools = await this.poolService.getPools();
|
|
47
|
-
if (pools.length === 0) return [];
|
|
48
|
-
const { assets, poolsMap } = await this.validateToken(token, pools);
|
|
49
|
-
const hops = this.getPaths(token, null, poolsMap, pools);
|
|
50
|
-
const dest = hops.map((hop) => hop[hop.length - 1].tokenOut);
|
|
51
|
-
return this.toPoolAssets([...new Set(dest)], assets);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Calculate and return all possible paths for best swap tokenIn>tokenOut
|
|
56
|
-
*
|
|
57
|
-
* @param {string} tokenIn - Storage key of tokenIn
|
|
58
|
-
* @param {string} tokenOut - Storage key of tokenOut
|
|
59
|
-
* @returns {<Hop[][]>} All possible paths containing route hops
|
|
60
|
-
*/
|
|
61
|
-
async getAllPaths(tokenIn: string, tokenOut: string): Promise<Hop[][]> {
|
|
62
|
-
const pools = await this.poolService.getPools();
|
|
63
|
-
if (pools.length === 0) return [];
|
|
64
|
-
const { poolsMap } = await this.validateTokenPair(tokenIn, tokenOut, pools);
|
|
65
|
-
return this.getPaths(tokenIn, tokenOut, poolsMap, pools);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Calculate and return best possible sell price for tokenIn>tokenOut
|
|
70
|
-
*
|
|
71
|
-
* @param {string} tokenIn - Storage key of tokenIn
|
|
72
|
-
* @param {string} tokenOut - Storage key of tokenOut
|
|
73
|
-
* @param {BigNumber} amountIn - Amount of tokenIn to sell for tokenOut
|
|
74
|
-
* @returns Best possible swaps(sells) of given token pair
|
|
75
|
-
*/
|
|
76
|
-
async getBestSellPrice(
|
|
77
|
-
tokenIn: string,
|
|
78
|
-
tokenOut: string,
|
|
79
|
-
amountIn: BigNumber
|
|
80
|
-
): Promise<Swap[]> {
|
|
81
|
-
const pools = await this.poolService.getPools();
|
|
82
|
-
if (pools.length === 0) return [];
|
|
83
|
-
const { poolsMap } = await this.validateTokenPair(tokenIn, tokenOut, pools);
|
|
84
|
-
const paths = this.getPaths(tokenIn, tokenOut, poolsMap, pools);
|
|
85
|
-
const swaps = paths.map((path) =>
|
|
86
|
-
this.toSellSwaps(amountIn, path, poolsMap)
|
|
87
|
-
);
|
|
88
|
-
const sorted = swaps.sort((a, b) => {
|
|
89
|
-
const swapAFinal = a[a.length - 1].returnFinalAmount;
|
|
90
|
-
const swapBFinal = b[b.length - 1].returnFinalAmount;
|
|
91
|
-
return swapAFinal.isGreaterThan(swapBFinal) ? -1 : 1;
|
|
92
|
-
});
|
|
93
|
-
return sorted[0];
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Calculate and return sell swaps for given path
|
|
98
|
-
* - final amount of previous swap is entry to next one
|
|
99
|
-
*
|
|
100
|
-
* @param amountIn - Amount of tokenIn to sell for tokenOut
|
|
101
|
-
* @param path - current path
|
|
102
|
-
* @param poolsMap - pools map
|
|
103
|
-
* @returns Sell swaps for given path
|
|
104
|
-
*/
|
|
105
|
-
private toSellSwaps(
|
|
106
|
-
amountIn: BigNumber,
|
|
107
|
-
path: Hop[],
|
|
108
|
-
poolsMap: Map<string, Pool>
|
|
109
|
-
): Swap[] {
|
|
110
|
-
const swaps: Swap[] = [];
|
|
111
|
-
for (let i = 0; i < path.length; i++) {
|
|
112
|
-
const hop = path[i];
|
|
113
|
-
const pool = poolsMap.get(hop.poolId);
|
|
114
|
-
if (pool == null) throw new Error('Pool does not exit');
|
|
115
|
-
|
|
116
|
-
let aIn: BigNumber;
|
|
117
|
-
if (i > 0) {
|
|
118
|
-
aIn = swaps[i - 1].returnFinalAmount;
|
|
119
|
-
} else {
|
|
120
|
-
aIn = amountIn;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const poolPair = pool.parsePoolPair(hop.tokenIn, hop.tokenOut);
|
|
124
|
-
const calculated = pool.calculateOutGivenIn(poolPair, aIn);
|
|
125
|
-
const fee = calculateTradeFee(calculated, poolPair.swapFee);
|
|
126
|
-
const spotPrice = pool.getSpotPriceOut(poolPair);
|
|
127
|
-
|
|
128
|
-
swaps.push({
|
|
129
|
-
...hop,
|
|
130
|
-
swapAmount: aIn,
|
|
131
|
-
returnAmount: calculated,
|
|
132
|
-
returnFinalAmount: calculated.minus(fee),
|
|
133
|
-
swapFee: fee,
|
|
134
|
-
spotPrice: spotPrice,
|
|
135
|
-
} as Swap);
|
|
136
|
-
}
|
|
137
|
-
return swaps;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Calculate and return best possible buy price for tokenIn>tokenOut
|
|
142
|
-
*
|
|
143
|
-
* @param {string} tokenIn - Storage key of tokenIn
|
|
144
|
-
* @param {string} tokenOut - Storage key of tokenOut
|
|
145
|
-
* @param {BigNumber} amountOut - Amount of tokenOut to buy for tokenIn
|
|
146
|
-
* @returns Best possible swaps(buys) of given token pair
|
|
147
|
-
*/
|
|
148
|
-
async getBestBuyPrice(
|
|
149
|
-
tokenIn: string,
|
|
150
|
-
tokenOut: string,
|
|
151
|
-
amountOut: BigNumber
|
|
152
|
-
): Promise<Swap[]> {
|
|
153
|
-
const pools = await this.poolService.getPools();
|
|
154
|
-
if (pools.length === 0) return [];
|
|
155
|
-
const { poolsMap } = await this.validateTokenPair(tokenIn, tokenOut, pools);
|
|
156
|
-
const paths = this.getPaths(tokenIn, tokenOut, poolsMap, pools);
|
|
157
|
-
const swaps = paths.map((path) =>
|
|
158
|
-
this.toBuySwaps(amountOut, path, poolsMap)
|
|
159
|
-
);
|
|
160
|
-
const sorted = swaps.sort((a, b) => {
|
|
161
|
-
const swapAFinal = a[0].returnFinalAmount;
|
|
162
|
-
const swapBFinal = b[0].returnFinalAmount;
|
|
163
|
-
return swapAFinal.isGreaterThan(swapBFinal) ? 1 : -1;
|
|
164
|
-
});
|
|
165
|
-
return sorted[0];
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Calculate and return buy swaps for given path
|
|
170
|
-
* - final amount of previous swap is entry to next one
|
|
171
|
-
* - calculation is done backwards
|
|
172
|
-
*
|
|
173
|
-
* @param amountOut - Amount of tokenOut to buy for tokenIn
|
|
174
|
-
* @param path - current path
|
|
175
|
-
* @param poolsMap - pools map
|
|
176
|
-
* @returns Buy swaps for given path
|
|
177
|
-
*/
|
|
178
|
-
private toBuySwaps(
|
|
179
|
-
amountOut: BigNumber,
|
|
180
|
-
path: Hop[],
|
|
181
|
-
poolsMap: Map<string, Pool>
|
|
182
|
-
): Swap[] {
|
|
183
|
-
const swaps: Swap[] = [];
|
|
184
|
-
for (let i = path.length - 1; i >= 0; i--) {
|
|
185
|
-
const hop = path[i];
|
|
186
|
-
const pool = poolsMap.get(hop.poolId);
|
|
187
|
-
if (pool == null) throw new Error('Pool does not exit');
|
|
188
|
-
|
|
189
|
-
let aOut: BigNumber;
|
|
190
|
-
if (i == path.length - 1) {
|
|
191
|
-
aOut = amountOut;
|
|
192
|
-
} else {
|
|
193
|
-
aOut = swaps[0].returnFinalAmount;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const poolPair = pool.parsePoolPair(hop.tokenIn, hop.tokenOut);
|
|
197
|
-
const calculated = pool.calculateInGivenOut(poolPair, aOut);
|
|
198
|
-
const fee = calculateTradeFee(calculated, poolPair.swapFee);
|
|
199
|
-
const spotPrice = pool.getSpotPriceIn(poolPair);
|
|
200
|
-
|
|
201
|
-
swaps.unshift({
|
|
202
|
-
...hop,
|
|
203
|
-
swapAmount: aOut,
|
|
204
|
-
returnAmount: calculated,
|
|
205
|
-
returnFinalAmount: calculated.plus(fee),
|
|
206
|
-
swapFee: fee,
|
|
207
|
-
spotPrice: spotPrice,
|
|
208
|
-
} as Swap);
|
|
209
|
-
}
|
|
210
|
-
return swaps;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Return map of all available assets from substrate based pools
|
|
215
|
-
*
|
|
216
|
-
* @returns Map of all available assets
|
|
217
|
-
*/
|
|
218
|
-
private async getAssets(): Promise<Map<string, PoolAsset>> {
|
|
219
|
-
const pools = await this.poolService.getPools();
|
|
220
|
-
if (pools.length === 0) return new Map<string, PoolAsset>();
|
|
221
|
-
const assets = pools
|
|
222
|
-
.map((pool: PoolBase) => {
|
|
223
|
-
return pool.tokens.map(({ id, symbol }) => {
|
|
224
|
-
return { token: id, symbol } as PoolAsset;
|
|
225
|
-
});
|
|
226
|
-
})
|
|
227
|
-
.flat();
|
|
228
|
-
return new Map(assets.map((asset) => [asset.token, asset]));
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Calculate and return all possible paths for best swap tokenIn>tokenOut
|
|
233
|
-
*
|
|
234
|
-
* @param tokenIn - Storage key of tokenIn
|
|
235
|
-
* @param tokenOut - Storage key of tokenOut
|
|
236
|
-
* @param poolsMap - pools map
|
|
237
|
-
* @param pools - pools
|
|
238
|
-
* @returns All possible paths containing route hops
|
|
239
|
-
*/
|
|
240
|
-
private getPaths(
|
|
241
|
-
tokenIn: string,
|
|
242
|
-
tokenOut: string | null,
|
|
243
|
-
poolsMap: Map<string, Pool>,
|
|
244
|
-
pools: PoolBase[]
|
|
245
|
-
): Hop[][] {
|
|
246
|
-
const routeProposals = this.routeSuggester.getProposals(
|
|
247
|
-
tokenIn,
|
|
248
|
-
tokenOut,
|
|
249
|
-
pools
|
|
250
|
-
);
|
|
251
|
-
const routes = routeProposals
|
|
252
|
-
.filter((path: Edge[]) => this.validPath(path, poolsMap))
|
|
253
|
-
.map((path: Edge[]) => this.toHops(path, poolsMap));
|
|
254
|
-
return routes;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Ckeck if input asset pair is valid and throw expection if not
|
|
259
|
-
*
|
|
260
|
-
* @param tokenIn - Storage key of tokenIn
|
|
261
|
-
* @param tokenOut - Storage key of tokenOut
|
|
262
|
-
* @returns Pool assets & map
|
|
263
|
-
*/
|
|
264
|
-
private async validateTokenPair(
|
|
265
|
-
tokenIn: string,
|
|
266
|
-
tokenOut: string,
|
|
267
|
-
pools: PoolBase[]
|
|
268
|
-
) {
|
|
269
|
-
const assets = await this.getAssets();
|
|
270
|
-
if (assets.get(tokenIn) == null)
|
|
271
|
-
throw new Error(tokenIn + ' is not supported token');
|
|
272
|
-
if (assets.get(tokenOut) == null)
|
|
273
|
-
throw new Error(tokenOut + ' is not supported token');
|
|
274
|
-
const poolsMap = this.getPoolMap(pools);
|
|
275
|
-
return { assets, poolsMap };
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* Ckeck if input asset is valid and throw expection if not
|
|
280
|
-
*
|
|
281
|
-
* @param token - Storage key of token
|
|
282
|
-
* @returns Pool assets & map
|
|
283
|
-
*/
|
|
284
|
-
private async validateToken(token: string, pools: PoolBase[]) {
|
|
285
|
-
const assets = await this.getAssets();
|
|
286
|
-
if (assets.get(token) == null)
|
|
287
|
-
throw new Error(token + ' is not supported token');
|
|
288
|
-
const poolsMap = this.getPoolMap(pools);
|
|
289
|
-
return { assets, poolsMap };
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Create pool map from substrate based pools
|
|
294
|
-
*/
|
|
295
|
-
private getPoolMap(pools: PoolBase[]): Map<string, Pool> {
|
|
296
|
-
return new Map<string, Pool>(
|
|
297
|
-
pools.map((i) => [i.address, PoolFactory.get(i)])
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Check if path is valid -> all edges are valid token pairs
|
|
303
|
-
*
|
|
304
|
-
* @param proposedPath - proposed path
|
|
305
|
-
* @param poolsMap - pools map
|
|
306
|
-
* @returns only valid paths
|
|
307
|
-
*/
|
|
308
|
-
private validPath(
|
|
309
|
-
proposedPath: Edge[],
|
|
310
|
-
poolsMap: Map<string, Pool>
|
|
311
|
-
): boolean {
|
|
312
|
-
return (
|
|
313
|
-
proposedPath.length > 0 &&
|
|
314
|
-
proposedPath
|
|
315
|
-
.map((edge: Edge) => this.validEdge(edge, poolsMap))
|
|
316
|
-
.reduce((prev, curr) => prev && curr)
|
|
317
|
-
);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Check if edge (token pair) of corresponding pool is valid combination
|
|
322
|
-
*
|
|
323
|
-
* @param edge - current edge (token pair)
|
|
324
|
-
* @param poolsMap - pools map
|
|
325
|
-
* @returns true if edge (token pair) is valid, otherwise false
|
|
326
|
-
*/
|
|
327
|
-
private validEdge(
|
|
328
|
-
[id, from, to]: Edge,
|
|
329
|
-
poolsMap: Map<string, Pool>
|
|
330
|
-
): boolean {
|
|
331
|
-
return poolsMap.get(id)?.validPair(from, to) || false;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
private toHops(path: Edge[], poolsMap: Map<string, Pool>): Hop[] {
|
|
335
|
-
return path.map(([id, from, to]: Edge) => {
|
|
336
|
-
const pool = poolsMap.get(id);
|
|
337
|
-
return {
|
|
338
|
-
poolId: id,
|
|
339
|
-
poolType: pool?.type,
|
|
340
|
-
tokenIn: from,
|
|
341
|
-
tokenOut: to,
|
|
342
|
-
fee: pool?.swapFee,
|
|
343
|
-
} as Hop;
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
private toPoolAssets(
|
|
348
|
-
tokens: string[],
|
|
349
|
-
assets: Map<string, PoolAsset>
|
|
350
|
-
): PoolAsset[] {
|
|
351
|
-
return tokens.map((token) => {
|
|
352
|
-
const asset = assets.get(token);
|
|
353
|
-
return {
|
|
354
|
-
token: token,
|
|
355
|
-
symbol: asset?.symbol,
|
|
356
|
-
} as PoolAsset;
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
}
|
package/src/api/trader.ts
DELETED
|
File without changes
|
package/src/client/capi.ts
DELETED
|
File without changes
|
package/src/client/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { PolkadotClient } from './polkadot';
|