@swapkit/core 1.0.0-rc.7 → 1.0.0-rc.71

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,30 +1,27 @@
1
1
  {
2
2
  "author": "swapkit-oss-team",
3
3
  "dependencies": {
4
- "@swapkit/types": "1.0.0-rc.2",
5
- "@swapkit/helpers": "1.0.0-rc.3"
4
+ "@swapkit/helpers": "1.0.0-rc.55",
5
+ "@swapkit/types": "1.0.0-rc.30"
6
6
  },
7
7
  "description": "SwapKit Lib core",
8
8
  "devDependencies": {
9
- "@vitest/coverage-istanbul": "0.34.4",
10
- "ethers": "6.7.1",
11
- "vite": "4.4.9",
12
- "vite-plugin-top-level-await": "1.3.1",
13
- "vite-plugin-wasm": "3.2.2",
14
- "vitest": "0.34.4",
15
- "@internal/config": "0.0.0-internal.0",
16
- "@swapkit/api": "1.0.0-rc.2",
17
- "@swapkit/tokens": "1.0.0-rc.2",
18
- "@swapkit/toolbox-cosmos": "1.0.0-rc.5",
19
- "@swapkit/toolbox-evm": "1.0.0-rc.4",
20
- "@swapkit/toolbox-utxo": "1.0.0-rc.4"
9
+ "@vitest/coverage-istanbul": "1.0.4",
10
+ "vite": "5.0.7",
11
+ "vitest": "1.0.4",
12
+ "@internal/config": "null-rc.0",
13
+ "@swapkit/api": "1.0.0-rc.30",
14
+ "@swapkit/tokens": "1.0.0-rc.31",
15
+ "@swapkit/toolbox-cosmos": "1.0.0-rc.59",
16
+ "@swapkit/toolbox-evm": "1.0.0-rc.59",
17
+ "@swapkit/toolbox-utxo": "1.0.0-rc.58"
21
18
  },
22
19
  "peerDependencies": {
23
- "@swapkit/api": "1.0.0-rc.2",
24
- "@swapkit/tokens": "1.0.0-rc.2",
25
- "@swapkit/toolbox-cosmos": "1.0.0-rc.5",
26
- "@swapkit/toolbox-evm": "1.0.0-rc.4",
27
- "@swapkit/toolbox-utxo": "1.0.0-rc.4"
20
+ "@swapkit/api": "1.0.0-rc.30",
21
+ "@swapkit/tokens": "1.0.0-rc.31",
22
+ "@swapkit/toolbox-cosmos": "1.0.0-rc.59",
23
+ "@swapkit/toolbox-evm": "1.0.0-rc.59",
24
+ "@swapkit/toolbox-utxo": "1.0.0-rc.58"
28
25
  },
29
26
  "eslintConfig": {
30
27
  "extends": "../../../internal/eslint-config"
@@ -52,7 +49,7 @@
52
49
  "repository": "https://github.com/thorswap/SwapKit.git",
53
50
  "type": "module",
54
51
  "types": "./dist/index.d.ts",
55
- "version": "1.0.0-rc.7",
52
+ "version": "1.0.0-rc.71",
56
53
  "scripts": {
57
54
  "build": "NODE_OPTIONS=--max_old_space_size=16384 vite build",
58
55
  "clean": "rm -rf dist vite.config.ts.* .turbo node_modules",
@@ -4,25 +4,55 @@ import { describe, expect, test } from 'vitest';
4
4
  import { getExplorerAddressUrl, getExplorerTxUrl } from '../explorerUrls.ts';
5
5
 
6
6
  describe('Explorer URLs', () => {
7
- Object.values(Chain)
8
- .filter((c) => ![Chain.Litecoin, Chain.Dogecoin, Chain.Cosmos].includes(c))
9
- .forEach((chain) => {
10
- test(`getExplorerTxUrl returns correct URL for ${chain}`, () => {
11
- expect(getExplorerTxUrl({ chain, txHash: '0x12345' })).toBe(
12
- `${ChainToExplorerUrl[chain]}/tx/0x12345`,
13
- );
7
+ [Chain.Binance, Chain.Maya, Chain.Kujira, Chain.THORChain].forEach((chain) => {
8
+ test(`getExplorerTxUrl returns correct URL for ${chain}`, () => {
9
+ expect(getExplorerTxUrl({ chain, txHash: '0x123456789' })).toBe(
10
+ `${ChainToExplorerUrl[chain]}/tx/123456789`,
11
+ );
14
12
 
15
- expect(getExplorerAddressUrl({ chain, address: 'asdfg' })).toBe(
16
- `${ChainToExplorerUrl[chain]}/address/asdfg`,
17
- );
18
- });
13
+ expect(getExplorerAddressUrl({ chain, address: 'asdfg' })).toBe(
14
+ `${ChainToExplorerUrl[chain]}/address/asdfg`,
15
+ );
19
16
  });
17
+ });
18
+
19
+ [
20
+ Chain.Arbitrum,
21
+ Chain.Avalanche,
22
+ Chain.BinanceSmartChain,
23
+ Chain.Ethereum,
24
+ Chain.Optimism,
25
+ Chain.Polygon,
26
+ ].forEach((chain) => {
27
+ test(`getExplorerTxUrl returns correct URL for ${chain}`, () => {
28
+ expect(getExplorerTxUrl({ chain, txHash: '0x123456789' })).toBe(
29
+ `${ChainToExplorerUrl[chain]}/tx/0x123456789`,
30
+ );
31
+
32
+ expect(getExplorerAddressUrl({ chain, address: 'asdfg' })).toBe(
33
+ `${ChainToExplorerUrl[chain]}/address/asdfg`,
34
+ );
35
+ });
36
+ });
37
+
38
+ [Chain.Bitcoin, Chain.BitcoinCash, Chain.Dogecoin, Chain.Litecoin].forEach((chain) => {
39
+ test(`getExplorerTxUrl returns correct URL for ${chain}`, () => {
40
+ expect(getExplorerTxUrl({ chain, txHash: '0x123456789' })).toBe(
41
+ `${ChainToExplorerUrl[chain]}/transaction/0x123456789`,
42
+ );
43
+
44
+ expect(getExplorerAddressUrl({ chain, address: 'asdfg' })).toBe(
45
+ `${ChainToExplorerUrl[chain]}/address/asdfg`,
46
+ );
47
+ });
48
+ });
20
49
 
21
50
  test('getExplorerTxUrl throws Error for unsupported Chain', () => {
22
51
  expect(() =>
23
52
  getExplorerTxUrl({ chain: 'unsupported' as Chain, txHash: '0x12345' }),
24
53
  ).toThrowError('Unsupported chain: unsupported');
25
54
  });
55
+
26
56
  test('getExplorerAddressUrl throws Error for unsupported Chain', () => {
27
57
  expect(() =>
28
58
  getExplorerAddressUrl({ chain: 'unsupported' as Chain, address: 'asdfg' }),
@@ -34,17 +64,6 @@ describe('Explorer URLs', () => {
34
64
  );
35
65
  });
36
66
 
37
- test('getExplorerTxUrl returns correct URL for Litecoin', () => {
38
- expect(getExplorerTxUrl({ chain: Chain.Litecoin, txHash: 'efghi' })).toBe(
39
- 'https://ltc.bitaps.com/efghi',
40
- );
41
- });
42
- test('getExplorerAddressUrl returns correct URL for Litecoin', () => {
43
- expect(getExplorerAddressUrl({ chain: Chain.Litecoin, address: '12345' })).toBe(
44
- 'https://ltc.bitaps.com/12345',
45
- );
46
- });
47
-
48
67
  test('getExplorerTxUrl returns correct URL for Cosmos', () => {
49
68
  expect(getExplorerTxUrl({ chain: Chain.Cosmos, txHash: 'pqrst' })).toBe(
50
69
  'https://cosmos.bigdipper.live/transactions/pqrst',
@@ -55,15 +74,4 @@ describe('Explorer URLs', () => {
55
74
  'https://cosmos.bigdipper.live/account/zabcd',
56
75
  );
57
76
  });
58
-
59
- test('getExplorerTxUrl returns correct URL for Doge', () => {
60
- expect(getExplorerTxUrl({ chain: Chain.Dogecoin, txHash: 'uvwxy' })).toBe(
61
- 'https://blockchair.com/dogecoin/transaction/uvwxy',
62
- );
63
- });
64
- test('getExplorerAddressUrl returns correct URL for Doge', () => {
65
- expect(getExplorerAddressUrl({ chain: Chain.Dogecoin, address: 'efghi' })).toBe(
66
- 'https://blockchair.com/dogecoin/address/efghi',
67
- );
68
- });
69
77
  });
@@ -5,12 +5,10 @@ export const getExplorerTxUrl = ({ chain, txHash }: { txHash: string; chain: Cha
5
5
 
6
6
  switch (chain) {
7
7
  case Chain.Binance:
8
- case Chain.Bitcoin:
9
- case Chain.BitcoinCash:
10
8
  case Chain.Maya:
11
9
  case Chain.Kujira:
12
10
  case Chain.THORChain:
13
- return `${baseUrl}/tx/${txHash}`;
11
+ return `${baseUrl}/tx/${txHash.startsWith('0x') ? txHash.slice(2) : txHash}`;
14
12
 
15
13
  case Chain.Arbitrum:
16
14
  case Chain.Avalanche:
@@ -22,10 +20,12 @@ export const getExplorerTxUrl = ({ chain, txHash }: { txHash: string; chain: Cha
22
20
 
23
21
  case Chain.Cosmos:
24
22
  return `${baseUrl}/transactions/${txHash}`;
23
+
24
+ case Chain.Litecoin:
25
+ case Chain.Bitcoin:
26
+ case Chain.BitcoinCash:
25
27
  case Chain.Dogecoin:
26
28
  return `${baseUrl}/transaction/${txHash.toLowerCase()}`;
27
- case Chain.Litecoin:
28
- return `${baseUrl}/${txHash}`;
29
29
 
30
30
  default:
31
31
  throw new Error(`Unsupported chain: ${chain}`);
@@ -44,17 +44,16 @@ export const getExplorerAddressUrl = ({ chain, address }: { address: string; cha
44
44
  case Chain.BitcoinCash:
45
45
  case Chain.Dogecoin:
46
46
  case Chain.Ethereum:
47
+ case Chain.Kujira:
48
+ case Chain.Litecoin:
47
49
  case Chain.Maya:
48
50
  case Chain.Optimism:
49
51
  case Chain.Polygon:
50
- case Chain.Kujira:
51
52
  case Chain.THORChain:
52
53
  return `${baseUrl}/address/${address}`;
53
54
 
54
55
  case Chain.Cosmos:
55
56
  return `${baseUrl}/account/${address}`;
56
- case Chain.Litecoin:
57
- return `${baseUrl}/${address}`;
58
57
 
59
58
  default:
60
59
  throw new Error(`Unsupported chain: ${chain}`);
@@ -54,6 +54,18 @@ const getEmptyWalletStructure = () =>
54
54
  {} as Record<Chain, null>,
55
55
  );
56
56
 
57
+ const validateAddressType = async ({ chain, address }: { chain: Chain; address?: string }) => {
58
+ if (!address) return false;
59
+
60
+ switch (chain) {
61
+ case Chain.Bitcoin:
62
+ // filter out taproot addresses
63
+ return !address.startsWith('bc1p');
64
+ default:
65
+ return true;
66
+ }
67
+ };
68
+
57
69
  export class SwapKitCore<T = ''> {
58
70
  public connectedChains: Wallet = getEmptyWalletStructure();
59
71
  public connectedWallets: WalletMethods = getEmptyWalletStructure();
@@ -68,9 +80,8 @@ export class SwapKitCore<T = ''> {
68
80
  getWallet = <T extends Chain>(chain: Chain) => this.connectedWallets[chain] as WalletMethods[T];
69
81
  getExplorerAddressUrl = (chain: Chain, address: string) =>
70
82
  getExplorerAddressUrl({ chain, address });
71
- getBalance = async (chain: Chain, refresh?: boolean) => {
72
- if (!refresh) return this.connectedChains[chain]?.balance || [];
73
- const wallet = await this.getWalletByChain(chain);
83
+ getBalance = async (chain: Chain, potentialScamFilter?: boolean) => {
84
+ const wallet = await this.getWalletByChain(chain, potentialScamFilter);
74
85
 
75
86
  return wallet?.balance || [];
76
87
  };
@@ -80,8 +91,8 @@ export class SwapKitCore<T = ''> {
80
91
  const evmChain = quoteMode.startsWith('ERC20-')
81
92
  ? Chain.Ethereum
82
93
  : quoteMode.startsWith('ARC20-')
83
- ? Chain.Avalanche
84
- : Chain.BinanceSmartChain;
94
+ ? Chain.Avalanche
95
+ : Chain.BinanceSmartChain;
85
96
 
86
97
  if (!route.complete) throw new SwapKitError('core_swap_route_not_complete');
87
98
 
@@ -95,7 +106,6 @@ export class SwapKitCore<T = ''> {
95
106
  const transaction = streamSwap ? route?.streamingSwap?.transaction : route?.transaction;
96
107
  if (!transaction) throw new SwapKitError('core_swap_route_transaction_not_found');
97
108
 
98
- const { isHexString, parseUnits } = await import('ethers');
99
109
  const { data, from, to, value } = route.transaction;
100
110
 
101
111
  const params = {
@@ -103,11 +113,7 @@ export class SwapKitCore<T = ''> {
103
113
  from,
104
114
  to: to.toLowerCase(),
105
115
  chainId: BigInt(ChainToChainId[evmChain]),
106
- value: value
107
- ? new SwapKitNumber({
108
- value: !isHexString(value) ? parseUnits(value, 'wei').toString(16) : value,
109
- }).baseValueBigInt
110
- : 0n,
116
+ value: value ? BigInt(value) : 0n,
111
117
  };
112
118
 
113
119
  return walletMethods.sendTransaction(params, feeOptionKey) as Promise<string>;
@@ -121,13 +127,20 @@ export class SwapKitCore<T = ''> {
121
127
  const { address: recipient } = await this.#getInboundDataByChain(asset.chain);
122
128
  const {
123
129
  contract: router,
124
- calldata: { amountIn, memo, memoStreamingSwap },
130
+ calldata: { expiration, amountIn, memo, memoStreamingSwap },
125
131
  } = route;
126
132
 
127
133
  const assetValue = asset.add(SwapKitNumber.fromBigInt(BigInt(amountIn), asset.decimal));
128
134
  const swapMemo = (streamSwap ? memoStreamingSwap || memo : memo) as string;
129
135
 
130
- return this.deposit({ assetValue, memo: swapMemo, feeOptionKey, router, recipient });
136
+ return this.deposit({
137
+ expiration,
138
+ assetValue,
139
+ memo: swapMemo,
140
+ feeOptionKey,
141
+ router,
142
+ recipient,
143
+ });
131
144
  }
132
145
 
133
146
  if (SWAP_IN.includes(quoteMode)) {
@@ -148,9 +161,7 @@ export class SwapKitCore<T = ''> {
148
161
 
149
162
  const contract = await walletMethods.createContract?.(contractAddress, abi, provider);
150
163
 
151
- // TODO: (@Towan) Contract evm methods should be generic
152
- // @ts-expect-error
153
- const tx = await contract.populateTransaction.swapIn?.(
164
+ const tx = await contract.getFunction('swapIn').populateTransaction(
154
165
  ...getSwapInParams({
155
166
  streamSwap,
156
167
  toChecksumAddress,
@@ -170,21 +181,27 @@ export class SwapKitCore<T = ''> {
170
181
  }
171
182
  };
172
183
 
173
- getWalletByChain = async (chain: Chain) => {
184
+ getWalletByChain = async (chain: Chain, potentialScamFilter?: boolean) => {
174
185
  const address = this.getAddress(chain);
175
186
  if (!address) return null;
187
+ const defaultBalance = [AssetValue.fromChainOrSignature(chain)];
188
+ const walletType = this.connectedChains[chain]?.walletType as WalletOption;
176
189
 
177
- const balance = (await this.getWallet(chain)?.getBalance(address)) ?? [
178
- AssetValue.fromChainOrSignature(chain),
179
- ];
190
+ try {
191
+ const balance = await this.getWallet(chain)?.getBalance(address, potentialScamFilter);
180
192
 
181
- this.connectedChains[chain] = {
182
- address,
183
- balance,
184
- walletType: this.connectedChains[chain]?.walletType as WalletOption,
185
- };
193
+ this.connectedChains[chain] = {
194
+ address,
195
+ balance: balance?.length ? balance : defaultBalance,
196
+ walletType,
197
+ };
198
+
199
+ return { ...this.connectedChains[chain] };
200
+ } catch (error) {
201
+ console.error(error);
186
202
 
187
- return { ...this.connectedChains[chain] };
203
+ return { address, balance: defaultBalance, walletType };
204
+ }
188
205
  };
189
206
 
190
207
  approveAssetValue = (assetValue: AssetValue, contractAddress?: string) =>
@@ -215,6 +232,8 @@ export class SwapKitCore<T = ''> {
215
232
  }: CoreTxParams & { router?: string }) => {
216
233
  const { chain, symbol, ticker } = assetValue;
217
234
  const walletInstance = this.connectedWallets[chain];
235
+ if (!(await validateAddressType({ address: await walletInstance?.getAddress(), chain })))
236
+ throw new SwapKitError('core_transaction_invalid_sender_address');
218
237
  if (!walletInstance) throw new SwapKitError('core_wallet_connection_not_found');
219
238
 
220
239
  const params = this.#prepareTxParams({ assetValue, recipient, router, ...rest });
@@ -235,10 +254,10 @@ export class SwapKitCore<T = ''> {
235
254
  chain === Chain.Avalanche
236
255
  ? TCAvalancheDepositABI
237
256
  : chain === Chain.BinanceSmartChain
238
- ? TCBscDepositABI
239
- : TCEthereumVaultAbi;
257
+ ? TCBscDepositABI
258
+ : TCEthereumVaultAbi;
240
259
 
241
- return (await (
260
+ const response = await (
242
261
  walletInstance as EVMWallet<typeof AVAXToolbox | typeof ETHToolbox | typeof BSCToolbox>
243
262
  ).call({
244
263
  abi,
@@ -248,13 +267,17 @@ export class SwapKitCore<T = ''> {
248
267
  funcParams: [
249
268
  recipient,
250
269
  getChecksumAddressFromAsset({ chain, symbol, ticker }, chain),
251
- // TODO: (@Towan) Re-Check on that conversion 🙏
252
- assetValue.baseValueBigInt.toString(),
270
+ assetValue.getBaseValue('string'),
253
271
  params.memo,
254
- rest.expiration,
272
+ rest.expiration || parseInt(`${(new Date().getTime() + 15 * 60 * 1000) / 1000}`),
255
273
  ],
256
- txOverrides: { from: params.from, value: assetValue.baseValueBigInt },
257
- })) as Promise<string>;
274
+ txOverrides: {
275
+ from: params.from,
276
+ value: assetValue.isGasAsset ? assetValue.getBaseValue('bigint') : undefined,
277
+ },
278
+ });
279
+
280
+ return response as string;
258
281
  }
259
282
 
260
283
  default: {
@@ -269,10 +292,10 @@ export class SwapKitCore<T = ''> {
269
292
  const errorKey: Keys = isInsufficientFunds
270
293
  ? 'core_transaction_deposit_insufficient_funds_error'
271
294
  : isGas
272
- ? 'core_transaction_deposit_gas_error'
273
- : isServer
274
- ? 'core_transaction_deposit_server_error'
275
- : 'core_transaction_deposit_error';
295
+ ? 'core_transaction_deposit_gas_error'
296
+ : isServer
297
+ ? 'core_transaction_deposit_server_error'
298
+ : 'core_transaction_deposit_error';
276
299
 
277
300
  throw new SwapKitError(errorKey, error);
278
301
  }
@@ -323,7 +346,6 @@ export class SwapKitCore<T = ''> {
323
346
  };
324
347
 
325
348
  addLiquidity = async ({
326
- poolIdentifier,
327
349
  runeAssetValue,
328
350
  assetValue,
329
351
  runeAddr,
@@ -331,7 +353,6 @@ export class SwapKitCore<T = ''> {
331
353
  isPendingSymmAsset,
332
354
  mode = 'sym',
333
355
  }: {
334
- poolIdentifier: string;
335
356
  runeAssetValue: AssetValue;
336
357
  assetValue: AssetValue;
337
358
  isPendingSymmAsset?: boolean;
@@ -339,7 +360,7 @@ export class SwapKitCore<T = ''> {
339
360
  assetAddr?: string;
340
361
  mode?: 'sym' | 'rune' | 'asset';
341
362
  }) => {
342
- const [chain, ...symbolPath] = poolIdentifier.split('.') as [Chain, string];
363
+ const { chain, symbol } = assetValue;
343
364
  const isSym = mode === 'sym';
344
365
  const runeTransfer = runeAssetValue?.gt(0) && (isSym || mode === 'rune');
345
366
  const assetTransfer = assetValue?.gt(0) && (isSym || mode === 'asset');
@@ -355,13 +376,12 @@ export class SwapKitCore<T = ''> {
355
376
  }
356
377
 
357
378
  let runeTx, assetTx;
358
- const sharedParams = { chain, symbol: symbolPath.join('.') };
359
379
 
360
380
  if (runeTransfer && runeAssetValue) {
361
381
  try {
362
382
  runeTx = await this.#depositToPool({
363
383
  assetValue: runeAssetValue,
364
- memo: getMemoFor(MemoType.DEPOSIT, { ...sharedParams, address: assetAddress }),
384
+ memo: getMemoFor(MemoType.DEPOSIT, { chain, symbol, address: assetAddress }),
365
385
  });
366
386
  } catch (error) {
367
387
  throw new SwapKitError('core_transaction_add_liquidity_rune_error', error);
@@ -372,7 +392,7 @@ export class SwapKitCore<T = ''> {
372
392
  try {
373
393
  assetTx = await this.#depositToPool({
374
394
  assetValue,
375
- memo: getMemoFor(MemoType.DEPOSIT, { ...sharedParams, address: runeAddress }),
395
+ memo: getMemoFor(MemoType.DEPOSIT, { chain, symbol, address: runeAddress }),
376
396
  });
377
397
  } catch (error) {
378
398
  throw new SwapKitError('core_transaction_add_liquidity_asset_error', error);
@@ -382,6 +402,29 @@ export class SwapKitCore<T = ''> {
382
402
  return { runeTx, assetTx };
383
403
  };
384
404
 
405
+ addLiquidityPart = ({
406
+ assetValue,
407
+ poolAddress,
408
+ address,
409
+ symmetric,
410
+ }: {
411
+ assetValue: AssetValue;
412
+ address?: string;
413
+ poolAddress: string;
414
+ symmetric: boolean;
415
+ }) => {
416
+ if (symmetric && !address) {
417
+ throw new SwapKitError('core_transaction_add_liquidity_invalid_params');
418
+ }
419
+ const memo = getMemoFor(MemoType.DEPOSIT, {
420
+ chain: poolAddress.split('.')[0] as Chain,
421
+ symbol: poolAddress.split('.')[1],
422
+ address: symmetric ? address : '',
423
+ });
424
+
425
+ return this.#depositToPool({ assetValue, memo });
426
+ };
427
+
385
428
  withdraw = async ({
386
429
  memo,
387
430
  assetValue,
@@ -399,28 +442,22 @@ export class SwapKitCore<T = ''> {
399
442
  to === 'rune'
400
443
  ? AssetValue.fromChainOrSignature(Chain.THORChain)
401
444
  : (from === 'sym' && to === 'sym') || from === 'rune' || from === 'asset'
402
- ? undefined
403
- : assetValue;
445
+ ? undefined
446
+ : assetValue;
404
447
 
405
- try {
406
- const txHash = await this.#depositToPool({
407
- assetValue: getMinAmountByChain(from === 'asset' ? assetValue.chain : Chain.THORChain),
408
- memo:
409
- memo ||
410
- getMemoFor(MemoType.WITHDRAW, {
411
- symbol: assetValue.symbol,
412
- chain: assetValue.chain,
413
- ticker: assetValue.ticker,
414
- basisPoints: Math.max(10000, Math.round(percent * 100)),
415
- targetAssetString: targetAsset?.toString(),
416
- singleSide: false,
417
- }),
448
+ const value = getMinAmountByChain(from === 'asset' ? assetValue.chain : Chain.THORChain);
449
+ const memoString =
450
+ memo ||
451
+ getMemoFor(MemoType.WITHDRAW, {
452
+ symbol: assetValue.symbol,
453
+ chain: assetValue.chain,
454
+ ticker: assetValue.ticker,
455
+ basisPoints: Math.min(10000, Math.round(percent * 100)),
456
+ targetAssetString: targetAsset?.toString(),
457
+ singleSide: false,
418
458
  });
419
459
 
420
- return txHash;
421
- } catch (error) {
422
- throw new SwapKitError('core_transaction_withdraw_error', error);
423
- }
460
+ return this.#depositToPool({ assetValue: value, memo: memoString });
424
461
  };
425
462
 
426
463
  savings = async ({
@@ -440,10 +477,13 @@ export class SwapKitCore<T = ''> {
440
477
  symbol: assetValue.symbol,
441
478
  chain: assetValue.chain,
442
479
  singleSide: true,
443
- basisPoints: percent ? Math.max(10000, Math.round(percent * 100)) : undefined,
480
+ basisPoints: percent ? Math.min(10000, Math.round(percent * 100)) : undefined,
444
481
  });
445
482
 
446
- return this.#depositToPool({ assetValue, memo: memoString });
483
+ const value =
484
+ memoType === MemoType.DEPOSIT ? assetValue : getMinAmountByChain(assetValue.chain);
485
+
486
+ return this.#depositToPool({ memo: memoString, assetValue: value });
447
487
  };
448
488
 
449
489
  loan = ({
@@ -480,7 +520,7 @@ export class SwapKitCore<T = ''> {
480
520
  type === 'bond' ? MemoType.BOND : type === 'unbond' ? MemoType.UNBOND : MemoType.LEAVE;
481
521
  const memo = getMemoFor(memoType, {
482
522
  address,
483
- unbondAmount: type === 'unbond' ? assetValue.baseValueNumber : undefined,
523
+ unbondAmount: type === 'unbond' ? assetValue.getBaseValue('number') : undefined,
484
524
  });
485
525
 
486
526
  return this.#thorchainTransfer({
@@ -498,7 +538,7 @@ export class SwapKitCore<T = ''> {
498
538
  extend = ({ wallets, config, apis = {}, rpcUrls = {} }: ExtendParams<T>) => {
499
539
  try {
500
540
  wallets.forEach((wallet) => {
501
- // @ts-expect-error ANCHOR - Not Worth
541
+ // @ts-expect-error - this is fine as we are extending the class
502
542
  this[wallet.connectMethodName] = wallet.connect({
503
543
  addChain: this.#addConnectedChain,
504
544
  config: config || {},
@@ -612,7 +652,7 @@ export class SwapKitCore<T = ''> {
612
652
  };
613
653
 
614
654
  #approve = async <T = string>({
615
- assetValue: { baseValueBigInt, address, chain, isGasAsset, isSynthetic },
655
+ assetValue,
616
656
  type = 'checkOnly',
617
657
  contractAddress,
618
658
  }: {
@@ -620,6 +660,7 @@ export class SwapKitCore<T = ''> {
620
660
  type?: 'checkOnly' | 'approve';
621
661
  contractAddress?: string;
622
662
  }) => {
663
+ const { address, chain, isGasAsset, isSynthetic } = assetValue;
623
664
  const isEVMChain = [Chain.Ethereum, Chain.Avalanche, Chain.BinanceSmartChain].includes(chain);
624
665
  const isNativeEVM = isEVMChain && isGasAsset;
625
666
 
@@ -638,7 +679,7 @@ export class SwapKitCore<T = ''> {
638
679
  contractAddress || ((await this.#getInboundDataByChain(chain)).router as string);
639
680
 
640
681
  return walletAction({
641
- amount: baseValueBigInt,
682
+ amount: assetValue.getBaseValue('bigint'),
642
683
  assetAddress: address,
643
684
  from,
644
685
  spenderAddress,
@@ -1,4 +1,4 @@
1
- import { getRequest } from '@swapkit/helpers';
1
+ import { RequestClient } from '@swapkit/helpers';
2
2
  import type { Chain } from '@swapkit/types';
3
3
  import { ApiUrl } from '@swapkit/types';
4
4
 
@@ -21,11 +21,11 @@ type InboundAddressData = {
21
21
  export const getInboundData = (stagenet: boolean) => {
22
22
  const baseUrl = stagenet ? ApiUrl.ThornodeStagenet : ApiUrl.ThornodeMainnet;
23
23
 
24
- return getRequest<InboundAddressData>(`${baseUrl}/thorchain/inbound_addresses`);
24
+ return RequestClient.get<InboundAddressData>(`${baseUrl}/thorchain/inbound_addresses`);
25
25
  };
26
26
 
27
27
  export const getMimirData = (stagenet: boolean) => {
28
28
  const baseUrl = stagenet ? ApiUrl.ThornodeStagenet : ApiUrl.ThornodeMainnet;
29
29
 
30
- return getRequest<Record<string, number>>(`${baseUrl}/thorchain/mimir`);
30
+ return RequestClient.get<Record<string, number>>(`${baseUrl}/thorchain/mimir`);
31
31
  };
@@ -1 +0,0 @@
1
- "use strict";var nt=Object.defineProperty;var st=(e,t,r)=>t in e?nt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var j=(e,t,r)=>(st(e,typeof t!="symbol"?t+"":t,r),r),D=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var s=(e,t,r)=>(D(e,t,"read from private field"),r?r.call(e):t.get(e)),b=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},M=(e,t,r,i)=>(D(e,t,"write to private field"),i?i.call(e,r):t.set(e,r),r);var u=(e,t,r)=>(D(e,t,"access private method"),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Q="6.7.1";function ot(e,t,r){const i=t.split("|").map(o=>o.trim());for(let o=0;o<i.length;o++)switch(t){case"any":return;case"bigint":case"boolean":case"number":case"string":if(typeof e===t)return}const n=new Error(`invalid value for type ${t}`);throw n.code="INVALID_ARGUMENT",n.argument=`value.${r}`,n.value=e,n}function K(e,t,r){for(let i in t){let n=t[i];const o=r?r[i]:null;o&&ot(n,o,i),Object.defineProperty(e,i,{enumerable:!0,value:n,writable:!1})}}function x(e){if(e==null)return"null";if(Array.isArray(e))return"[ "+e.map(x).join(", ")+" ]";if(e instanceof Uint8Array){const t="0123456789abcdef";let r="0x";for(let i=0;i<e.length;i++)r+=t[e[i]>>4],r+=t[e[i]&15];return r}if(typeof e=="object"&&typeof e.toJSON=="function")return x(e.toJSON());switch(typeof e){case"boolean":case"symbol":return e.toString();case"bigint":return BigInt(e).toString();case"number":return e.toString();case"string":return JSON.stringify(e);case"object":{const t=Object.keys(e);return t.sort(),"{ "+t.map(r=>`${x(r)}: ${x(e[r])}`).join(", ")+" }"}}return"[ COULD NOT SERIALIZE ]"}function W(e,t,r){{const n=[];if(r){if("message"in r||"code"in r||"name"in r)throw new Error(`value will overwrite populated values: ${x(r)}`);for(const o in r){const l=r[o];n.push(o+"="+x(l))}}n.push(`code=${t}`),n.push(`version=${Q}`),n.length&&(e+=" ("+n.join(", ")+")")}let i;switch(t){case"INVALID_ARGUMENT":i=new TypeError(e);break;case"NUMERIC_FAULT":case"BUFFER_OVERRUN":i=new RangeError(e);break;default:i=new Error(e)}return K(i,{code:t}),r&&Object.assign(i,r),i}function g(e,t,r,i){if(!e)throw W(t,r,i)}function c(e,t,r,i){g(e,t,"INVALID_ARGUMENT",{argument:r,value:i})}["NFD","NFC","NFKD","NFKC"].reduce((e,t)=>{try{if("test".normalize(t)!=="test")throw new Error("bad");if(t==="NFD"){const r=String.fromCharCode(233).normalize("NFD"),i=String.fromCharCode(101,769);if(r!==i)throw new Error("broken")}e.push(t)}catch{}return e},[]);function Y(e,t,r){if(r==null&&(r=""),e!==t){let i=r,n="new";r&&(i+=".",n+=" "+r),g(!1,`private constructor; use ${i}from* methods`,"UNSUPPORTED_OPERATION",{operation:n})}}function ft(e,t,r){if(e instanceof Uint8Array)return r?new Uint8Array(e):e;if(typeof e=="string"&&e.match(/^0x([0-9a-f][0-9a-f])*$/i)){const i=new Uint8Array((e.length-2)/2);let n=2;for(let o=0;o<i.length;o++)i[o]=parseInt(e.substring(n,n+2),16),n+=2;return i}c(!1,"invalid BytesLike value",t||"value",e)}function tt(e,t){return ft(e,t,!1)}function ut(e,t){return!(typeof e!="string"||!e.match(/^0x[0-9A-Fa-f]*$/)||typeof t=="number"&&e.length!==2+2*t||t===!0&&e.length%2!==0)}const et=BigInt(0),E=BigInt(1),S=9007199254740991;function k(e,t){const r=q(e,"value"),i=BigInt(T(t,"width"));if(g(r>>i===et,"overflow","NUMERIC_FAULT",{operation:"fromTwos",fault:"overflow",value:e}),r>>i-E){const n=(E<<i)-E;return-((~r&n)+E)}return r}function z(e,t){const r=q(e,"value"),i=BigInt(T(t,"bits"));return r&(E<<i)-E}function V(e,t){switch(typeof e){case"bigint":return e;case"number":return c(Number.isInteger(e),"underflow",t||"value",e),c(e>=-S&&e<=S,"overflow",t||"value",e),BigInt(e);case"string":try{if(e==="")throw new Error("empty string");return e[0]==="-"&&e[1]!=="-"?-BigInt(e.substring(1)):BigInt(e)}catch(r){c(!1,`invalid BigNumberish string: ${r.message}`,t||"value",e)}}c(!1,"invalid BigNumberish value",t||"value",e)}function q(e,t){const r=V(e,t);return g(r>=et,"unsigned value cannot be negative","NUMERIC_FAULT",{fault:"overflow",operation:"getUint",value:e}),r}const X="0123456789abcdef";function rt(e){if(e instanceof Uint8Array){let t="0x0";for(const r of e)t+=X[r>>4],t+=X[r&15];return BigInt(t)}return V(e)}function T(e,t){switch(typeof e){case"bigint":return c(e>=-S&&e<=S,"overflow",t||"value",e),Number(e);case"number":return c(Number.isInteger(e),"underflow",t||"value",e),c(e>=-S&&e<=S,"overflow",t||"value",e),e;case"string":try{if(e==="")throw new Error("empty string");return T(BigInt(e),t)}catch(r){c(!1,`invalid numeric string: ${r.message}`,t||"value",e)}}c(!1,"invalid numeric value",t||"value",e)}const ct=BigInt(-1),d=BigInt(0),F=BigInt(1),lt=BigInt(5),B={};let A="0000";for(;A.length<80;)A+=A;function y(e){let t=A;for(;t.length<e;)t+=t;return BigInt("1"+t.substring(0,e))}function C(e,t,r){const i=BigInt(t.width);if(t.signed){const n=F<<i-F;g(r==null||e>=-n&&e<n,"overflow","NUMERIC_FAULT",{operation:r,fault:"overflow",value:e}),e>d?e=k(z(e,i),i):e=-k(z(-e,i),i)}else{const n=F<<i;g(r==null||e>=0&&e<n,"overflow","NUMERIC_FAULT",{operation:r,fault:"overflow",value:e}),e=(e%n+n)%n&n-F}return e}function P(e){typeof e=="number"&&(e=`fixed128x${e}`);let t=!0,r=128,i=18;if(typeof e=="string"){if(e!=="fixed")if(e==="ufixed")t=!1;else{const o=e.match(/^(u?)fixed([0-9]+)x([0-9]+)$/);c(o,"invalid fixed format","format",e),t=o[1]!=="u",r=parseInt(o[2]),i=parseInt(o[3])}}else if(e){const o=e,l=(h,R,it)=>o[h]==null?it:(c(typeof o[h]===R,"invalid fixed format ("+h+" not "+R+")","format."+h,o[h]),o[h]);t=l("signed","boolean",t),r=l("width","number",r),i=l("decimals","number",i)}c(r%8===0,"invalid FixedNumber width (not byte aligned)","format.width",r),c(i<=80,"invalid FixedNumber decimals (too large)","format.decimals",i);const n=(t?"":"u")+"fixed"+String(r)+"x"+String(i);return{signed:t,width:r,decimals:i,name:n}}function at(e,t){let r="";e<d&&(r="-",e*=ct);let i=e.toString();if(t===0)return r+i;for(;i.length<=t;)i=A+i;const n=i.length-t;for(i=i.substring(0,n)+"."+i.substring(n);i[0]==="0"&&i[1]!==".";)i=i.substring(1);for(;i[i.length-1]==="0"&&i[i.length-2]!==".";)i=i.substring(0,i.length-1);return r+i}var m,f,a,N,U,w,p,$,G,L,H,v,J,_,Z;const I=class I{constructor(t,r,i){b(this,N);b(this,w);b(this,$);b(this,L);b(this,v);b(this,_);j(this,"format");b(this,m,void 0);b(this,f,void 0);b(this,a,void 0);j(this,"_value");Y(t,B,"FixedNumber"),M(this,f,r),M(this,m,i);const n=at(r,i.decimals);K(this,{format:i.name,_value:n}),M(this,a,y(i.decimals))}get signed(){return s(this,m).signed}get width(){return s(this,m).width}get decimals(){return s(this,m).decimals}get value(){return s(this,f)}addUnsafe(t){return u(this,$,G).call(this,t)}add(t){return u(this,$,G).call(this,t,"add")}subUnsafe(t){return u(this,L,H).call(this,t)}sub(t){return u(this,L,H).call(this,t,"sub")}mulUnsafe(t){return u(this,v,J).call(this,t)}mul(t){return u(this,v,J).call(this,t,"mul")}mulSignal(t){u(this,N,U).call(this,t);const r=s(this,f)*s(t,f);return g(r%s(this,a)===d,"precision lost during signalling mul","NUMERIC_FAULT",{operation:"mulSignal",fault:"underflow",value:this}),u(this,w,p).call(this,r/s(this,a),"mulSignal")}divUnsafe(t){return u(this,_,Z).call(this,t)}div(t){return u(this,_,Z).call(this,t,"div")}divSignal(t){g(s(t,f)!==d,"division by zero","NUMERIC_FAULT",{operation:"div",fault:"divide-by-zero",value:this}),u(this,N,U).call(this,t);const r=s(this,f)*s(this,a);return g(r%s(t,f)===d,"precision lost during signalling div","NUMERIC_FAULT",{operation:"divSignal",fault:"underflow",value:this}),u(this,w,p).call(this,r/s(t,f),"divSignal")}cmp(t){let r=this.value,i=t.value;const n=this.decimals-t.decimals;return n>0?i*=y(n):n<0&&(r*=y(-n)),r<i?-1:r>i?1:0}eq(t){return this.cmp(t)===0}lt(t){return this.cmp(t)<0}lte(t){return this.cmp(t)<=0}gt(t){return this.cmp(t)>0}gte(t){return this.cmp(t)>=0}floor(){let t=s(this,f);return s(this,f)<d&&(t-=s(this,a)-F),t=s(this,f)/s(this,a)*s(this,a),u(this,w,p).call(this,t,"floor")}ceiling(){let t=s(this,f);return s(this,f)>d&&(t+=s(this,a)-F),t=s(this,f)/s(this,a)*s(this,a),u(this,w,p).call(this,t,"ceiling")}round(t){if(t==null&&(t=0),t>=this.decimals)return this;const r=this.decimals-t,i=lt*y(r-1);let n=this.value+i;const o=y(r);return n=n/o*o,C(n,s(this,m),"round"),new I(B,n,s(this,m))}isZero(){return s(this,f)===d}isNegative(){return s(this,f)<d}toString(){return this._value}toUnsafeFloat(){return parseFloat(this.toString())}toFormat(t){return I.fromString(this.toString(),t)}static fromValue(t,r,i){const n=r==null?0:T(r),o=P(i);let l=V(t,"value");const h=n-o.decimals;if(h>0){const R=y(h);g(l%R===d,"value loses precision for format","NUMERIC_FAULT",{operation:"fromValue",fault:"underflow",value:t}),l/=R}else h<0&&(l*=y(-h));return C(l,o,"fromValue"),new I(B,l,o)}static fromString(t,r){const i=t.match(/^(-?)([0-9]*)\.?([0-9]*)$/);c(i&&i[2].length+i[3].length>0,"invalid FixedNumber string value","value",t);const n=P(r);let o=i[2]||"0",l=i[3]||"";for(;l.length<n.decimals;)l+=A;g(l.substring(n.decimals).match(/^0*$/),"too many decimals for format","NUMERIC_FAULT",{operation:"fromString",fault:"underflow",value:t}),l=l.substring(0,n.decimals);const h=BigInt(i[1]+o+l);return C(h,n,"fromString"),new I(B,h,n)}static fromBytes(t,r){let i=rt(tt(t,"value"));const n=P(r);return n.signed&&(i=k(i,n.width)),C(i,n,"fromBytes"),new I(B,i,n)}};m=new WeakMap,f=new WeakMap,a=new WeakMap,N=new WeakSet,U=function(t){c(this.format===t.format,"incompatible format; use fixedNumber.toFormat","other",t)},w=new WeakSet,p=function(t,r){return t=C(t,s(this,m),r),new I(B,t,s(this,m))},$=new WeakSet,G=function(t,r){return u(this,N,U).call(this,t),u(this,w,p).call(this,s(this,f)+s(t,f),r)},L=new WeakSet,H=function(t,r){return u(this,N,U).call(this,t),u(this,w,p).call(this,s(this,f)-s(t,f),r)},v=new WeakSet,J=function(t,r){return u(this,N,U).call(this,t),u(this,w,p).call(this,s(this,f)*s(t,f)/s(this,a),r)},_=new WeakSet,Z=function(t,r){return g(s(t,f)!==d,"division by zero","NUMERIC_FAULT",{operation:"div",fault:"divide-by-zero",value:this}),u(this,N,U).call(this,t),u(this,w,p).call(this,s(this,f)*s(this,a)/s(t,f),r)};let O=I;const ht=["wei","kwei","mwei","gwei","szabo","finney","ether"];function gt(e,t){c(typeof e=="string","value must be a string","value",e);let r=18;if(typeof t=="string"){const i=ht.indexOf(t);c(i>=0,"invalid unit","unit",t),r=3*i}else t!=null&&(r=T(t,"unit"));return O.fromString(e,{decimals:r,width:512}).value}exports.FixedNumber=O;exports.assert=g;exports.assertArgument=c;exports.assertPrivate=Y;exports.defineProperties=K;exports.fromTwos=k;exports.getBigInt=V;exports.getBytes=tt;exports.getNumber=T;exports.getUint=q;exports.isHexString=ut;exports.makeError=W;exports.mask=z;exports.parseUnits=gt;exports.toBigInt=rt;exports.version=Q;