@alcorexchange/alcor-swap-sdk 1.0.1 → 1.0.5

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/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # alcor-v2-sdk
2
+
3
+ ## Installation
4
+ ​​
5
+ **npm**
6
+ ```
7
+ npm i @alcorexchange/alcor-swap-sdk
8
+ ```
9
+ **yarn**
10
+ ```
11
+ yarn add @alcorexchange/alcor-swap-sdk
12
+ ```
13
+ ## Usage
14
+ ### Import:
15
+
16
+ ES6
17
+
18
+ ```js
19
+ import SwapSDK from '@alcorexchange/alcor-swap-sdk'
20
+ ```
21
+
22
+ CommonJS
23
+
24
+ ```js
25
+ const SwapSDK = require('@alcorexchange/alcor-swap-sdk')
26
+ ```
27
+
28
+ ### Initialization:
29
+
30
+ ```ts
31
+ import fetch from 'node-fetch'
32
+
33
+ import { Token, Pool } from '@alcorexchange/alcor-swap-sdk'
34
+
35
+ import { asset } from 'eos-common'
36
+ import { JsonRpc } from 'eosjs'
37
+
38
+ export function parseToken(token) {
39
+ return new Token(
40
+ token.contract,
41
+ asset(token.quantity).symbol.precision(),
42
+ asset(token.quantity).symbol.code().to_string(),
43
+ (asset(token.quantity).symbol.code().to_string() + '-' + token.contract).toLowerCase()
44
+ )
45
+ }
46
+
47
+ const rpc = new JsonRpc('https://waxnode02.alcor.exchange', { fetch });
48
+
49
+ async function main() {
50
+ const { rows } = await rpc.get_table_rows({
51
+ scope: 'swap.alcor',
52
+ table: 'pools',
53
+ code: 'swap.alcor',
54
+ })
55
+
56
+ const { tokenA, tokenB, currSlot: { sqrtPriceX64, tick } } = rows[0]
57
+
58
+ const pool = new Pool({
59
+ ...rows[0],
60
+ tokenA: parseToken(tokenA),
61
+ tokenB: parseToken(tokenB),
62
+ sqrtPriceX64,
63
+ tickCurrent: tick
64
+ })
65
+
66
+ // Do you thing with pool here
67
+ }
68
+ ```
69
+ ## Examples
70
+ The examples can be found in examples/ directory.
@@ -12,6 +12,8 @@ interface PositionConstructorArgs {
12
12
  liquidity: BigintIsh;
13
13
  feeGrowthInsideALastX64: BigintIsh;
14
14
  feeGrowthInsideBLastX64: BigintIsh;
15
+ feesA: BigintIsh;
16
+ feesB: BigintIsh;
15
17
  }
