@swapkit/helpers 1.0.0-rc.7 → 1.0.0-rc.70
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/index.cjs +2 -1
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +94 -73
- package/dist/index.es.js +988 -498
- package/dist/index.es.js.map +1 -0
- package/package.json +16 -13
- package/src/helpers/__tests__/memo.test.ts +3 -3
- package/src/helpers/asset.ts +56 -56
- package/src/helpers/liquidity.ts +46 -38
- package/src/helpers/memo.ts +19 -16
- package/src/helpers/others.ts +6 -54
- package/src/helpers/validators.ts +4 -3
- package/src/index.ts +2 -0
- package/src/modules/__tests__/assetValue.test.ts +145 -38
- package/src/modules/__tests__/bigIntArithmetics.test.ts +30 -0
- package/src/modules/__tests__/swapKitNumber.test.ts +174 -48
- package/src/modules/assetValue.ts +169 -145
- package/src/modules/bigIntArithmetics.ts +185 -116
- package/src/modules/swapKitError.ts +13 -4
- package/src/modules/swapKitNumber.ts +8 -1
- package/src/types.ts +30 -0
|
@@ -1,84 +1,46 @@
|
|
|
1
|
-
import
|
|
2
|
-
CoinGeckoList,
|
|
3
|
-
MayaList,
|
|
4
|
-
PancakeswapETHList,
|
|
5
|
-
PancakeswapList,
|
|
6
|
-
PangolinList,
|
|
7
|
-
StargateARBList,
|
|
8
|
-
SushiswapList,
|
|
9
|
-
ThorchainList,
|
|
10
|
-
TraderjoeList,
|
|
11
|
-
UniswapList,
|
|
12
|
-
WoofiList,
|
|
13
|
-
} from '@swapkit/tokens';
|
|
14
|
-
import { BaseDecimal, Chain } from '@swapkit/types';
|
|
1
|
+
import { BaseDecimal, Chain, ChainToChainId } from '@swapkit/types';
|
|
15
2
|
|
|
16
3
|
import type { CommonAssetString } from '../helpers/asset.ts';
|
|
17
4
|
import { getAssetType, getCommonAssetInfo, getDecimal, isGasAsset } from '../helpers/asset.ts';
|
|
18
5
|
import { validateIdentifier } from '../helpers/validators.ts';
|
|
6
|
+
import type { TokenNames, TokenTax } from '../types.ts';
|
|
19
7
|
|
|
20
|
-
import {
|
|
8
|
+
import type { NumberPrimitives } from './bigIntArithmetics.ts';
|
|
9
|
+
import { BigIntArithmetics, formatBigIntToSafeValue } from './bigIntArithmetics.ts';
|
|
21
10
|
import type { SwapKitValueType } from './swapKitNumber.ts';
|
|
22
11
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
type TCTokenNames = (typeof ThorchainList)['tokens'][number]['identifier'];
|
|
29
|
-
|
|
30
|
-
type TokenNames =
|
|
31
|
-
| TCTokenNames
|
|
32
|
-
| (typeof CoinGeckoList)['tokens'][number]['identifier']
|
|
33
|
-
| (typeof MayaList)['tokens'][number]['identifier']
|
|
34
|
-
| (typeof PancakeswapETHList)['tokens'][number]['identifier']
|
|
35
|
-
| (typeof PancakeswapList)['tokens'][number]['identifier']
|
|
36
|
-
| (typeof PangolinList)['tokens'][number]['identifier']
|
|
37
|
-
| (typeof StargateARBList)['tokens'][number]['identifier']
|
|
38
|
-
| (typeof SushiswapList)['tokens'][number]['identifier']
|
|
39
|
-
| (typeof TraderjoeList)['tokens'][number]['identifier']
|
|
40
|
-
| (typeof WoofiList)['tokens'][number]['identifier']
|
|
41
|
-
| (typeof UniswapList)['tokens'][number]['identifier'];
|
|
42
|
-
|
|
43
|
-
let staticTokensMap: Map<TokenNames, { decimal: number; identifier: string }> | undefined;
|
|
44
|
-
|
|
45
|
-
const getStaticToken = (identifier: TokenNames) => {
|
|
46
|
-
if (!staticTokensMap) {
|
|
47
|
-
throw new Error('Static assets not loaded, call await AssetValue.loadStaticAssets() first');
|
|
48
|
-
}
|
|
49
|
-
const tokenInfo = staticTokensMap.get(identifier.toUpperCase() as TokenNames);
|
|
50
|
-
|
|
51
|
-
return tokenInfo || { decimal: BaseDecimal.THOR, identifier: '' };
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const createAssetValue = async (assetString: string, value: number | string = 0) => {
|
|
55
|
-
validateIdentifier(assetString);
|
|
56
|
-
|
|
57
|
-
const decimal = await getDecimal(getAssetInfo(assetString));
|
|
58
|
-
return new AssetValue({ decimal, value, identifier: assetString });
|
|
59
|
-
};
|
|
12
|
+
const staticTokensMap = new Map<
|
|
13
|
+
TokenNames,
|
|
14
|
+
{ tax?: TokenTax; decimal: number; identifier: string }
|
|
15
|
+
>();
|
|
60
16
|
|
|
61
17
|
export class AssetValue extends BigIntArithmetics {
|
|
62
18
|
address?: string;
|
|
63
19
|
chain: Chain;
|
|
64
|
-
isSynthetic = false;
|
|
65
20
|
isGasAsset = false;
|
|
21
|
+
isSynthetic = false;
|
|
66
22
|
symbol: string;
|
|
23
|
+
tax?: TokenTax;
|
|
67
24
|
ticker: string;
|
|
68
25
|
type: ReturnType<typeof getAssetType>;
|
|
69
26
|
|
|
70
|
-
constructor(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
27
|
+
constructor({
|
|
28
|
+
value,
|
|
29
|
+
decimal,
|
|
30
|
+
tax,
|
|
31
|
+
chain,
|
|
32
|
+
symbol,
|
|
33
|
+
identifier,
|
|
34
|
+
}: { decimal: number; value: SwapKitValueType; tax?: TokenTax } & (
|
|
35
|
+
| { chain: Chain; symbol: string; identifier?: never }
|
|
36
|
+
| { identifier: string; chain?: never; symbol?: never }
|
|
37
|
+
)) {
|
|
38
|
+
super(typeof value === 'object' ? value : { decimal, value });
|
|
76
39
|
|
|
77
|
-
const identifier
|
|
78
|
-
'identifier' in params ? params.identifier : `${params.chain}.${params.symbol}`;
|
|
79
|
-
const assetInfo = getAssetInfo(identifier);
|
|
40
|
+
const assetInfo = getAssetInfo(identifier || `${chain}.${symbol}`);
|
|
80
41
|
|
|
81
42
|
this.type = getAssetType(assetInfo);
|
|
43
|
+
this.tax = tax;
|
|
82
44
|
this.chain = assetInfo.chain;
|
|
83
45
|
this.ticker = assetInfo.ticker;
|
|
84
46
|
this.symbol = assetInfo.symbol;
|
|
@@ -87,100 +49,112 @@ export class AssetValue extends BigIntArithmetics {
|
|
|
87
49
|
this.isGasAsset = assetInfo.isGasAsset;
|
|
88
50
|
}
|
|
89
51
|
|
|
90
|
-
|
|
91
|
-
return `${this.
|
|
52
|
+
toString() {
|
|
53
|
+
return this.isSynthetic ? this.symbol : `${this.chain}.${this.symbol}`;
|
|
92
54
|
}
|
|
93
55
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const shortFormat = this.isSynthetic ? this.ticker : `${this.chain}.${this.ticker}`;
|
|
97
|
-
|
|
98
|
-
return short
|
|
99
|
-
? shortFormat
|
|
100
|
-
: // THOR.ETH/ETH | ETH.USDT-0x1234567890
|
|
101
|
-
`${this.chain}.${this.symbol}`;
|
|
56
|
+
toUrl() {
|
|
57
|
+
return this.isSynthetic ? `${this.chain}.${this.symbol.replace('/', '.')}` : this.toString();
|
|
102
58
|
}
|
|
103
59
|
|
|
104
60
|
eq({ chain, symbol }: { chain: Chain; symbol: string }) {
|
|
105
61
|
return this.chain === chain && this.symbol === symbol;
|
|
106
62
|
}
|
|
107
63
|
|
|
108
|
-
|
|
109
|
-
return
|
|
64
|
+
chainId() {
|
|
65
|
+
return ChainToChainId[this.chain];
|
|
110
66
|
}
|
|
111
67
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
68
|
+
// THOR.RUNE
|
|
69
|
+
// THOR.ETH.ETH
|
|
70
|
+
// ETH.THOR-0x1234567890
|
|
71
|
+
static fromUrl(urlAsset: string, value: NumberPrimitives = 0) {
|
|
72
|
+
const [chain, ticker, symbol] = urlAsset.split('.');
|
|
73
|
+
if (!chain || !ticker) throw new Error('Invalid asset url');
|
|
116
74
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
: undefined;
|
|
120
|
-
}
|
|
75
|
+
const assetString =
|
|
76
|
+
chain === Chain.THORChain && symbol ? `${chain}.${ticker}/${symbol}` : urlAsset;
|
|
121
77
|
|
|
122
|
-
static async fromIdentifier(
|
|
123
|
-
assetString: `${Chain}.${string}` | `${Chain}/${string}` | `${Chain}.${string}-${string}`,
|
|
124
|
-
value: number | string = 0,
|
|
125
|
-
) {
|
|
126
78
|
return createAssetValue(assetString, value);
|
|
127
79
|
}
|
|
128
80
|
|
|
129
|
-
static
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return new AssetValue({ decimal, identifier: tokenIdentifier, value });
|
|
81
|
+
static fromString(assetString: string, value: NumberPrimitives = 0) {
|
|
82
|
+
return createAssetValue(assetString, value);
|
|
133
83
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
84
|
+
static fromIdentifier(
|
|
85
|
+
assetString:
|
|
86
|
+
| `${Chain}.${string}`
|
|
87
|
+
| `${Chain}/${string}`
|
|
88
|
+
| `${Chain}.${string}-${string}`
|
|
89
|
+
| TokenNames,
|
|
90
|
+
value: NumberPrimitives = 0,
|
|
91
|
+
) {
|
|
92
|
+
return createAssetValue(assetString, value);
|
|
139
93
|
}
|
|
140
94
|
|
|
141
|
-
static
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
95
|
+
static fromStringSync(assetString: string, value: NumberPrimitives = 0) {
|
|
96
|
+
const { chain, isSynthetic } = getAssetInfo(assetString);
|
|
97
|
+
const tokenInfo = staticTokensMap.get(assetString.toUpperCase() as TokenNames);
|
|
98
|
+
|
|
99
|
+
if (isSynthetic) return createSyntheticAssetValue(assetString, value);
|
|
100
|
+
// TODO: write logger that will only run in dev mode with some flag
|
|
101
|
+
// if (!tokenInfo) {
|
|
102
|
+
// console.error(
|
|
103
|
+
// `Asset ${assetString} is not loaded. Use AssetValue.loadStaticAssets() to load it`,
|
|
104
|
+
// );
|
|
105
|
+
// }
|
|
106
|
+
|
|
107
|
+
const { tax, decimal, identifier } = tokenInfo || {
|
|
108
|
+
decimal: BaseDecimal[chain],
|
|
109
|
+
identifier: assetString,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
return new AssetValue({
|
|
113
|
+
tax,
|
|
114
|
+
value: safeValue(value, decimal),
|
|
115
|
+
identifier: isSynthetic ? assetString : identifier,
|
|
116
|
+
decimal: isSynthetic ? 8 : decimal,
|
|
117
|
+
});
|
|
146
118
|
}
|
|
147
119
|
|
|
148
|
-
static
|
|
149
|
-
const
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
120
|
+
static fromIdentifierSync(assetString: TokenNames, value: NumberPrimitives = 0) {
|
|
121
|
+
const { chain, isSynthetic } = getAssetInfo(assetString);
|
|
122
|
+
const tokenInfo = staticTokensMap.get(assetString);
|
|
123
|
+
|
|
124
|
+
if (isSynthetic) return createSyntheticAssetValue(assetString, value);
|
|
125
|
+
// TODO: write logger that will only run in dev mode with some flag
|
|
126
|
+
// if (!tokenInfo) {
|
|
127
|
+
// console.error(
|
|
128
|
+
// `Asset ${assetString} is not loaded. - Loading with base Chain. Use AssetValue.loadStaticAssets() to load it`,
|
|
129
|
+
// );
|
|
130
|
+
// }
|
|
131
|
+
|
|
132
|
+
const { tax, decimal, identifier } = tokenInfo || {
|
|
133
|
+
decimal: BaseDecimal[chain],
|
|
134
|
+
identifier: assetString,
|
|
135
|
+
};
|
|
136
|
+
return new AssetValue({ tax, decimal, identifier, value: safeValue(value, decimal) });
|
|
137
|
+
}
|
|
155
138
|
|
|
156
|
-
|
|
139
|
+
static fromChainOrSignature(assetString: CommonAssetString, value: NumberPrimitives = 0) {
|
|
140
|
+
const { decimal, identifier } = getCommonAssetInfo(assetString);
|
|
141
|
+
return new AssetValue({ value: safeValue(value, decimal), decimal, identifier });
|
|
157
142
|
}
|
|
158
143
|
|
|
159
|
-
static
|
|
144
|
+
static loadStaticAssets() {
|
|
160
145
|
return new Promise<{ ok: true } | { ok: false; message: string; error: any }>(
|
|
161
146
|
async (resolve, reject) => {
|
|
162
147
|
try {
|
|
163
|
-
const
|
|
164
|
-
// Omit ThorchainList from import to avoid decimals conflict (TC uses 8 for all)
|
|
165
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
166
|
-
ThorchainList: _ThorchainList,
|
|
167
|
-
NativeList,
|
|
168
|
-
...tokensPackage
|
|
169
|
-
} = await import('@swapkit/tokens');
|
|
170
|
-
const tokensMap = [NativeList, ...Object.values(tokensPackage)].reduce(
|
|
171
|
-
(acc, { tokens }) => {
|
|
172
|
-
tokens.forEach(({ identifier, chain, ...rest }) => {
|
|
173
|
-
const decimal = 'decimals' in rest ? rest.decimals : BaseDecimal[chain as Chain];
|
|
174
|
-
|
|
175
|
-
acc.set(identifier as TokenNames, { identifier, decimal });
|
|
176
|
-
});
|
|
148
|
+
const tokenPackages = await import('@swapkit/tokens');
|
|
177
149
|
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
150
|
+
Object.values(tokenPackages).forEach((tokenList) => {
|
|
151
|
+
tokenList?.tokens?.forEach(({ identifier, chain, ...rest }) => {
|
|
152
|
+
staticTokensMap.set(identifier.toUpperCase() as TokenNames, {
|
|
153
|
+
identifier,
|
|
154
|
+
decimal: 'decimals' in rest ? rest.decimals : BaseDecimal[chain as Chain],
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
});
|
|
184
158
|
|
|
185
159
|
resolve({ ok: true });
|
|
186
160
|
} catch (error) {
|
|
@@ -197,46 +171,96 @@ export class AssetValue extends BigIntArithmetics {
|
|
|
197
171
|
}
|
|
198
172
|
}
|
|
199
173
|
|
|
200
|
-
export
|
|
174
|
+
export function getMinAmountByChain(chain: Chain) {
|
|
201
175
|
const asset = AssetValue.fromChainOrSignature(chain);
|
|
202
176
|
|
|
203
177
|
switch (chain) {
|
|
204
178
|
case Chain.Bitcoin:
|
|
205
179
|
case Chain.Litecoin:
|
|
206
180
|
case Chain.BitcoinCash:
|
|
207
|
-
return asset.
|
|
181
|
+
return asset.set(0.00010001);
|
|
208
182
|
|
|
209
183
|
case Chain.Dogecoin:
|
|
210
|
-
return asset.
|
|
184
|
+
return asset.set(1.00000001);
|
|
211
185
|
|
|
212
186
|
case Chain.Avalanche:
|
|
213
187
|
case Chain.Ethereum:
|
|
214
|
-
return asset.
|
|
188
|
+
return asset.set(0.00000001);
|
|
215
189
|
|
|
216
190
|
case Chain.THORChain:
|
|
217
191
|
case Chain.Maya:
|
|
218
|
-
return asset.
|
|
192
|
+
return asset.set(0);
|
|
193
|
+
|
|
194
|
+
case Chain.Cosmos:
|
|
195
|
+
return asset.set(0.000001);
|
|
219
196
|
|
|
220
197
|
default:
|
|
221
|
-
return asset.
|
|
198
|
+
return asset.set(0.00000001);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async function createAssetValue(identifier: string, value: NumberPrimitives = 0) {
|
|
203
|
+
validateIdentifier(identifier);
|
|
204
|
+
|
|
205
|
+
const staticToken = staticTokensMap.get(identifier.toUpperCase() as TokenNames);
|
|
206
|
+
const decimal = staticToken?.decimal || (await getDecimal(getAssetInfo(identifier)));
|
|
207
|
+
if (!staticToken) {
|
|
208
|
+
staticTokensMap.set(identifier.toUpperCase() as TokenNames, { identifier, decimal });
|
|
222
209
|
}
|
|
223
|
-
};
|
|
224
210
|
|
|
225
|
-
|
|
211
|
+
return new AssetValue({ decimal, value: safeValue(value, decimal), identifier });
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function createSyntheticAssetValue(identifier: string, value: NumberPrimitives = 0) {
|
|
215
|
+
const [synthChain, symbol] =
|
|
216
|
+
identifier.split('.')[0].toUpperCase() === Chain.THORChain
|
|
217
|
+
? identifier.split('.').slice(1)!.join().split('/')
|
|
218
|
+
: identifier.split('/');
|
|
219
|
+
|
|
220
|
+
if (!synthChain || !symbol) throw new Error('Invalid asset identifier');
|
|
221
|
+
|
|
222
|
+
return new AssetValue({
|
|
223
|
+
decimal: 8,
|
|
224
|
+
value: safeValue(value, 8),
|
|
225
|
+
identifier: `${Chain.THORChain}.${synthChain}/${symbol}`,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function safeValue(value: NumberPrimitives, decimal: number) {
|
|
230
|
+
return typeof value === 'bigint'
|
|
231
|
+
? formatBigIntToSafeValue({ value, bigIntDecimal: decimal, decimal })
|
|
232
|
+
: value;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// TODO refactor & split into smaller functions
|
|
236
|
+
function getAssetInfo(identifier: string) {
|
|
226
237
|
const isSynthetic = identifier.slice(0, 14).includes('/');
|
|
227
|
-
const adjustedIdentifier = identifier.includes('.')
|
|
228
|
-
? identifier
|
|
229
|
-
: `${Chain.THORChain}.${identifier}`;
|
|
230
238
|
|
|
231
|
-
const [
|
|
232
|
-
|
|
239
|
+
const [synthChain, synthSymbol] =
|
|
240
|
+
identifier.split('.')[0].toUpperCase() === Chain.THORChain
|
|
241
|
+
? identifier.split('.').slice(1)!.join().split('/')
|
|
242
|
+
: identifier.split('/');
|
|
243
|
+
|
|
244
|
+
if (isSynthetic && (!synthChain || !synthSymbol)) throw new Error('Invalid asset identifier');
|
|
245
|
+
|
|
246
|
+
const adjustedIdentifier =
|
|
247
|
+
identifier.includes('.') && !isSynthetic ? identifier : `${Chain.THORChain}.${synthSymbol}`;
|
|
248
|
+
|
|
249
|
+
const [chain, ...rest] = adjustedIdentifier.split('.') as [Chain, string];
|
|
250
|
+
const [ticker, address] = (isSynthetic ? synthSymbol : rest.join('.')).split('-') as [
|
|
251
|
+
string,
|
|
252
|
+
string?,
|
|
253
|
+
];
|
|
254
|
+
const symbol = isSynthetic ? synthSymbol : rest.join('.');
|
|
233
255
|
|
|
234
256
|
return {
|
|
235
257
|
address: address?.toLowerCase(),
|
|
236
258
|
chain,
|
|
237
259
|
isGasAsset: isGasAsset({ chain, symbol }),
|
|
238
260
|
isSynthetic,
|
|
239
|
-
symbol:
|
|
240
|
-
|
|
261
|
+
symbol:
|
|
262
|
+
(isSynthetic ? `${synthChain}/` : '') +
|
|
263
|
+
(address ? `${ticker}-${address?.toLowerCase() ?? ''}` : symbol),
|
|
264
|
+
ticker,
|
|
241
265
|
};
|
|
242
|
-
}
|
|
266
|
+
}
|