@swapkit/helpers 1.0.0-rc.3 → 1.0.0-rc.30

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/package.json CHANGED
@@ -1,20 +1,23 @@
1
1
  {
2
2
  "author": "swapkit-oss-team",
3
3
  "description": "SwapKit Lib swapkit-helpers",
4
+ "dependencies": {
5
+ "ky": "1.1.2"
6
+ },
4
7
  "devDependencies": {
5
8
  "@vitest/coverage-istanbul": "0.34.4",
6
9
  "vite": "4.4.9",
7
10
  "vitest": "0.34.4",
8
- "@internal/config": "0.0.0-internal.0",
9
- "@swapkit/tokens": "1.0.0-rc.2",
10
- "@swapkit/types": "1.0.0-rc.2"
11
+ "@internal/config": "0.0.0-rc.1",
12
+ "@swapkit/tokens": "1.0.0-rc.12",
13
+ "@swapkit/types": "1.0.0-rc.12"
11
14
  },
12
15
  "eslintConfig": {
13
16
  "extends": "../../../internal/eslint-config"
14
17
  },
15
18
  "peerDependencies": {
16
- "@swapkit/tokens": "1.0.0-rc.2",
17
- "@swapkit/types": "1.0.0-rc.2"
19
+ "@swapkit/tokens": "1.0.0-rc.12",
20
+ "@swapkit/types": "1.0.0-rc.12"
18
21
  },
19
22
  "exports": {
20
23
  ".": {
@@ -39,7 +42,7 @@
39
42
  "repository": "https://github.com/thorswap/SwapKit.git",
40
43
  "type": "module",
41
44
  "types": "./dist/index.d.ts",
42
- "version": "1.0.0-rc.3",
45
+ "version": "1.0.0-rc.30",
43
46
  "scripts": {
44
47
  "build": "vite build",
45
48
  "clean": "rm -rf dist vite.config.ts.* .turbo node_modules",
@@ -1,7 +1,7 @@
1
1
  import type { EVMChain } from '@swapkit/types';
2
- import { BaseDecimal, Chain, ChainToRPC, FeeOption } from '@swapkit/types';
2
+ import { BaseDecimal, Chain, ChainToRPC, EVMChainList, FeeOption } from '@swapkit/types';
3
3
 
4
- import { postRequest } from './others.ts';
4
+ import { RequestClient } from '../index.ts';
5
5
 
6
6
  const getDecimalMethodHex = '0x313ce567';
7
7
 
@@ -9,19 +9,19 @@ export type CommonAssetString = 'MAYA.MAYA' | 'ETH.THOR' | 'ETH.vTHOR' | Chain;
9
9
 
10
10
  const getContractDecimals = async ({ chain, to }: { chain: EVMChain; to: string }) => {
11
11
  try {
12
- const response = await postRequest<string>(
13
- ChainToRPC[chain],
14
- JSON.stringify({
15
- method: 'eth_call',
16
- params: [{ to: to.toLowerCase(), data: getDecimalMethodHex }, 'latest'],
12
+ const { result } = await RequestClient.post<{ result: string }>(ChainToRPC[chain], {
13
+ headers: {
14
+ accept: '*/*',
15
+ 'content-type': 'application/json',
16
+ 'cache-control': 'no-cache',
17
+ },
18
+ body: JSON.stringify({
17
19
  id: 44,
18
20
  jsonrpc: '2.0',
21
+ method: 'eth_call',
22
+ params: [{ to: to.toLowerCase(), data: getDecimalMethodHex }, 'latest'],
19
23
  }),
20
- { accept: '*/*', 'cache-control': 'no-cache', 'content-type': 'application/json' },
21
- true,
22
- );
23
-
24
- const { result } = JSON.parse(response) as { result: string };
24
+ });
25
25
 
26
26
  return parseInt(BigInt(result).toString());
27
27
  } catch (error) {
@@ -152,9 +152,9 @@ export const getAssetType = ({ chain, symbol }: { chain: Chain; symbol: string }
152
152
  return 'Native';
153
153
 
154
154
  case Chain.Cosmos:
155
- return symbol === 'ATOM' ? 'Native' : 'GAIA';
155
+ return symbol === 'ATOM' ? 'Native' : Chain.Cosmos;
156
156
  case Chain.Kujira:
157
- return symbol === 'KUJI' ? 'Native' : 'KUJI';
157
+ return symbol === Chain.Kujira ? 'Native' : Chain.Kujira;
158
158
  case Chain.Binance:
159
159
  return symbol === Chain.Binance ? 'Native' : 'BEP2';
160
160
  case Chain.BinanceSmartChain:
@@ -162,7 +162,7 @@ export const getAssetType = ({ chain, symbol }: { chain: Chain; symbol: string }
162
162
  case Chain.Ethereum:
163
163
  return symbol === Chain.Ethereum ? 'Native' : 'ERC20';
164
164
  case Chain.Avalanche:
165
- return symbol === Chain.Avalanche ? 'Native' : 'AVAX';
165
+ return symbol === Chain.Avalanche ? 'Native' : Chain.Avalanche;
166
166
  case Chain.Polygon:
167
167
  return symbol === Chain.Polygon ? 'Native' : 'POLYGON';
168
168
 
@@ -181,3 +181,34 @@ export const assetFromString = (assetString: string) => {
181
181
 
182
182
  return { chain, symbol, ticker, synth };
183
183
  };
184
+
185
+ const potentialScamRegex = new RegExp(
186
+ /(.)\1{6}|\.ORG|\.NET|\.FINANCE|\.COM|WWW|HTTP|\\\\|\/\/|[\s$%:[\]]/,
187
+ 'gmi',
188
+ );
189
+
190
+ const evmAssetHasAddress = (assetString: string) => {
191
+ const [chain, symbol] = assetString.split('.') as [EVMChain, string];
192
+ if (!EVMChainList.includes(chain as EVMChain)) return true;
193
+ const [, address] = symbol.split('-') as [string, string?];
194
+
195
+ return isGasAsset({ chain: chain as Chain, symbol }) || !!address;
196
+ };
197
+
198
+ export const filterAssets = (
199
+ tokens: {
200
+ value: string;
201
+ decimal: number;
202
+ chain: Chain;
203
+ symbol: string;
204
+ }[],
205
+ ) =>
206
+ tokens.filter((token) => {
207
+ const assetString = `${token.chain}.${token.symbol}`;
208
+
209
+ return (
210
+ !potentialScamRegex.test(assetString) &&
211
+ evmAssetHasAddress(assetString) &&
212
+ token.value !== '0'
213
+ );
214
+ });
@@ -81,7 +81,7 @@ export const getAsymmetricAssetWithdrawAmount = ({
81
81
  getAsymmetricAssetShare({ assetDepth, liquidityUnits, poolUnits }).mul(percent);
82
82
 
83
83
  const toTCSwapKitNumber = (value: string) =>
84
- new SwapKitNumber({ value, decimal: BaseDecimal.THOR });
84
+ SwapKitNumber.fromBigInt(BigInt(value), BaseDecimal.THOR);
85
85
 
86
86
  export const getSymmetricPoolShare = ({
87
87
  liquidityUnits,
@@ -126,11 +126,11 @@ export const getEstimatedPoolShare = ({
126
126
  runeDepth: string;
127
127
  assetDepth: string;
128
128
  }>) => {
129
- const R = toTCSwapKitNumber(runeDepth);
130
- const A = toTCSwapKitNumber(assetDepth);
131
- const P = toTCSwapKitNumber(poolUnits);
132
- const runeAddAmount = toTCSwapKitNumber(runeAmount);
133
- const assetAddAmount = toTCSwapKitNumber(assetAmount);
129
+ const R = new SwapKitNumber({ value: runeDepth, decimal: 8 });
130
+ const A = new SwapKitNumber({ value: assetDepth, decimal: 8 });
131
+ const P = new SwapKitNumber({ value: poolUnits, decimal: 8 });
132
+ const runeAddAmount = new SwapKitNumber({ value: runeAmount, decimal: 8 });
133
+ const assetAddAmount = new SwapKitNumber({ value: assetAmount, decimal: 8 });
134
134
 
135
135
  // liquidityUnits = P * (r*A + a*R + 2*r*a) / (r*A + a*R + 2*R*A)
136
136
  const rA = runeAddAmount.mul(A);
@@ -142,14 +142,14 @@ export const getEstimatedPoolShare = ({
142
142
  const liquidityUnitsAfterAdd = numerator.div(denominator);
143
143
  const estimatedLiquidityUnits = toTCSwapKitNumber(liquidityUnits).add(liquidityUnitsAfterAdd);
144
144
 
145
- if (liquidityUnitsAfterAdd.baseValueNumber === 0) {
146
- return estimatedLiquidityUnits.div(P).baseValueNumber;
145
+ if (liquidityUnitsAfterAdd.getBaseValue('number') === 0) {
146
+ return estimatedLiquidityUnits.div(P).getBaseValue('number');
147
147
  }
148
148
 
149
149
  // get pool units after add
150
150
  const newPoolUnits = P.add(estimatedLiquidityUnits);
151
151
 
152
- return estimatedLiquidityUnits.div(newPoolUnits).baseValueNumber;
152
+ return estimatedLiquidityUnits.div(newPoolUnits).getBaseValue('number');
153
153
  };
154
154
 
155
155
  export const getLiquiditySlippage = ({
@@ -158,6 +158,8 @@ export const getLiquiditySlippage = ({
158
158
  runeDepth,
159
159
  assetDepth,
160
160
  }: PoolParams) => {
161
+ if (runeAmount === '0' || assetAmount === '0' || runeDepth === '0' || assetDepth === '0')
162
+ return 0;
161
163
  // formula: (t * R - T * r)/ (T*r + R*T)
162
164
  const R = toTCSwapKitNumber(runeDepth);
163
165
  const T = toTCSwapKitNumber(assetDepth);
@@ -168,5 +170,5 @@ export const getLiquiditySlippage = ({
168
170
  const denominator = T.mul(runeAddAmount).add(R.mul(T));
169
171
 
170
172
  // set absolute value of percent, no negative allowed
171
- return Math.abs(numerator.div(denominator).baseValueNumber);
173
+ return Math.abs(numerator.div(denominator).getBaseValue('number'));
172
174
  };
@@ -18,51 +18,3 @@ export const derivationPathToString = ([network, chainId, account, change, index
18
18
 
19
19
  return `${network}'/${chainId}'/${account}'/${change}${shortPath ? '' : `/${index}`}`;
20
20
  };
21
-
22
- export const getRequest = async <T>(
23
- url: string,
24
- params?: { [key in string]?: any },
25
- ): Promise<T> => {
26
- try {
27
- const queryParams = Object.entries(params || {}).reduce(
28
- (acc, [key, value]) => {
29
- if (value) {
30
- acc[key] = value;
31
- }
32
-
33
- return acc;
34
- },
35
- {} as { [key in string]: any },
36
- );
37
-
38
- const response = await fetch(
39
- `${url}${params ? `?${new URLSearchParams(queryParams).toString()}` : ''}`,
40
- { method: 'GET', mode: 'cors', credentials: 'omit', referrer: 'https://sk.thorswap.net' },
41
- );
42
-
43
- return response.json();
44
- } catch (error) {
45
- console.error(error);
46
- return {} as T;
47
- }
48
- };
49
-
50
- export const postRequest = async <T>(
51
- url: string,
52
- body: string,
53
- headers?: Record<string, string>,
54
- parseAsString = false,
55
- ): Promise<T> => {
56
- try {
57
- const response = await fetch(`${url}`, {
58
- body,
59
- headers,
60
- method: 'POST',
61
- referrer: 'https://sk.thorswap.net',
62
- });
63
-
64
- return parseAsString ? response.text() : response.json();
65
- } catch (error) {
66
- return {} as T;
67
- }
68
- };
@@ -0,0 +1,15 @@
1
+ import type { Options } from 'ky';
2
+ import ky from 'ky';
3
+
4
+ const headers =
5
+ typeof window !== 'undefined'
6
+ ? {}
7
+ : { referrer: 'https://sk.thorswap.net', referer: 'https://sk.thorswap.net' };
8
+
9
+ const kyClient = ky.create({ headers });
10
+
11
+ export const RequestClient = {
12
+ get: <T>(url: string | URL | Request, options?: Options) => kyClient.get(url, options).json<T>(),
13
+ post: <T>(url: string | URL | Request, options?: Options) =>
14
+ kyClient.post(url, options).json<T>(),
15
+ };
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ export * from './helpers/asset.ts';
5
5
  export * from './helpers/liquidity.ts';
6
6
  export * from './helpers/memo.ts';
7
7
  export * from './helpers/others.ts';
8
+ export * from './helpers/request.ts';
8
9
 
9
10
  /**
10
11
  * Modules
@@ -1,7 +1,7 @@
1
1
  import { BaseDecimal, Chain } from '@swapkit/types';
2
2
  import { describe, expect, test } from 'vitest';
3
3
 
4
- import { AssetValue } from '../assetValue.ts';
4
+ import { AssetValue, getMinAmountByChain } from '../assetValue.ts';
5
5
 
6
6
  describe('AssetValue', () => {
7
7
  describe('assetValue', () => {
@@ -12,10 +12,13 @@ describe('AssetValue', () => {
12
12
  chain: Chain.Avalanche,
13
13
  symbol: 'USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e',
14
14
  });
15
- expect(fakeAvaxUSDCAsset.assetValue).toBe('1234567890 USDC');
15
+ expect(fakeAvaxUSDCAsset.toString(true)).toBe('USDC');
16
+ expect(fakeAvaxUSDCAsset.toString()).toBe(
17
+ 'AVAX.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e',
18
+ );
16
19
 
17
20
  const thor = AssetValue.fromChainOrSignature('ETH.THOR');
18
- expect(thor.assetValue).toBe('0 THOR');
21
+ expect(thor.toString(true)).toBe('THOR');
19
22
 
20
23
  const ethSynth = new AssetValue({
21
24
  chain: Chain.THORChain,
@@ -24,8 +27,9 @@ describe('AssetValue', () => {
24
27
  value: 1234567890,
25
28
  });
26
29
 
27
- expect(ethSynth.assetValue).toBe('1234567890 ETH/ETH');
28
30
  expect(ethSynth.toString()).toBe('THOR.ETH/ETH');
31
+ expect(ethSynth.toString(true)).toBe('ETH/ETH');
32
+ expect(ethSynth.mul(21.37).getValue('string')).toBe('26382715809.3');
29
33
 
30
34
  const atomDerived = new AssetValue({
31
35
  identifier: 'THOR.ATOM',
@@ -33,7 +37,7 @@ describe('AssetValue', () => {
33
37
  value: 123456789,
34
38
  });
35
39
 
36
- expect(atomDerived.assetValue).toBe('123456789 ATOM');
40
+ expect(atomDerived.toString(true)).toBe('ATOM');
37
41
  expect(atomDerived.toString()).toBe('THOR.ATOM');
38
42
  });
39
43
  });
@@ -70,17 +74,25 @@ describe('AssetValue', () => {
70
74
  });
71
75
  });
72
76
 
77
+ describe('from bigint', () => {
78
+ test('returns asset value with correct decimal', async () => {
79
+ const avaxUSDCAsset = await AssetValue.fromIdentifier(
80
+ `${Chain.Avalanche}.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e`,
81
+ 1234567800n,
82
+ );
83
+ expect(avaxUSDCAsset.getValue('string')).toBe('1234.5678');
84
+ });
85
+ });
86
+
73
87
  describe('toString', () => {
74
88
  test('returns asset value string/identifier', async () => {
75
- const fakeAvaxUSDCAsset = new AssetValue({
89
+ const avaxUSDCAsset = new AssetValue({
76
90
  decimal: 6,
77
91
  value: 1234567890,
78
92
  chain: Chain.Avalanche,
79
93
  symbol: 'USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e',
80
94
  });
81
- expect(fakeAvaxUSDCAsset.toString()).toBe(
82
- 'AVAX.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e',
83
- );
95
+ expect(avaxUSDCAsset.toString()).toBe('AVAX.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e');
84
96
 
85
97
  const thor = AssetValue.fromChainOrSignature('ETH.THOR');
86
98
  expect(thor.toString()).toBe('ETH.THOR-0xa5f2211b9b8170f694421f2046281775e8468044');
@@ -92,10 +104,11 @@ describe('AssetValue', () => {
92
104
 
93
105
  describe('fromIdentifier', () => {
94
106
  test('creates AssetValue from string', async () => {
95
- const fakeAvaxUSDCAssetString = 'AVAX.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e';
96
- const fakeAvaxUSDCAsset = await AssetValue.fromIdentifier(fakeAvaxUSDCAssetString);
107
+ const avaxUSDCAsset = await AssetValue.fromIdentifier(
108
+ 'AVAX.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e',
109
+ );
97
110
 
98
- expect(fakeAvaxUSDCAsset).toEqual(
111
+ expect(avaxUSDCAsset).toEqual(
99
112
  expect.objectContaining({
100
113
  address: '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e',
101
114
  chain: Chain.Avalanche,
@@ -293,3 +306,22 @@ describe('AssetValue', () => {
293
306
  });
294
307
  });
295
308
  });
309
+
310
+ describe('getMinAmountByChain', () => {
311
+ test('returns min amount for chain', () => {
312
+ expect(getMinAmountByChain(Chain.THORChain).getValue('string')).toBe('0');
313
+ expect(getMinAmountByChain(Chain.Maya).getValue('string')).toBe('0');
314
+ expect(getMinAmountByChain(Chain.Cosmos).getValue('string')).toBe('0');
315
+
316
+ expect(getMinAmountByChain(Chain.Bitcoin).getValue('string')).toBe('0.00010001');
317
+ expect(getMinAmountByChain(Chain.Litecoin).getValue('string')).toBe('0.00010001');
318
+ expect(getMinAmountByChain(Chain.BitcoinCash).getValue('string')).toBe('0.00010001');
319
+ expect(getMinAmountByChain(Chain.Dogecoin).getValue('string')).toBe('1.00000001');
320
+
321
+ expect(getMinAmountByChain(Chain.BinanceSmartChain).getValue('string')).toBe('0.00000001');
322
+ expect(getMinAmountByChain(Chain.Ethereum).getValue('string')).toBe('0.00000001');
323
+ expect(getMinAmountByChain(Chain.Avalanche).getValue('string')).toBe('0.00000001');
324
+ expect(getMinAmountByChain(Chain.Arbitrum).getValue('string')).toBe('0.00000001');
325
+ expect(getMinAmountByChain(Chain.Optimism).getValue('string')).toBe('0.00000001');
326
+ });
327
+ });