16
18
  interface Fees {
17
19
  feesA: CurrencyAmount<Token>;
@@ -24,6 +26,8 @@ export declare class Position {
24
26
  readonly tickLower: number;
25
27
  readonly tickUpper: number;
26
28
  readonly liquidity: JSBI;
29
+ readonly feesA: JSBI;
30
+ readonly feesB: JSBI;
27
31
  readonly feeGrowthInsideALastX64: JSBI;
28
32
  readonly feeGrowthInsideBLastX64: JSBI;
29
33
  private _tokenAAmount;
@@ -36,7 +40,7 @@ export declare class Position {
36
40
  * @param lower The lower tick of the position
37
41
  * @param upper The upper tick of the position
38
42
  */
39
- constructor({ id, owner, pool, liquidity, tickLower, tickUpper, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, }: PositionConstructorArgs);
43
+ constructor({ id, owner, pool, liquidity, tickLower, tickUpper, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, feesA, feesB, }: PositionConstructorArgs);
40
44
  get inRange(): boolean;
41
45
  /**
42
46
  * Returns the price of tokenA at the lower tick
@@ -100,7 +104,7 @@ export declare class Position {
100
104
  * not what core can theoretically support
101
105
  * @returns The amount of liquidity for the position
102
106
  */
103
- static fromAmounts({ id, owner, pool, tickLower, tickUpper, amountA, amountB, useFullPrecision, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, }: {
107
+ static fromAmounts({ id, owner, pool, tickLower, tickUpper, amountA, amountB, useFullPrecision, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, feesA, feesB }: {
104
108
  id: number;
105
109
  owner: string;
106
110
  pool: Pool;
@@ -111,6 +115,8 @@ export declare class Position {
111
115
  useFullPrecision: boolean;
112
116
  feeGrowthInsideALastX64: BigintIsh;
113
117
  feeGrowthInsideBLastX64: BigintIsh;
118
+ feesA: BigintIsh;
119
+ feesB: BigintIsh;
114
120
  }): Position;
115
121
  /**
116
122
  * Computes a position with the maximum amount of liquidity received for a given amount of tokenA, assuming an unlimited amount of tokenB
@@ -122,7 +128,7 @@ export declare class Position {
122
128
  * not what core can theoretically support
123
129
  * @returns The position
124
130
  */
125
- static fromAmountA({ id, owner, pool, tickLower, tickUpper, amountA, useFullPrecision, feeGrowthInsideALastX64, feeGrowthInsideBLastX64 }: {
131
+ static fromAmountA({ id, owner, pool, tickLower, tickUpper, amountA, useFullPrecision, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, feesA, feesB }: {
126
132
  id: number;
127
133
  owner: string;
128
134
  pool: Pool;
@@ -132,6 +138,8 @@ export declare class Position {
132
138
  useFullPrecision: boolean;
133
139
  feeGrowthInsideALastX64: BigintIsh;
134
140
  feeGrowthInsideBLastX64: BigintIsh;
141
+ feesA: BigintIsh;
142
+ feesB: BigintIsh;
135
143
  }): Position;
136
144
  /**
137
145
  * Computes a position with the maximum amount of liquidity received for a given amount of tokenB, assuming an unlimited amount of tokenA
@@ -141,7 +149,7 @@ export declare class Position {
141
149
  * @param amountB The desired amount of tokenB
142
150
  * @returns The position
143
151
  */
144
- static fromAmountB({ id, owner, pool, tickLower, tickUpper, amountB, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, }: {
152
+ static fromAmountB({ id, owner, pool, tickLower, tickUpper, amountB, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, feesA, feesB }: {
145
153
  id: number;
146
154
  owner: string;
147
155
  pool: Pool;
@@ -150,6 +158,8 @@ export declare class Position {
150
158
  amountB: BigintIsh;
151
159
  feeGrowthInsideALastX64: BigintIsh;
152
160
  feeGrowthInsideBLastX64: BigintIsh;
161
+ feesA: BigintIsh;
162
+ feesB: BigintIsh;
153
163
  }): Position;
154
164
  /**
155
165
  * Computes a position fees
@@ -33,7 +33,7 @@ class Position {
33
33
  * @param lower The lower tick of the position
34
34
  * @param upper The upper tick of the position
35
35
  */
36
- constructor({ id, owner, pool, liquidity, tickLower, tickUpper, feeGrowthInsideALastX64 = 0, feeGrowthInsideBLastX64 = 0, }) {
36
+ constructor({ id, owner, pool, liquidity, tickLower, tickUpper, feeGrowthInsideALastX64 = 0, feeGrowthInsideBLastX64 = 0, feesA = 0, feesB = 0, }) {
37
37
  // cached resuts for the getters
38
38
  this._tokenAAmount = null;
39
39
  this._tokenBAmount = null;
@@ -49,6 +49,8 @@ class Position {
49
49
  this.liquidity = jsbi_1.default.BigInt(liquidity);
50
50
  this.feeGrowthInsideALastX64 = jsbi_1.default.BigInt(feeGrowthInsideALastX64);
51
51
  this.feeGrowthInsideBLastX64 = jsbi_1.default.BigInt(feeGrowthInsideBLastX64);
52
+ this.feesA = jsbi_1.default.BigInt(feesA);
53
+ this.feesB = jsbi_1.default.BigInt(feesB);
52
54
  }
53
55
  get inRange() {
54
56
  return (this.tickLower < this.pool.tickCurrent &&
@@ -156,7 +158,7 @@ class Position {
156
158
  ticks: this.pool.tickDataProvider
157
159
  });
158
160
  // because the router is imprecise, we need to calculate the position that will be created (assuming no slippage)
159
- const positionThatWillBeCreated = Position.fromAmounts(Object.assign(Object.assign({ id: this.id, owner: this.owner, pool: this.pool, tickLower: this.tickLower, tickUpper: this.tickUpper }, this.mintAmounts), { useFullPrecision: false, feeGrowthInsideALastX64: this.feeGrowthInsideALastX64, feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64 }));
161
+ const positionThatWillBeCreated = Position.fromAmounts(Object.assign(Object.assign({ id: this.id, owner: this.owner, pool: this.pool, tickLower: this.tickLower, tickUpper: this.tickUpper }, this.mintAmounts), { useFullPrecision: false, feeGrowthInsideALastX64: this.feeGrowthInsideALastX64, feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64, feesA: this.feesA, feesB: this.feesB }));
160
162
  // we want the smaller amounts...
161
163
  // ...which occurs at the upper price for amountA...
162
164
  const { amountA } = new Position({
@@ -168,6 +170,8 @@ class Position {
168
170
  tickUpper: this.tickUpper,
169
171
  feeGrowthInsideALastX64: this.feeGrowthInsideALastX64,
170
172
  feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64,
173
+ feesA: this.feesA,
174
+ feesB: this.feesB,
171
175
  }).mintAmounts;
172
176
  // ...and the lower for amountB
173
177
  const { amountB } = new Position({
@@ -179,6 +183,8 @@ class Position {
179
183
  tickUpper: this.tickUpper,
180
184
  feeGrowthInsideALastX64: this.feeGrowthInsideALastX64,
181
185
  feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64,
186
+ feesA: this.feesA,
187
+ feesB: this.feesB,
182
188
  }).mintAmounts;
183
189
  return { amountA, amountB };
184
190
  }
@@ -227,6 +233,8 @@ class Position {
227
233
  tickUpper: this.tickUpper,
228
234
  feeGrowthInsideALastX64: this.feeGrowthInsideALastX64,
229
235
  feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64,
236
+ feesA: this.feesA,
237
+ feesB: this.feesB,
230
238
  }).amountA;
231
239
  // ...and the lower for amountB
232
240
  const amountB = new Position({
@@ -238,6 +246,8 @@ class Position {
238
246
  tickUpper: this.tickUpper,
239
247
  feeGrowthInsideALastX64: this.feeGrowthInsideALastX64,
240
248
  feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64,
249
+ feesA: this.feesA,
250
+ feesB: this.feesB,
241
251
  }).amountB;
242
252
  return { amountA: amountA, amountB: amountB };
243
253
  }
@@ -280,7 +290,7 @@ class Position {
280
290
  * not what core can theoretically support
281
291
  * @returns The amount of liquidity for the position
282
292
  */
283
- static fromAmounts({ id, owner, pool, tickLower, tickUpper, amountA, amountB, useFullPrecision, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, }) {
293
+ static fromAmounts({ id, owner, pool, tickLower, tickUpper, amountA, amountB, useFullPrecision, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, feesA, feesB }) {
284
294
  const sqrtRatioLX64 = tickMath_1.TickMath.getSqrtRatioAtTick(tickLower);
285
295
  const sqrtRatioUX64 = tickMath_1.TickMath.getSqrtRatioAtTick(tickUpper);
286
296
  return new Position({
@@ -291,7 +301,9 @@ class Position {
291
301
  tickUpper,
292
302
  liquidity: (0, maxLiquidityForAmounts_1.maxLiquidityForAmounts)(pool.sqrtPriceX64, sqrtRatioLX64, sqrtRatioUX64, amountA, amountB, useFullPrecision),
293
303
  feeGrowthInsideALastX64,
294
- feeGrowthInsideBLastX64
304
+ feeGrowthInsideBLastX64,
305
+ feesA,
306
+ feesB
295
307
  });
296
308
  }
297
309
  /**
@@ -304,7 +316,7 @@ class Position {
304
316
  * not what core can theoretically support
305
317
  * @returns The position
306
318
  */
307
- static fromAmountA({ id, owner, pool, tickLower, tickUpper, amountA, useFullPrecision, feeGrowthInsideALastX64, feeGrowthInsideBLastX64 }) {
319
+ static fromAmountA({ id, owner, pool, tickLower, tickUpper, amountA, useFullPrecision, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, feesA, feesB }) {
308
320
  return Position.fromAmounts({
309
321
  id,
310
322
  owner,
@@ -315,7 +327,9 @@ class Position {
315
327
  amountB: internalConstants_1.MaxUint64,
316
328
  useFullPrecision,
317
329
  feeGrowthInsideALastX64,
318
- feeGrowthInsideBLastX64
330
+ feeGrowthInsideBLastX64,
331
+ feesA,
332
+ feesB
319
333
  });
320
334
  }
321
335
  /**
@@ -326,7 +340,7 @@ class Position {
326
340
  * @param amountB The desired amount of tokenB
327
341
  * @returns The position
328
342
  */
329
- static fromAmountB({ id, owner, pool, tickLower, tickUpper, amountB, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, }) {
343
+ static fromAmountB({ id, owner, pool, tickLower, tickUpper, amountB, feeGrowthInsideALastX64, feeGrowthInsideBLastX64, feesA, feesB }) {
330
344
  // this function always uses full precision,
331
345
  return Position.fromAmounts({
332
346
  id,
@@ -339,6 +353,8 @@ class Position {
339
353
  useFullPrecision: true,
340
354
  feeGrowthInsideALastX64,
341
355
  feeGrowthInsideBLastX64,
356
+ feesA,
357
+ feesB
342
358
  });
343
359
  }
344
360
  /**
@@ -355,8 +371,8 @@ class Position {
355
371
  const tokensOwedA = jsbi_1.default.divide(jsbi_1.default.multiply((0, utils_1.subIn128)(feeGrowthInsideAX64, feeGrowthInsideALastX64), liquidity), internalConstants_1.Q64);
356
372
  const tokensOwedB = jsbi_1.default.divide(jsbi_1.default.multiply((0, utils_1.subIn128)(feeGrowthInsideBX64, feeGrowthInsideBLastX64), liquidity), internalConstants_1.Q64);
357
373
  return {
358
- feesA: fractions_1.CurrencyAmount.fromRawAmount(this.pool.tokenA, tokensOwedA),
359
- feesB: fractions_1.CurrencyAmount.fromRawAmount(this.pool.tokenB, tokensOwedB),
374
+ feesA: fractions_1.CurrencyAmount.fromRawAmount(this.pool.tokenA, jsbi_1.default.add(tokensOwedA, this.feesA)),
375
+ feesB: fractions_1.CurrencyAmount.fromRawAmount(this.pool.tokenB, jsbi_1.default.add(tokensOwedB, this.feesB))
360
376
  };
361
377
  });
362
378
  }
@@ -0,0 +1,45 @@
1
+ import fetch from 'node-fetch'
2
+
3
+ // Alcor v2 sdk: https://github.com/alcorexchange/alcor-v2-sdk
4
+ import { Token, Pool } from '../src'
5
+
6
+ import { asset } from 'eos-common'
7
+ import { JsonRpc } from 'eosjs'
8
+
9
+ export function parseToken(token) {
10
+ return new Token(
11
+ token.contract,
12
+ asset(token.quantity).symbol.precision(),
13
+ asset(token.quantity).symbol.code().to_string(),
14
+ (asset(token.quantity).symbol.code().to_string() + '-' + token.contract).toLowerCase()
15
+ )
16
+ }
17
+
18
+ const rpc = new JsonRpc('https://waxnode02.alcor.exchange', { fetch });
19
+
20
+ async function main() {
21
+ const { rows } = await rpc.get_table_rows({
22
+ scope: 'swap.alcor',
23
+ table: 'pools',
24
+ code: 'swap.alcor',
25
+ })
26
+
27
+ // First pool for example
28
+ const { tokenA, tokenB, currSlot: { sqrtPriceX64, tick } } = rows[0]
29
+
30
+ const pool = new Pool({
31
+ ...rows[0],
32
+ tokenA: parseToken(tokenA),
33
+ tokenB: parseToken(tokenB),
34
+ sqrtPriceX64,
35
+ tickCurrent: tick
36
+ })
37
+
38
+ console.log('priceA', pool.tokenAPrice.toFixed())
39
+ console.log('priceB', pool.tokenBPrice.toFixed())
40
+ }
41
+
42
+ main()
43
+
44
+ //priceA 0.2820
45
+ //priceB 3.5466
@@ -0,0 +1,105 @@
1
+ import fetch from 'node-fetch'
2
+
3
+ // Alcor v2 sdk: https://github.com/alcorexchange/alcor-v2-sdk
4
+ import { Token, Position, Pool } from '../src'
5
+ import { fetchAllRows } from './utils/rpc'
6
+
7
+ import { asset } from 'eos-common'
8
+ import { JsonRpc } from 'eosjs'
9
+ import { Serialize } from 'eosjs'
10
+
11
+
12
+ export function parseToken(token) {
13
+ return new Token(
14
+ token.contract,
15
+ asset(token.quantity).symbol.precision(),
16
+ asset(token.quantity).symbol.code().to_string(),
17
+ (asset(token.quantity).symbol.code().to_string() + '-' + token.contract).toLowerCase()
18
+ )
19
+ }
20
+
21
+ const rpc = new JsonRpc('https://wax-api.alcor.exchange', { fetch });
22
+
23
+ const types: any = Serialize.createInitialTypes()
24
+
25
+ export const nameToUint64 = (name) => {
26
+ const ser = new Serialize.SerialBuffer()
27
+ ser.pushName(name)
28
+ return types.get('uint64').deserialize(ser)
29
+ }
30
+
31
+ async function main() {
32
+ const account = '3mob2.wam'
33
+
34
+ const pools = await fetchAllRows(rpc, {
35
+ scope: 'swap.alcor',
36
+ table: 'pools',
37
+ code: 'swap.alcor',
38
+ })
39
+
40
+ // First pool for example (TLM / WAX)
41
+ // const poolRow= pools[0]
42
+
43
+ // Or Specific pool
44
+ const poolRow= pools.find(p => p.id == 205)
45
+
46
+ //const { id, tokenA, tokenB, currSlot: { sqrtPriceX64, tick } } = poolRow
47
+
48
+ // Or Specific pool
49
+ const { id, tokenA, tokenB, currSlot: { sqrtPriceX64, tick } } = poolRow
50
+
51
+ const ticks = await fetchAllRows(rpc, {
52
+ scope: id,
53
+ table: 'ticks',
54
+ code: 'swap.alcor',
55
+ })
56
+
57
+ const pool = new Pool({
58
+ ...poolRow,
59
+ tokenA: parseToken(tokenA),
60
+ tokenB: parseToken(tokenB),
61
+ sqrtPriceX64,
62
+ tickCurrent: tick,
63
+ ticks: ticks.sort((a, b) => a.id - b.id)
64
+ })
65
+
66
+ // const { rows: positions } = await rpc.get_table_rows({
67
+ // scope: pool.id,
68
+ // table: 'positions',
69
+ // code: 'swap.alcor',
70
+ // key_type: 'i64',
71
+ // index_position: 3,
72
+ // lower_bound: nameToUint64(account),
73
+ // upper_bound: nameToUint64(account)
74
+ // })
75
+
76
+ // or Specific position by id
77
+ const { rows: positions } = await rpc.get_table_rows({
78
+ scope: pool.id,
79
+ table: 'positions',
80
+ code: 'swap.alcor',
81
+ lower_bound: 14235,
82
+ upper_bound: 14235
83
+ })
84
+
85
+ //console.log({ pool: pool.id, positions })
86
+
87
+ const position = new Position({
88
+ ...positions[0], // Only first of account position
89
+ pool
90
+ })
91
+
92
+ // console.log('amountA:', position.amountA.toAsset())
93
+ // console.log('amountB:', position.amountB.toAsset())
94
+
95
+ // fees:
96
+ const { feesA, feesB } = await position.getFees()
97
+
98
+ console.log('feesA', feesA.toAsset())
99
+ console.log('feesB', feesB.toAsset())
100
+ }
101
+
102
+ main()
103
+
104
+ // amountA: 103.4332 TLM
105
+ // amountB: 29.16056021 WAX
@@ -0,0 +1,95 @@
1
+ import fetch from 'node-fetch'
2
+ import { fetchAllRows } from './utils/rpc'
3
+
4
+ // Alcor v2 sdk: https://github.com/alcorexchange/alcor-v2-sdk
5
+ import { Token, Pool, Trade, CurrencyAmount, Percent } from '../src'
6
+
7
+ import { asset } from 'eos-common'
8
+ import { JsonRpc } from 'eosjs'
9
+
10
+ export function parseToken(token) {
11
+ return new Token(
12
+ token.contract,
13
+ asset(token.quantity).symbol.precision(),
14
+ asset(token.quantity).symbol.code().to_string(),
15
+ (asset(token.quantity).symbol.code().to_string() + '-' + token.contract).toLowerCase()
16
+ )
17
+ }
18
+
19
+ const rpc = new JsonRpc('https://eos-api.alcor.exchange', { fetch });
20
+
21
+ async function main() {
22
+ const rows = await fetchAllRows(rpc, {
23
+ scope: 'swap.alcor',
24
+ table: 'pools',
25
+ code: 'swap.alcor',
26
+ })
27
+
28
+ const pools: Pool[] = []
29
+
30
+ // We have to get all pools with fetched ticks for them
31
+ for (const p of rows) {
32
+ const { id, tokenA, tokenB, currSlot: { sqrtPriceX64, tick } } = p
33
+
34
+ const ticks = await fetchAllRows(rpc, {
35
+ scope: id,
36
+ table: 'ticks',
37
+ code: 'swap.alcor',
38
+ })
39
+
40
+ pools.push(new Pool({
41
+ ...p,
42
+ tokenA: parseToken(tokenA),
43
+ tokenB: parseToken(tokenB),
44
+ sqrtPriceX64,
45
+ tickCurrent: tick,
46
+ ticks: ticks.sort((a, b) => a.id - b.id)
47
+ }))
48
+ }
49
+
50
+ // 1.0000 EOS
51
+ const amountIn = CurrencyAmount.fromRawAmount(new Token('eosio.token', 4, 'EOS'), 1_0000)
52
+ const tokenOut = new Token('tethertether', 4, 'USDT')
53
+ const slippage = new Percent(3, 100) // 0.3%
54
+ const receiver = 'myaccount'
55
+
56
+ // First trade sorted by biggest output
57
+ const [trade] = await Trade.bestTradeExactIn(pools, amountIn, tokenOut, { maxHops: 3 })
58
+
59
+ const route = trade.route.pools.map(p => p.id)
60
+
61
+ const maxSent = trade.inputAmount
62
+ const minReceived = trade.minimumAmountOut(slippage)
63
+
64
+ // Memo Format <Service Name>#<Pool ID's>#<Recipient>#<Output Token>#<Deadline>
65
+ const memo = `swapexactin#${route.join(',')}#${receiver}#${minReceived.toExtendedAsset()}#0`
66
+
67
+ const result = {
68
+ input: trade.inputAmount.toFixed(),
69
+ output: trade.outputAmount.toFixed(),
70
+ minReceived: minReceived.toFixed(),
71
+ maxSent: maxSent.toFixed(),
72
+ priceImpact: trade.priceImpact.toSignificant(2),
73
+ memo,
74
+ route,
75
+ executionPrice: {
76
+ numerator: trade.executionPrice.numerator.toString(),
77
+ denominator: trade.executionPrice.denominator.toString()
78
+ }
79
+ }
80
+
81
+ console.log(result)
82
+ }
83
+
84
+ main()
85
+
86
+ // {
87
+ // input: '1.0000',
88
+ // output: '1.0314 USDT',
89
+ // minReceived: '1.0013',
90
+ // maxSent: '1.0000',
91
+ // priceImpact: '0.44',
92
+ // memo: 'swapexactin#2#myaccount#1.0013 USDT@tethertether#0',
93
+ // route: [ 2 ],
94
+ // executionPrice: { numerator: '10314', denominator: '10000' }
95
+ // }
@@ -0,0 +1,39 @@
1
+ const MAX_PAGINATION_FETCHES = 99
2
+
3
+ export const fetchAllRows =
4
+ async (rpc, options, indexName = 'id'): Promise<any> => {
5
+ const mergedOptions = {
6
+ json: true,
7
+ lower_bound: 0,
8
+ upper_bound: undefined,
9
+ limit: 9999,
10
+ ...options
11
+ }
12
+
13
+ let rows = []
14
+ let lowerBound = mergedOptions.lower_bound
15
+
16
+ for (let i = 0; i < MAX_PAGINATION_FETCHES; i += 1) {
17
+ const result = await rpc.get_table_rows({
18
+ ...mergedOptions,
19
+ lower_bound: lowerBound
20
+ })
21
+ rows = rows.concat(result.rows)
22
+
23
+ if (!result.more || result.rows.length === 0) break
24
+
25
+ // EOS 2.0 api
26
+ // TODO Add 'more' key
27
+ if (typeof result.next_key !== 'undefined') {
28
+ lowerBound = result.next_key
29
+ } else {
30
+ lowerBound =
31
+ Number.parseInt(
32
+ `${result.rows[result.rows.length - 1][indexName]}`,
33
+ 10
34
+ ) + 1
35
+ }
36
+ }
37
+
38
+ return rows
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alcorexchange/alcor-swap-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -15,7 +15,13 @@
15
15
  "type": "git",
16
16
  "url": "git+https://github.com/alcorexchange/alcor-v2-sdk"
17
17
  },
18
- "keywords": ["alcor", "antelope", "eosio", "amm", "dex"],
18
+ "keywords": [
19
+ "alcor",
20
+ "antelope",
21
+ "eosio",
22
+ "amm",
23
+ "dex"
24
+ ],
19
25
  "author": "alcorexchange",
20
26
  "license": "ISC",
21
27
  "bugs": {
@@ -20,7 +20,9 @@ interface PositionConstructorArgs {
20
20
  tickUpper: number;
21
21
  liquidity: BigintIsh;
22
22
  feeGrowthInsideALastX64: BigintIsh,
23
- feeGrowthInsideBLastX64: BigintIsh
23
+ feeGrowthInsideBLastX64: BigintIsh,
24
+ feesA: BigintIsh,
25
+ feesB: BigintIsh,
24
26
  }
25
27
 
26
28
  interface Fees {
@@ -35,6 +37,8 @@ export class Position {
35
37
  public readonly tickLower: number;
36
38
  public readonly tickUpper: number;
37
39
  public readonly liquidity: JSBI;
40
+ public readonly feesA: JSBI;
41
+ public readonly feesB: JSBI;
38
42
  public readonly feeGrowthInsideALastX64: JSBI;
39
43
  public readonly feeGrowthInsideBLastX64: JSBI;
40
44
 
@@ -60,6 +64,8 @@ export class Position {
60
64
  tickUpper,
61
65
  feeGrowthInsideALastX64 = 0,
62
66
  feeGrowthInsideBLastX64 = 0,
67
+ feesA = 0,
68
+ feesB = 0,
63
69
  }: PositionConstructorArgs) {
64
70
  invariant(tickLower < tickUpper, "TICK_ORDER");
65
71
  invariant(
@@ -79,6 +85,8 @@ export class Position {
79
85
  this.liquidity = JSBI.BigInt(liquidity);
80
86
  this.feeGrowthInsideALastX64 = JSBI.BigInt(feeGrowthInsideALastX64);
81
87
  this.feeGrowthInsideBLastX64 = JSBI.BigInt(feeGrowthInsideBLastX64);
88
+ this.feesA = JSBI.BigInt(feesA)
89
+ this.feesB = JSBI.BigInt(feesB)
82
90
  }
83
91
 
84
92
  public get inRange(): boolean {
@@ -260,6 +268,8 @@ export class Position {
260
268
  useFullPrecision: false,
261
269
  feeGrowthInsideALastX64: this.feeGrowthInsideALastX64,
262
270
  feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64,
271
+ feesA: this.feesA,
272
+ feesB: this.feesB,
263
273
  });
264
274
 
265
275
  // we want the smaller amounts...
@@ -273,6 +283,8 @@ export class Position {
273
283
  tickUpper: this.tickUpper,
274
284
  feeGrowthInsideALastX64: this.feeGrowthInsideALastX64,
275
285
  feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64,
286
+ feesA: this.feesA,
287
+ feesB: this.feesB,
276
288
  }).mintAmounts;
277
289
  // ...and the lower for amountB
278
290
  const { amountB } = new Position({
@@ -284,6 +296,8 @@ export class Position {
284
296
  tickUpper: this.tickUpper,
285
297
  feeGrowthInsideALastX64: this.feeGrowthInsideALastX64,
286
298
  feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64,
299
+ feesA: this.feesA,
300
+ feesB: this.feesB,
287
301
  }).mintAmounts;
288
302
 
289
303
  return { amountA, amountB };
@@ -339,6 +353,8 @@ export class Position {
339
353
  tickUpper: this.tickUpper,
340
354
  feeGrowthInsideALastX64: this.feeGrowthInsideALastX64,
341
355
  feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64,
356
+ feesA: this.feesA,
357
+ feesB: this.feesB,
342
358
  }).amountA;
343
359
  // ...and the lower for amountB
344
360
  const amountB = new Position({
@@ -350,6 +366,8 @@ export class Position {
350
366
  tickUpper: this.tickUpper,
351
367
  feeGrowthInsideALastX64: this.feeGrowthInsideALastX64,
352
368
  feeGrowthInsideBLastX64: this.feeGrowthInsideBLastX64,
369
+ feesA: this.feesA,
370
+ feesB: this.feesB,
353
371
  }).amountB;
354
372
 
355
373
  return { amountA: amountA, amountB: amountB };
@@ -424,6 +442,8 @@ export class Position {
424
442
  useFullPrecision,
425
443
  feeGrowthInsideALastX64,
426
444
  feeGrowthInsideBLastX64,
445
+ feesA,
446
+ feesB
427
447
  }: {
428
448
  id: number,
429
449
  owner: string,
@@ -434,7 +454,9 @@ export class Position {
434
454
  amountB: BigintIsh;
435
455
  useFullPrecision: boolean;
436
456
  feeGrowthInsideALastX64: | BigintIsh,
437
- feeGrowthInsideBLastX64: | BigintIsh
457
+ feeGrowthInsideBLastX64: | BigintIsh,
458
+ feesA: BigintIsh,
459
+ feesB: BigintIsh
438
460
  }) {
439
461
  const sqrtRatioLX64 = TickMath.getSqrtRatioAtTick(tickLower);
440
462
  const sqrtRatioUX64 = TickMath.getSqrtRatioAtTick(tickUpper);
@@ -453,7 +475,9 @@ export class Position {
453
475
  useFullPrecision
454
476
  ),
455
477
  feeGrowthInsideALastX64,
456
- feeGrowthInsideBLastX64
478
+ feeGrowthInsideBLastX64,
479
+ feesA,
480
+ feesB
457
481
  });
458
482
  }
459
483
 
@@ -476,7 +500,9 @@ export class Position {
476
500
  amountA,
477
501
  useFullPrecision,
478
502
  feeGrowthInsideALastX64,
479
- feeGrowthInsideBLastX64
503
+ feeGrowthInsideBLastX64,
504
+ feesA,
505
+ feesB
480
506
  }: {
481
507
  id: number,
482
508
  owner: string,
@@ -487,6 +513,8 @@ export class Position {
487
513
  useFullPrecision: boolean;
488
514
  feeGrowthInsideALastX64: | BigintIsh;
489
515
  feeGrowthInsideBLastX64: | BigintIsh;
516
+ feesA: | BigintIsh;
517
+ feesB: | BigintIsh;
490
518
  }) {
491
519
  return Position.fromAmounts({
492
520
  id,
@@ -498,7 +526,9 @@ export class Position {
498
526
  amountB: MaxUint64,
499
527
  useFullPrecision,
500
528
  feeGrowthInsideALastX64,
501
- feeGrowthInsideBLastX64
529
+ feeGrowthInsideBLastX64,
530
+ feesA,
531
+ feesB
502
532
  });
503
533
  }
504
534
 
@@ -519,6 +549,8 @@ export class Position {
519
549
  amountB,
520
550
  feeGrowthInsideALastX64,
521
551
  feeGrowthInsideBLastX64,
552
+ feesA,
553
+ feesB
522
554
  }: {
523
555
  id: number,
524
556
  owner: string,
@@ -528,6 +560,8 @@ export class Position {
528
560
  amountB: BigintIsh;
529
561
  feeGrowthInsideALastX64: | BigintIsh;
530
562
  feeGrowthInsideBLastX64: | BigintIsh;
563
+ feesA: BigintIsh
564
+ feesB: BigintIsh
531
565
  }) {
532
566
  // this function always uses full precision,
533
567
  return Position.fromAmounts({
@@ -541,6 +575,8 @@ export class Position {
541
575
  useFullPrecision: true,
542
576
  feeGrowthInsideALastX64,
543
577
  feeGrowthInsideBLastX64,
578
+ feesA,
579
+ feesB
544
580
  });
545
581
  }
546
582
 
@@ -584,8 +620,8 @@ export class Position {
584
620
  );
585
621
 
586
622
  return {
587
- feesA: CurrencyAmount.fromRawAmount(this.pool.tokenA, tokensOwedA),
588
- feesB: CurrencyAmount.fromRawAmount(this.pool.tokenB, tokensOwedB),
623
+ feesA: CurrencyAmount.fromRawAmount(this.pool.tokenA, JSBI.add(tokensOwedA, this.feesA)),
624
+ feesB: CurrencyAmount.fromRawAmount(this.pool.tokenB, JSBI.add(tokensOwedB, this.feesB))
589
625
  }
590
626
  }
591
627
  }
package/test2.ts DELETED
@@ -1,73 +0,0 @@
1
- import fetch from 'node-fetch'
2
-
3
- // Alcor v2 sdk: https://github.com/alcorexchange/alcor-v2-sdk
4
- import { Token, Position, Pool } from './src'
5
-
6
- import { asset } from 'eos-common'
7
- import { JsonRpc } from 'eosjs'
8
- import { Serialize } from 'eosjs'
9
-
10
-
11
- export function parseToken(token) {
12
- return new Token(
13
- token.contract,
14
- asset(token.quantity).symbol.precision(),
15
- asset(token.quantity).symbol.code().to_string(),
16
- (asset(token.quantity).symbol.code().to_string() + '-' + token.contract).toLowerCase()
17
- )
18
- }
19
-
20
- const rpc = new JsonRpc('https://waxnode02.alcor.exchange', { fetch });
21
-
22
- const types: any = Serialize.createInitialTypes()
23
-
24
- export const nameToUint64 = (name) => {
25
- const ser = new Serialize.SerialBuffer()
26
- ser.pushName(name)
27
- return types.get('uint64').deserialize(ser)
28
- }
29
-
30
- async function main() {
31
- const account = '3mob2.wam'
32
-
33
- const { rows: pools } = await rpc.get_table_rows({
34
- scope: 'swap.alcor',
35
- table: 'pools',
36
- code: 'swap.alcor',
37
- })
38
-
39
- // First pool for example (TLM / WAX)
40
- const { tokenA, tokenB, currSlot: { sqrtPriceX64, tick } } = pools[0]
41
-
42
- const pool = new Pool({
43
- ...pools[0],
44
- tokenA: parseToken(tokenA),
45
- tokenB: parseToken(tokenB),
46
- sqrtPriceX64,
47
- tickCurrent: tick
48
- })
49
-
50
- const { rows: positions } = await rpc.get_table_rows({
51
- scope: pool.id,
52
- table: 'positions',
53
- code: 'swap.alcor',
54
- key_type: 'i64',
55
- index_position: 3,
56
- lower_bound: nameToUint64(account),
57
- upper_bound: nameToUint64(account)
58
- })
59
-
60
-
61
- const position = new Position({
62
- ...positions[0], // Only first of account position
63
- pool
64
- })
65
-
66
- console.log('amountA:', position.amountA.toAsset())
67
- console.log('amountB:', position.amountB.toAsset())
68
- }
69
-
70
- main()
71
-
72
- // amountA: 103.4332 TLM
73
- // amountB: 29.16056021 WAX
package/test3.ts DELETED
@@ -1,73 +0,0 @@
1
- import fetch from 'node-fetch'
2
-
3
- // Alcor v2 sdk: https://github.com/alcorexchange/alcor-v2-sdk
4
- import { Token, Position, Pool } from './src'
5
-
6
- import { asset } from 'eos-common'
7
- import { JsonRpc } from 'eosjs'
8
- import { Serialize } from 'eosjs'
9
-
10
-
11
- export function parseToken(token) {
12
- return new Token(
13
- token.contract,
14
- asset(token.quantity).symbol.precision(),
15
- asset(token.quantity).symbol.code().to_string(),
16
- (asset(token.quantity).symbol.code().to_string() + '-' + token.contract).toLowerCase()
17
- )
18
- }
19
-
20
- const rpc = new JsonRpc('https://waxnode02.alcor.exchange', { fetch });
21
-
22
- const types: any = Serialize.createInitialTypes()
23
-
24
- export const nameToUint64 = (name) => {
25
- const ser = new Serialize.SerialBuffer()
26
- ser.pushName(name)
27
- return types.get('uint64').deserialize(ser)
28
- }
29
-
30
- async function main() {
31
- const account = '3mob2.wam'
32
-
33
- const { rows: pools } = await rpc.get_table_rows({
34
- scope: 'swap.alcor',
35
- table: 'pools',
36
- code: 'swap.alcor',
37
- })
38
-
39
- // First pool for example (TLM / WAX)
40
- const { tokenA, tokenB, currSlot: { sqrtPriceX64, tick } } = pools[0]
41
-
42
- const pool = new Pool({
43
- ...pools[0],
44
- tokenA: parseToken(tokenA),
45
- tokenB: parseToken(tokenB),
46
- sqrtPriceX64,
47
- tickCurrent: tick
48
- })
49
-
50
- const { rows: positions } = await rpc.get_table_rows({
51
- scope: pool.id,
52
- table: 'positions',
53
- code: 'swap.alcor',
54
- key_type: 'i64',
55
- index_position: 3,
56
- lower_bound: nameToUint64(account),
57
- upper_bound: nameToUint64(account)
58
- })
59
-
60
-
61
- const position = new Position({
62
- ...positions[0], // Only first of account position
63
- pool
64
- })
65
-
66
- console.log('amountA:', position.amountA.toAsset())
67
- console.log('amountB:', position.amountB.toAsset())
68
- }
69
-
70
- main()
71
-
72
- // amountA: 103.4332 TLM
73
- // amountB: 29.16056021 WAX