@alcorexchange/alcor-swap-sdk 1.0.0

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.
Files changed (110) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +12 -0
  3. package/LICENSE +21 -0
  4. package/build/entities/baseCurrency.js +27 -0
  5. package/build/entities/currency.js +2 -0
  6. package/build/entities/fractions/currencyAmount.js +80 -0
  7. package/build/entities/fractions/fraction.js +117 -0
  8. package/build/entities/fractions/index.js +11 -0
  9. package/build/entities/fractions/percent.js +46 -0
  10. package/build/entities/fractions/price.js +73 -0
  11. package/build/entities/index.js +26 -0
  12. package/build/entities/pool.js +248 -0
  13. package/build/entities/position.js +364 -0
  14. package/build/entities/route.js +70 -0
  15. package/build/entities/tick.js +23 -0
  16. package/build/entities/tickDataProvider.js +30 -0
  17. package/build/entities/tickListDataProvider.js +35 -0
  18. package/build/entities/token.js +53 -0
  19. package/build/entities/trade.js +464 -0
  20. package/build/index.js +19 -0
  21. package/build/internalConstants.js +54 -0
  22. package/build/utils/computeAllRoutes.js +39 -0
  23. package/build/utils/encodeSqrtRatioX64.js +21 -0
  24. package/build/utils/fullMath.js +22 -0
  25. package/build/utils/index.js +30 -0
  26. package/build/utils/isSorted.js +18 -0
  27. package/build/utils/liquidityMath.js +23 -0
  28. package/build/utils/maxLiquidityForAmounts.js +86 -0
  29. package/build/utils/mostSignificantBit.js +27 -0
  30. package/build/utils/nearestUsableTick.js +26 -0
  31. package/build/utils/positionLibrary.js +22 -0
  32. package/build/utils/priceTickConversions.js +51 -0
  33. package/build/utils/sortedInsert.js +39 -0
  34. package/build/utils/sqrt.js +33 -0
  35. package/build/utils/sqrtPriceMath.js +92 -0
  36. package/build/utils/swapMath.js +86 -0
  37. package/build/utils/tickLibrary.js +61 -0
  38. package/build/utils/tickList.js +110 -0
  39. package/build/utils/tickMath.js +122 -0
  40. package/jest.config.js +40 -0
  41. package/nodemon.json +6 -0
  42. package/package.json +51 -0
  43. package/src/entities/baseCurrency.ts +53 -0
  44. package/src/entities/currency.ts +3 -0
  45. package/src/entities/fractions/currencyAmount.ts +129 -0
  46. package/src/entities/fractions/fraction.ts +190 -0
  47. package/src/entities/fractions/index.ts +4 -0
  48. package/src/entities/fractions/percent.ts +54 -0
  49. package/src/entities/fractions/price.ts +127 -0
  50. package/src/entities/index.ts +11 -0
  51. package/src/entities/pool.ts +399 -0
  52. package/src/entities/position.ts +591 -0
  53. package/src/entities/route.ts +84 -0
  54. package/src/entities/tick.ts +48 -0
  55. package/src/entities/tickDataProvider.ts +43 -0
  56. package/src/entities/tickListDataProvider.ts +37 -0
  57. package/src/entities/token.ts +56 -0
  58. package/src/entities/trade.ts +650 -0
  59. package/src/index.ts +3 -0
  60. package/src/internalConstants.ts +58 -0
  61. package/src/utils/computeAllRoutes.ts +64 -0
  62. package/src/utils/encodeSqrtRatioX64.ts +20 -0
  63. package/src/utils/fullMath.ts +17 -0
  64. package/src/utils/index.ts +14 -0
  65. package/src/utils/isSorted.ts +17 -0
  66. package/src/utils/liquidityMath.ts +17 -0
  67. package/src/utils/maxLiquidityForAmounts.ts +127 -0
  68. package/src/utils/mostSignificantBit.ts +25 -0
  69. package/src/utils/nearestUsableTick.ts +23 -0
  70. package/src/utils/positionLibrary.ts +37 -0
  71. package/src/utils/priceTickConversions.ts +57 -0
  72. package/src/utils/sortedInsert.ts +35 -0
  73. package/src/utils/sqrt.ts +31 -0
  74. package/src/utils/sqrtPriceMath.ts +169 -0
  75. package/src/utils/swapMath.ts +175 -0
  76. package/src/utils/tickLibrary.ts +88 -0
  77. package/src/utils/tickList.ts +147 -0
  78. package/src/utils/tickMath.ts +166 -0
  79. package/test/bestTradeExactOut.test.ts +266 -0
  80. package/test/currencyAmount.test.js +92 -0
  81. package/test/currencyAmount.test.ts +114 -0
  82. package/test/encodeSqrtRatioX64.test.ts +33 -0
  83. package/test/fixtures/pools.json +276 -0
  84. package/test/fixtures/ticks.json +608 -0
  85. package/test/fraction.test.js +87 -0
  86. package/test/fraction.test.ts +176 -0
  87. package/test/isSorted.test.ts +52 -0
  88. package/test/maxLiquidityForAmounts.test copy.ts +256 -0
  89. package/test/mostSignificantBit.test.ts +32 -0
  90. package/test/nearestUsableTick.test.ts +54 -0
  91. package/test/percent.test.js +52 -0
  92. package/test/percent.test.ts +68 -0
  93. package/test/pool.test.ts +377 -0
  94. package/test/position.test.ts +579 -0
  95. package/test/positionLibrary.test.ts +31 -0
  96. package/test/price.test.js +57 -0
  97. package/test/price.test.ts +62 -0
  98. package/test/priceTickConversions.test.ts +137 -0
  99. package/test/sqrtPriceMath.test.ts +113 -0
  100. package/test/tick.test.js +22 -0
  101. package/test/tick.test.ts +28 -0
  102. package/test/tickDataProvider.test.ts +17 -0
  103. package/test/tickLibrary.test.ts +111 -0
  104. package/test/tickList.test.ts +215 -0
  105. package/test/tickListDataProvider.test.ts +64 -0
  106. package/test/tickMath.test.ts +66 -0
  107. package/test/token.test.ts +58 -0
  108. package/test/trade.test.ts +210 -0
  109. package/test2.ts +73 -0
  110. package/tsconfig.json +24 -0
@@ -0,0 +1,190 @@
1
+ import JSBI from "jsbi";
2
+ import invariant from "tiny-invariant";
3
+ import toFormat from "toformat";
4
+ import _Decimal from "decimal.js-light";
5
+ import _Big, { RoundingMode } from "big.js";
6
+
7
+ import { BigintIsh, Rounding } from "../../internalConstants";
8
+
9
+ const Decimal = toFormat(_Decimal);
10
+ const Big = toFormat(_Big);
11
+
12
+ const toSignificantRounding = {
13
+ [Rounding.ROUND_DOWN]: Decimal.ROUND_DOWN,
14
+ [Rounding.ROUND_HALF_UP]: Decimal.ROUND_HALF_UP,
15
+ [Rounding.ROUND_UP]: Decimal.ROUND_UP,
16
+ };
17
+
18
+ // const toFixedRounding = {
19
+ // [Rounding.ROUND_DOWN]: RoundingMode.RoundDown,
20
+ // [Rounding.ROUND_HALF_UP]: RoundingMode.RoundHalfUp,
21
+ // [Rounding.ROUND_UP]: RoundingMode.RoundUp
22
+ // }
23
+ const toFixedRounding = {
24
+ [Rounding.ROUND_DOWN]: 0,
25
+ [Rounding.ROUND_HALF_UP]: 1,
26
+ [Rounding.ROUND_UP]: 3,
27
+ };
28
+
29
+ export class Fraction {
30
+ public readonly numerator: JSBI;
31
+ public readonly denominator: JSBI;
32
+
33
+ public constructor(
34
+ numerator: BigintIsh,
35
+ denominator: BigintIsh = JSBI.BigInt(1)
36
+ ) {
37
+ this.numerator = JSBI.BigInt(numerator);
38
+ this.denominator = JSBI.BigInt(denominator);
39
+ }
40
+
41
+ private static tryParseFraction(fractionish: BigintIsh | Fraction): Fraction {
42
+ if (
43
+ fractionish instanceof JSBI ||
44
+ typeof fractionish === "number" ||
45
+ typeof fractionish === "string"
46
+ )
47
+ return new Fraction(fractionish);
48
+
49
+ if ("numerator" in fractionish && "denominator" in fractionish)
50
+ return fractionish;
51
+ throw new Error("Could not parse fraction");
52
+ }
53
+
54
+ // performs floor division
55
+ public get quotient(): JSBI {
56
+ return JSBI.divide(this.numerator, this.denominator);
57
+ }
58
+
59
+ // remainder after floor division
60
+ public get remainder(): Fraction {
61
+ return new Fraction(
62
+ JSBI.remainder(this.numerator, this.denominator),
63
+ this.denominator
64
+ );
65
+ }
66
+
67
+ public invert(): Fraction {
68
+ return new Fraction(this.denominator, this.numerator);
69
+ }
70
+
71
+ public add(other: Fraction | BigintIsh): Fraction {
72
+ const otherParsed = Fraction.tryParseFraction(other);
73
+ if (JSBI.equal(this.denominator, otherParsed.denominator)) {
74
+ return new Fraction(
75
+ JSBI.add(this.numerator, otherParsed.numerator),
76
+ this.denominator
77
+ );
78
+ }
79
+ return new Fraction(
80
+ JSBI.add(
81
+ JSBI.multiply(this.numerator, otherParsed.denominator),
82
+ JSBI.multiply(otherParsed.numerator, this.denominator)
83
+ ),
84
+ JSBI.multiply(this.denominator, otherParsed.denominator)
85
+ );
86
+ }
87
+
88
+ public subtract(other: Fraction | BigintIsh): Fraction {
89
+ const otherParsed = Fraction.tryParseFraction(other);
90
+ if (JSBI.equal(this.denominator, otherParsed.denominator)) {
91
+ return new Fraction(
92
+ JSBI.subtract(this.numerator, otherParsed.numerator),
93
+ this.denominator
94
+ );
95
+ }
96
+ return new Fraction(
97
+ JSBI.subtract(
98
+ JSBI.multiply(this.numerator, otherParsed.denominator),
99
+ JSBI.multiply(otherParsed.numerator, this.denominator)
100
+ ),
101
+ JSBI.multiply(this.denominator, otherParsed.denominator)
102
+ );
103
+ }
104
+
105
+ public lessThan(other: Fraction | BigintIsh): boolean {
106
+ const otherParsed = Fraction.tryParseFraction(other);
107
+ return JSBI.lessThan(
108
+ JSBI.multiply(this.numerator, otherParsed.denominator),
109
+ JSBI.multiply(otherParsed.numerator, this.denominator)
110
+ );
111
+ }
112
+
113
+ public equalTo(other: Fraction | BigintIsh): boolean {
114
+ const otherParsed = Fraction.tryParseFraction(other);
115
+ return JSBI.equal(
116
+ JSBI.multiply(this.numerator, otherParsed.denominator),
117
+ JSBI.multiply(otherParsed.numerator, this.denominator)
118
+ );
119
+ }
120
+
121
+ public greaterThan(other: Fraction | BigintIsh): boolean {
122
+ const otherParsed = Fraction.tryParseFraction(other);
123
+ return JSBI.greaterThan(
124
+ JSBI.multiply(this.numerator, otherParsed.denominator),
125
+ JSBI.multiply(otherParsed.numerator, this.denominator)
126
+ );
127
+ }
128
+
129
+ public multiply(other: Fraction | BigintIsh): Fraction {
130
+ const otherParsed = Fraction.tryParseFraction(other);
131
+ return new Fraction(
132
+ JSBI.multiply(this.numerator, otherParsed.numerator),
133
+ JSBI.multiply(this.denominator, otherParsed.denominator)
134
+ );
135
+ }
136
+
137
+ public divide(other: Fraction | BigintIsh): Fraction {
138
+ const otherParsed = Fraction.tryParseFraction(other);
139
+ return new Fraction(
140
+ JSBI.multiply(this.numerator, otherParsed.denominator),
141
+ JSBI.multiply(this.denominator, otherParsed.numerator)
142
+ );
143
+ }
144
+
145
+ public toSignificant(
146
+ significantDigits: number,
147
+ format: object = { groupSeparator: "" },
148
+ rounding: Rounding = Rounding.ROUND_HALF_UP
149
+ ): string {
150
+ invariant(
151
+ Number.isInteger(significantDigits),
152
+ `${significantDigits} is not an integer.`
153
+ );
154
+ invariant(significantDigits > 0, `${significantDigits} is not positive.`);
155
+
156
+ Decimal.set({
157
+ precision: significantDigits + 1,
158
+ rounding: toSignificantRounding[rounding],
159
+ });
160
+ const quotient = new Decimal(this.numerator.toString())
161
+ .div(this.denominator.toString())
162
+ .toSignificantDigits(significantDigits);
163
+ return quotient.toFormat(quotient.decimalPlaces(), format);
164
+ }
165
+
166
+ public toFixed(
167
+ decimalPlaces: number,
168
+ format: object = { groupSeparator: "" },
169
+ rounding: Rounding = Rounding.ROUND_HALF_UP
170
+ ): string {
171
+ invariant(
172
+ Number.isInteger(decimalPlaces),
173
+ `${decimalPlaces} is not an integer.`
174
+ );
175
+ invariant(decimalPlaces >= 0, `${decimalPlaces} is negative.`);
176
+
177
+ Big.DP = decimalPlaces;
178
+ Big.RM = toFixedRounding[rounding];
179
+ return new Big(this.numerator.toString())
180
+ .div(this.denominator.toString())
181
+ .toFormat(decimalPlaces, format);
182
+ }
183
+
184
+ /**
185
+ * Helper method for converting any super class back to a fraction
186
+ */
187
+ public get asFraction(): Fraction {
188
+ return new Fraction(this.numerator, this.denominator);
189
+ }
190
+ }
@@ -0,0 +1,4 @@
1
+ export { CurrencyAmount } from "./currencyAmount";
2
+ export { Fraction } from "./fraction";
3
+ export { Percent } from "./percent";
4
+ export { Price } from "./price";
@@ -0,0 +1,54 @@
1
+ import JSBI from "jsbi";
2
+ import { BigintIsh, Rounding } from "../../internalConstants";
3
+ import { Fraction } from "./fraction";
4
+
5
+ const ONE_HUNDRED = new Fraction(JSBI.BigInt(100));
6
+
7
+ /**
8
+ * Converts a fraction to a percent
9
+ * @param fraction the fraction to convert
10
+ */
11
+ function toPercent(fraction: Fraction): Percent {
12
+ return new Percent(fraction.numerator, fraction.denominator);
13
+ }
14
+
15
+ export class Percent extends Fraction {
16
+ /**
17
+ * This boolean prevents a fraction from being interpreted as a Percent
18
+ */
19
+ public readonly isPercent: true = true;
20
+
21
+ add(other: Fraction | BigintIsh): Percent {
22
+ return toPercent(super.add(other));
23
+ }
24
+
25
+ subtract(other: Fraction | BigintIsh): Percent {
26
+ return toPercent(super.subtract(other));
27
+ }
28
+
29
+ multiply(other: Fraction | BigintIsh): Percent {
30
+ return toPercent(super.multiply(other));
31
+ }
32
+
33
+ divide(other: Fraction | BigintIsh): Percent {
34
+ return toPercent(super.divide(other));
35
+ }
36
+
37
+ public toSignificant(
38
+ significantDigits: number = 5,
39
+ format?: object,
40
+ rounding?: Rounding
41
+ ): string {
42
+ return super
43
+ .multiply(ONE_HUNDRED)
44
+ .toSignificant(significantDigits, format, rounding);
45
+ }
46
+
47
+ public toFixed(
48
+ decimalPlaces: number = 2,
49
+ format?: object,
50
+ rounding?: Rounding
51
+ ): string {
52
+ return super.multiply(ONE_HUNDRED).toFixed(decimalPlaces, format, rounding);
53
+ }
54
+ }
@@ -0,0 +1,127 @@
1
+ import JSBI from "jsbi";
2
+ import invariant from "tiny-invariant";
3
+
4
+ import { BigintIsh, Rounding } from "../../internalConstants";
5
+ import { Currency } from "../currency";
6
+ import { Fraction } from "./fraction";
7
+ import { CurrencyAmount } from "./currencyAmount";
8
+
9
+ export class Price<
10
+ TBase extends Currency,
11
+ TQuote extends Currency
12
+ > extends Fraction {
13
+ public readonly baseCurrency: TBase; // input i.e. denominator
14
+ public readonly quoteCurrency: TQuote; // output i.e. numerator
15
+ public readonly scalar: Fraction; // used to adjust the raw fraction w/r/t the decimals of the {base,quote}Token
16
+
17
+ /**
18
+ * Construct a price, either with the base and quote currency amount, or the
19
+ * @param args
20
+ */
21
+ public constructor(
22
+ ...args:
23
+ | [TBase, TQuote, BigintIsh, BigintIsh]
24
+ | [
25
+ {
26
+ baseAmount: CurrencyAmount<TBase>;
27
+ quoteAmount: CurrencyAmount<TQuote>;
28
+ }
29
+ ]
30
+ ) {
31
+ let baseCurrency: TBase,
32
+ quoteCurrency: TQuote,
33
+ denominator: BigintIsh,
34
+ numerator: BigintIsh;
35
+
36
+ if (args.length === 4) {
37
+ [baseCurrency, quoteCurrency, denominator, numerator] = args;
38
+ } else {
39
+ const result = args[0].quoteAmount.divide(args[0].baseAmount);
40
+ [baseCurrency, quoteCurrency, denominator, numerator] = [
41
+ args[0].baseAmount.currency,
42
+ args[0].quoteAmount.currency,
43
+ result.denominator,
44
+ result.numerator,
45
+ ];
46
+ }
47
+ super(numerator, denominator);
48
+
49
+ this.baseCurrency = baseCurrency;
50
+ this.quoteCurrency = quoteCurrency;
51
+ this.scalar = new Fraction(
52
+ JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(baseCurrency.decimals)),
53
+ JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(quoteCurrency.decimals))
54
+ );
55
+ }
56
+
57
+ /**
58
+ * Flip the price, switching the base and quote currency
59
+ */
60
+ public invert(): Price<TQuote, TBase> {
61
+ return new Price(
62
+ this.quoteCurrency,
63
+ this.baseCurrency,
64
+ this.numerator,
65
+ this.denominator
66
+ );
67
+ }
68
+
69
+ /**
70
+ * Multiply the price by another price, returning a new price. The other price must have the same base currency as this price's quote currency
71
+ * @param other the other price
72
+ */
73
+ public multiply<TOtherQuote extends Currency>(
74
+ other: Price<TQuote, TOtherQuote>
75
+ ): Price<TBase, TOtherQuote> {
76
+ invariant(this.quoteCurrency.equals(other.baseCurrency), "TOKEN");
77
+ const fraction = super.multiply(other);
78
+ return new Price(
79
+ this.baseCurrency,
80
+ other.quoteCurrency,
81
+ fraction.denominator,
82
+ fraction.numerator
83
+ );
84
+ }
85
+
86
+ /**
87
+ * Return the amount of quote currency corresponding to a given amount of the base currency
88
+ * @param currencyAmount the amount of base currency to quote against the price
89
+ */
90
+ public quote(currencyAmount: CurrencyAmount<TBase>): CurrencyAmount<TQuote> {
91
+ invariant(currencyAmount.currency.equals(this.baseCurrency), "TOKEN");
92
+ const result = super.multiply(currencyAmount);
93
+ return CurrencyAmount.fromFractionalAmount(
94
+ this.quoteCurrency,
95
+ result.numerator,
96
+ result.denominator
97
+ );
98
+ }
99
+
100
+ /**
101
+ * Get the value scaled by decimals for formatting
102
+ * @private
103
+ */
104
+ private get adjustedForDecimals(): Fraction {
105
+ return super.multiply(this.scalar);
106
+ }
107
+
108
+ public toSignificant(
109
+ significantDigits: number = 6,
110
+ format?: object,
111
+ rounding?: Rounding
112
+ ): string {
113
+ return this.adjustedForDecimals.toSignificant(
114
+ significantDigits,
115
+ format,
116
+ rounding
117
+ );
118
+ }
119
+
120
+ public toFixed(
121
+ decimalPlaces: number = 4,
122
+ format?: object,
123
+ rounding?: Rounding
124
+ ): string {
125
+ return this.adjustedForDecimals.toFixed(decimalPlaces, format, rounding);
126
+ }
127
+ }
@@ -0,0 +1,11 @@
1
+ export * from "./fractions";
2
+
3
+ export * from "./tick";
4
+ export * from "./tickDataProvider";
5
+ export * from "./tickListDataProvider";
6
+ export * from "./currency";
7
+ export * from "./token";
8
+ export * from "./pool";
9
+ export * from "./position";
10
+ export * from "./route";
11
+ export * from "./trade";