@swapkit/core 1.0.0-rc.9 → 1.0.0-rc.91

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.
@@ -1,4 +1,4 @@
1
- import type { Keys, ThornameRegisterParam } from '@swapkit/helpers';
1
+ import type { ErrorKeys, ThornameRegisterParam } from '@swapkit/helpers';
2
2
  import {
3
3
  AssetValue,
4
4
  gasFeeMultiplier,
@@ -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,123 +80,153 @@ 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
  };
77
88
 
78
89
  swap = async ({ streamSwap, recipient, route, feeOptionKey }: SwapParams) => {
79
- const { quoteMode } = route.meta;
90
+ const {
91
+ meta: { quoteMode },
92
+ // evmTransactionDetails: contractCallParams,
93
+ } = route;
80
94
  const evmChain = quoteMode.startsWith('ERC20-')
81
95
  ? Chain.Ethereum
82
96
  : quoteMode.startsWith('ARC20-')
83
- ? Chain.Avalanche
84
- : Chain.BinanceSmartChain;
97
+ ? Chain.Avalanche
98
+ : quoteMode.startsWith('BEP20-')
99
+ ? Chain.BinanceSmartChain
100
+ : undefined;
85
101
 
86
102
  if (!route.complete) throw new SwapKitError('core_swap_route_not_complete');
87
103
 
88
- try {
89
- if (AGG_SWAP.includes(quoteMode)) {
90
- const walletMethods = this.connectedWallets[evmChain];
91
- if (!walletMethods?.sendTransaction) {
92
- throw new SwapKitError('core_wallet_connection_not_found');
93
- }
94
-
95
- const transaction = streamSwap ? route?.streamingSwap?.transaction : route?.transaction;
96
- if (!transaction) throw new SwapKitError('core_swap_route_transaction_not_found');
97
-
98
- const { isHexString, parseUnits } = await import('ethers');
99
- const { data, from, to, value } = route.transaction;
100
-
101
- const params = {
102
- data,
103
- from,
104
- to: to.toLowerCase(),
105
- chainId: BigInt(ChainToChainId[evmChain]),
106
- value: value
107
- ? new SwapKitNumber({
108
- value: !isHexString(value) ? parseUnits(value, 'wei').toString(16) : value,
109
- }).baseValueBigInt
110
- : 0n,
111
- };
112
-
113
- return walletMethods.sendTransaction(params, feeOptionKey) as Promise<string>;
104
+ // TODO enable when BE is ready
105
+ // if (contractCallParams && evmChain) {
106
+ // const walletMethods = this.connectedWallets[evmChain];
107
+
108
+ // if (!walletMethods?.call) {
109
+ // throw new SwapKitError('core_wallet_connection_not_found');
110
+ // }
111
+
112
+ // const { contractAddress, contractMethod, contractParams, contractParamsStreaming } =
113
+ // contractCallParams;
114
+
115
+ // if (!(streamSwap ? contractParamsStreaming : contractParams)) {
116
+ // throw new SwapKitError('core_swap_route_transaction_not_found');
117
+ // }
118
+
119
+ // return await walletMethods.call<string>({
120
+ // contractAddress,
121
+ // abi: lowercasedContractAbiMapping[contractAddress.toLowerCase()],
122
+ // funcName: contractMethod,
123
+ // funcParams: streamSwap ? contractParamsStreaming : contractParams,
124
+ // });
125
+ // }
126
+
127
+ if (AGG_SWAP.includes(quoteMode) && evmChain) {
128
+ const walletMethods = this.connectedWallets[evmChain];
129
+ if (!walletMethods?.sendTransaction) {
130
+ throw new SwapKitError('core_wallet_connection_not_found');
114
131
  }
115
132
 
116
- if (SWAP_OUT.includes(quoteMode)) {
117
- if (!route.calldata.fromAsset) throw new SwapKitError('core_swap_asset_not_recognized');
118
- const asset = await AssetValue.fromString(route.calldata.fromAsset);
119
- if (!asset) throw new SwapKitError('core_swap_asset_not_recognized');
133
+ const transaction = streamSwap ? route?.streamingSwap?.transaction : route?.transaction;
134
+ if (!transaction) throw new SwapKitError('core_swap_route_transaction_not_found');
120
135
 
121
- const { address: recipient } = await this.#getInboundDataByChain(asset.chain);
122
- const {
123
- contract: router,
124
- calldata: { amountIn, memo, memoStreamingSwap },
125
- } = route;
136
+ const { data, from, to, value } = route.transaction;
126
137
 
127
- const assetValue = asset.add(SwapKitNumber.fromBigInt(BigInt(amountIn), asset.decimal));
128
- const swapMemo = (streamSwap ? memoStreamingSwap || memo : memo) as string;
138
+ const params = {
139
+ data,
140
+ from,
141
+ to: to.toLowerCase(),
142
+ chainId: BigInt(ChainToChainId[evmChain]),
143
+ value: value ? BigInt(value) : 0n,
144
+ };
129
145
 
130
- return this.deposit({ assetValue, memo: swapMemo, feeOptionKey, router, recipient });
131
- }
146
+ return walletMethods.sendTransaction(params, feeOptionKey) as Promise<string>;
147
+ }
132
148
 
133
- if (SWAP_IN.includes(quoteMode)) {
134
- const { calldata, contract: contractAddress } = route;
135
- if (!contractAddress) throw new SwapKitError('core_swap_contract_not_found');
149
+ if (SWAP_OUT.includes(quoteMode)) {
150
+ if (!route.calldata.fromAsset) throw new SwapKitError('core_swap_asset_not_recognized');
151
+ const asset = await AssetValue.fromString(route.calldata.fromAsset);
152
+ if (!asset) throw new SwapKitError('core_swap_asset_not_recognized');
136
153
 
137
- const walletMethods = this.connectedWallets[evmChain];
138
- const from = this.getAddress(evmChain);
139
- if (!walletMethods?.sendTransaction || !from) {
140
- throw new SwapKitError('core_wallet_connection_not_found');
141
- }
154
+ const { address: recipient } = await this.#getInboundDataByChain(asset.chain);
155
+ const {
156
+ contract: router,
157
+ calldata: { expiration, amountIn, memo, memoStreamingSwap },
158
+ } = route;
142
159
 
143
- const { getProvider, toChecksumAddress } = await import('@swapkit/toolbox-evm');
144
- const provider = getProvider(evmChain);
145
- const abi = lowercasedContractAbiMapping[contractAddress.toLowerCase()];
160
+ const assetValue = asset.add(SwapKitNumber.fromBigInt(BigInt(amountIn), asset.decimal));
161
+ const swapMemo = (streamSwap ? memoStreamingSwap || memo : memo) as string;
146
162
 
147
- if (!abi) throw new SwapKitError('core_swap_contract_not_supported', { contractAddress });
163
+ return this.deposit({
164
+ expiration,
165
+ assetValue,
166
+ memo: swapMemo,
167
+ feeOptionKey,
168
+ router,
169
+ recipient,
170
+ });
171
+ }
148
172
 
149
- const contract = await walletMethods.createContract?.(contractAddress, abi, provider);
173
+ if (SWAP_IN.includes(quoteMode) && evmChain) {
174
+ const { calldata, contract: contractAddress } = route;
175
+ if (!contractAddress) throw new SwapKitError('core_swap_contract_not_found');
150
176
 
151
- // TODO: (@Towan) Contract evm methods should be generic
152
- // @ts-expect-error
153
- const tx = await contract.populateTransaction.swapIn?.(
154
- ...getSwapInParams({
155
- streamSwap,
156
- toChecksumAddress,
157
- contractAddress: contractAddress as AGG_CONTRACT_ADDRESS,
158
- recipient,
159
- calldata,
160
- }),
161
- { from },
162
- );
177
+ const walletMethods = this.connectedWallets[evmChain];
178
+ const from = this.getAddress(evmChain);
163
179
 
164
- return walletMethods.sendTransaction(tx, feeOptionKey) as Promise<string>;
180
+ if (!walletMethods?.sendTransaction || !from) {
181
+ throw new SwapKitError('core_wallet_connection_not_found');
165
182
  }
166
183
 
167
- throw new SwapKitError('core_swap_quote_mode_not_supported', { quoteMode });
168
- } catch (error) {
169
- throw new SwapKitError('core_swap_transaction_error', error);
184
+ const { getProvider, toChecksumAddress } = await import('@swapkit/toolbox-evm');
185
+ const provider = getProvider(evmChain);
186
+ const abi = lowercasedContractAbiMapping[contractAddress.toLowerCase()];
187
+
188
+ if (!abi) throw new SwapKitError('core_swap_contract_not_supported', { contractAddress });
189
+
190
+ const contract = await walletMethods.createContract?.(contractAddress, abi, provider);
191
+
192
+ const tx = await contract.getFunction('swapIn').populateTransaction(
193
+ ...getSwapInParams({
194
+ streamSwap,
195
+ toChecksumAddress,
196
+ contractAddress: contractAddress as AGG_CONTRACT_ADDRESS,
197
+ recipient,
198
+ calldata,
199
+ }),
200
+ { from },
201
+ );
202
+
203
+ return walletMethods.sendTransaction(tx, feeOptionKey) as Promise<string>;
170
204
  }
205
+
206
+ throw new SwapKitError('core_swap_quote_mode_not_supported', { quoteMode });
171
207
  };
172
208
 
173
- getWalletByChain = async (chain: Chain) => {
209
+ getWalletByChain = async (chain: Chain, potentialScamFilter?: boolean) => {
174
210
  const address = this.getAddress(chain);
175
211
  if (!address) return null;
212
+ const defaultBalance = [AssetValue.fromChainOrSignature(chain)];
213
+ const walletType = this.connectedChains[chain]?.walletType as WalletOption;
176
214
 
177
- const balance = (await this.getWallet(chain)?.getBalance(address)) ?? [
178
- AssetValue.fromChainOrSignature(chain),
179
- ];
215
+ try {
216
+ const balance = await this.getWallet(chain)?.getBalance(address, potentialScamFilter);
180
217
 
181
- this.connectedChains[chain] = {
182
- address,
183
- balance,
184
- walletType: this.connectedChains[chain]?.walletType as WalletOption,
185
- };
218
+ this.connectedChains[chain] = {
219
+ address,
220
+ balance: balance?.length ? balance : defaultBalance,
221
+ walletType,
222
+ };
223
+
224
+ return { ...this.connectedChains[chain] };
225
+ } catch (error) {
226
+ console.error(error);
186
227
 
187
- return { ...this.connectedChains[chain] };
228
+ return { address, balance: defaultBalance, walletType };
229
+ }
188
230
  };
189
231
 
190
232
  approveAssetValue = (assetValue: AssetValue, contractAddress?: string) =>
@@ -215,13 +257,23 @@ export class SwapKitCore<T = ''> {
215
257
  }: CoreTxParams & { router?: string }) => {
216
258
  const { chain, symbol, ticker } = assetValue;
217
259
  const walletInstance = this.connectedWallets[chain];
260
+ const isAddressValidated = await validateAddressType({
261
+ address: await walletInstance?.getAddress(),
262
+ chain,
263
+ });
264
+
265
+ if (!isAddressValidated) {
266
+ throw new SwapKitError('core_transaction_invalid_sender_address');
267
+ }
268
+
218
269
  if (!walletInstance) throw new SwapKitError('core_wallet_connection_not_found');
219
270
 
220
271
  const params = this.#prepareTxParams({ assetValue, recipient, router, ...rest });
221
272
 
222
273
  try {
223
274
  switch (chain) {
224
- case Chain.THORChain: {
275
+ case Chain.THORChain:
276
+ case Chain.Maya: {
225
277
  const wallet = walletInstance as ThorchainWallet;
226
278
  return await (recipient === '' ? wallet.deposit(params) : wallet.transfer(params));
227
279
  }
@@ -235,10 +287,10 @@ export class SwapKitCore<T = ''> {
235
287
  chain === Chain.Avalanche
236
288
  ? TCAvalancheDepositABI
237
289
  : chain === Chain.BinanceSmartChain
238
- ? TCBscDepositABI
239
- : TCEthereumVaultAbi;
290
+ ? TCBscDepositABI
291
+ : TCEthereumVaultAbi;
240
292
 
241
- return (await (
293
+ const response = await (
242
294
  walletInstance as EVMWallet<typeof AVAXToolbox | typeof ETHToolbox | typeof BSCToolbox>
243
295
  ).call({
244
296
  abi,
@@ -248,13 +300,17 @@ export class SwapKitCore<T = ''> {
248
300
  funcParams: [
249
301
  recipient,
250
302
  getChecksumAddressFromAsset({ chain, symbol, ticker }, chain),
251
- // TODO: (@Towan) Re-Check on that conversion 🙏
252
- assetValue.baseValueBigInt.toString(),
303
+ assetValue.getBaseValue('string'),
253
304
  params.memo,
254
- rest.expiration,
305
+ rest.expiration || parseInt(`${(new Date().getTime() + 15 * 60 * 1000) / 1000}`),
255
306
  ],
256
- txOverrides: { from: params.from, value: assetValue.baseValueBigInt },
257
- })) as Promise<string>;
307
+ txOverrides: {
308
+ from: params.from,
309
+ value: assetValue.isGasAsset ? assetValue.getBaseValue('bigint') : undefined,
310
+ },
311
+ });
312
+
313
+ return response as string;
258
314
  }
259
315
 
260
316
  default: {
@@ -266,13 +322,16 @@ export class SwapKitCore<T = ''> {
266
322
  const isInsufficientFunds = errorMessage?.includes('insufficient funds');
267
323
  const isGas = errorMessage?.includes('gas');
268
324
  const isServer = errorMessage?.includes('server');
269
- const errorKey: Keys = isInsufficientFunds
325
+ const isUserRejected = errorMessage?.includes('user rejected');
326
+ const errorKey: ErrorKeys = isInsufficientFunds
270
327
  ? 'core_transaction_deposit_insufficient_funds_error'
271
328
  : isGas
272
- ? 'core_transaction_deposit_gas_error'
273
- : isServer
274
- ? 'core_transaction_deposit_server_error'
275
- : 'core_transaction_deposit_error';
329
+ ? 'core_transaction_deposit_gas_error'
330
+ : isServer
331
+ ? 'core_transaction_deposit_server_error'
332
+ : isUserRejected
333
+ ? 'core_transaction_user_rejected'
334
+ : 'core_transaction_deposit_error';
276
335
 
277
336
  throw new SwapKitError(errorKey, error);
278
337
  }
@@ -323,7 +382,6 @@ export class SwapKitCore<T = ''> {
323
382
  };
324
383
 
325
384
  addLiquidity = async ({
326
- poolIdentifier,
327
385
  runeAssetValue,
328
386
  assetValue,
329
387
  runeAddr,
@@ -331,7 +389,6 @@ export class SwapKitCore<T = ''> {
331
389
  isPendingSymmAsset,
332
390
  mode = 'sym',
333
391
  }: {
334
- poolIdentifier: string;
335
392
  runeAssetValue: AssetValue;
336
393
  assetValue: AssetValue;
337
394
  isPendingSymmAsset?: boolean;
@@ -339,7 +396,7 @@ export class SwapKitCore<T = ''> {
339
396
  assetAddr?: string;
340
397
  mode?: 'sym' | 'rune' | 'asset';
341
398
  }) => {
342
- const [chain, ...symbolPath] = poolIdentifier.split('.') as [Chain, string];
399
+ const { chain, symbol } = assetValue;
343
400
  const isSym = mode === 'sym';
344
401
  const runeTransfer = runeAssetValue?.gt(0) && (isSym || mode === 'rune');
345
402
  const assetTransfer = assetValue?.gt(0) && (isSym || mode === 'asset');
@@ -355,13 +412,12 @@ export class SwapKitCore<T = ''> {
355
412
  }
356
413
 
357
414
  let runeTx, assetTx;
358
- const sharedParams = { chain, symbol: symbolPath.join('.') };
359
415
 
360
416
  if (runeTransfer && runeAssetValue) {
361
417
  try {
362
418
  runeTx = await this.#depositToPool({
363
419
  assetValue: runeAssetValue,
364
- memo: getMemoFor(MemoType.DEPOSIT, { ...sharedParams, address: assetAddress }),
420
+ memo: getMemoFor(MemoType.DEPOSIT, { chain, symbol, address: assetAddress }),
365
421
  });
366
422
  } catch (error) {
367
423
  throw new SwapKitError('core_transaction_add_liquidity_rune_error', error);
@@ -372,7 +428,7 @@ export class SwapKitCore<T = ''> {
372
428
  try {
373
429
  assetTx = await this.#depositToPool({
374
430
  assetValue,
375
- memo: getMemoFor(MemoType.DEPOSIT, { ...sharedParams, address: runeAddress }),
431
+ memo: getMemoFor(MemoType.DEPOSIT, { chain, symbol, address: runeAddress }),
376
432
  });
377
433
  } catch (error) {
378
434
  throw new SwapKitError('core_transaction_add_liquidity_asset_error', error);
@@ -382,6 +438,29 @@ export class SwapKitCore<T = ''> {
382
438
  return { runeTx, assetTx };
383
439
  };
384
440
 
441
+ addLiquidityPart = ({
442
+ assetValue,
443
+ poolAddress,
444
+ address,
445
+ symmetric,
446
+ }: {
447
+ assetValue: AssetValue;
448
+ address?: string;
449
+ poolAddress: string;
450
+ symmetric: boolean;
451
+ }) => {
452
+ if (symmetric && !address) {
453
+ throw new SwapKitError('core_transaction_add_liquidity_invalid_params');
454
+ }
455
+ const memo = getMemoFor(MemoType.DEPOSIT, {
456
+ chain: poolAddress.split('.')[0] as Chain,
457
+ symbol: poolAddress.split('.')[1],
458
+ address: symmetric ? address : '',
459
+ });
460
+
461
+ return this.#depositToPool({ assetValue, memo });
462
+ };
463
+
385
464
  withdraw = async ({
386
465
  memo,
387
466
  assetValue,
@@ -396,31 +475,25 @@ export class SwapKitCore<T = ''> {
396
475
  to: 'sym' | 'rune' | 'asset';
397
476
  }) => {
398
477
  const targetAsset =
399
- to === 'rune'
478
+ to === 'rune' && from !== 'rune'
400
479
  ? AssetValue.fromChainOrSignature(Chain.THORChain)
401
480
  : (from === 'sym' && to === 'sym') || from === 'rune' || from === 'asset'
402
- ? undefined
403
- : assetValue;
481
+ ? undefined
482
+ : assetValue;
404
483
 
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
- }),
484
+ const value = getMinAmountByChain(from === 'asset' ? assetValue.chain : Chain.THORChain);
485
+ const memoString =
486
+ memo ||
487
+ getMemoFor(MemoType.WITHDRAW, {
488
+ symbol: assetValue.symbol,
489
+ chain: assetValue.chain,
490
+ ticker: assetValue.ticker,
491
+ basisPoints: Math.min(10000, Math.round(percent * 100)),
492
+ targetAssetString: targetAsset?.toString(),
493
+ singleSide: false,
418
494
  });
419
495
 
420
- return txHash;
421
- } catch (error) {
422
- throw new SwapKitError('core_transaction_withdraw_error', error);
423
- }
496
+ return this.#depositToPool({ assetValue: value, memo: memoString });
424
497
  };
425
498
 
426
499
  savings = async ({
@@ -440,10 +513,13 @@ export class SwapKitCore<T = ''> {
440
513
  symbol: assetValue.symbol,
441
514
  chain: assetValue.chain,
442
515
  singleSide: true,
443
- basisPoints: percent ? Math.max(10000, Math.round(percent * 100)) : undefined,
516
+ basisPoints: percent ? Math.min(10000, Math.round(percent * 100)) : undefined,
444
517
  });
445
518
 
446
- return this.#depositToPool({ assetValue, memo: memoString });
519
+ const value =
520
+ memoType === MemoType.DEPOSIT ? assetValue : getMinAmountByChain(assetValue.chain);
521
+
522
+ return this.#depositToPool({ memo: memoString, assetValue: value });
447
523
  };
448
524
 
449
525
  loan = ({
@@ -480,7 +556,7 @@ export class SwapKitCore<T = ''> {
480
556
  type === 'bond' ? MemoType.BOND : type === 'unbond' ? MemoType.UNBOND : MemoType.LEAVE;
481
557
  const memo = getMemoFor(memoType, {
482
558
  address,
483
- unbondAmount: type === 'unbond' ? assetValue.baseValueNumber : undefined,
559
+ unbondAmount: type === 'unbond' ? assetValue.getBaseValue('number') : undefined,
484
560
  });
485
561
 
486
562
  return this.#thorchainTransfer({
@@ -498,7 +574,7 @@ export class SwapKitCore<T = ''> {
498
574
  extend = ({ wallets, config, apis = {}, rpcUrls = {} }: ExtendParams<T>) => {
499
575
  try {
500
576
  wallets.forEach((wallet) => {
501
- // @ts-expect-error ANCHOR - Not Worth
577
+ // @ts-expect-error - this is fine as we are extending the class
502
578
  this[wallet.connectMethodName] = wallet.connect({
503
579
  addChain: this.#addConnectedChain,
504
580
  config: config || {},
@@ -567,6 +643,9 @@ export class SwapKitCore<T = ''> {
567
643
  connectWalletconnect = async (_chains: Chain[], _options?: any): Promise<void> => {
568
644
  throw new SwapKitError('core_wallet_walletconnect_not_installed');
569
645
  };
646
+ connectKeepkey = async (_chains: Chain[], _derivationPath: number[][]): Promise<string> => {
647
+ throw new SwapKitError('core_wallet_keepkey_not_installed');
648
+ };
570
649
  connectKeystore = async (_chains: Chain[], _phrase: string): Promise<void> => {
571
650
  throw new SwapKitError('core_wallet_keystore_not_installed');
572
651
  };
@@ -588,22 +667,21 @@ export class SwapKitCore<T = ''> {
588
667
  };
589
668
 
590
669
  #getInboundDataByChain = async (chain: Chain) => {
591
- if (chain === Chain.THORChain) {
592
- return {
593
- gas_rate: '0',
594
- router: '0',
595
- address: '',
596
- halted: false,
597
- chain: Chain.THORChain,
598
- };
599
- }
600
- const inboundData = await getInboundData(this.stagenet);
601
- const chainAddressData = inboundData.find((item) => item.chain === chain);
670
+ switch (chain) {
671
+ case Chain.Maya:
672
+ case Chain.THORChain:
673
+ return { gas_rate: '0', router: '', address: '', halted: false, chain };
674
+
675
+ default: {
676
+ const inboundData = await getInboundData(this.stagenet);
677
+ const chainAddressData = inboundData.find((item) => item.chain === chain);
602
678
 
603
- if (!chainAddressData) throw new SwapKitError('core_inbound_data_not_found');
604
- if (chainAddressData?.halted) throw new SwapKitError('core_chain_halted');
679
+ if (!chainAddressData) throw new SwapKitError('core_inbound_data_not_found');
680
+ if (chainAddressData?.halted) throw new SwapKitError('core_chain_halted');
605
681
 
606
- return chainAddressData;
682
+ return chainAddressData;
683
+ }
684
+ }
607
685
  };
608
686
 
609
687
  #addConnectedChain = ({ chain, wallet, walletMethods }: AddChainWalletParams) => {
@@ -612,7 +690,7 @@ export class SwapKitCore<T = ''> {
612
690
  };
613
691
 
614
692
  #approve = async <T = string>({
615
- assetValue: { baseValueBigInt, address, chain, isGasAsset, isSynthetic },
693
+ assetValue,
616
694
  type = 'checkOnly',
617
695
  contractAddress,
618
696
  }: {
@@ -620,6 +698,7 @@ export class SwapKitCore<T = ''> {
620
698
  type?: 'checkOnly' | 'approve';
621
699
  contractAddress?: string;
622
700
  }) => {
701
+ const { address, chain, isGasAsset, isSynthetic } = assetValue;
623
702
  const isEVMChain = [Chain.Ethereum, Chain.Avalanche, Chain.BinanceSmartChain].includes(chain);
624
703
  const isNativeEVM = isEVMChain && isGasAsset;
625
704
 
@@ -638,7 +717,7 @@ export class SwapKitCore<T = ''> {
638
717
  contractAddress || ((await this.#getInboundDataByChain(chain)).router as string);
639
718
 
640
719
  return walletAction({
641
- amount: baseValueBigInt,
720
+ amount: assetValue.getBaseValue('bigint'),
642
721
  assetAddress: address,
643
722
  from,
644
723
  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,5 +1,4 @@
1
- import type { QuoteRoute } from '@swapkit/api';
2
- import type { AssetValue, SwapKitNumber } from '@swapkit/helpers';
1
+ import type { AssetValue, QuoteRoute, SwapKitNumber } from '@swapkit/helpers';
3
2
  import type {
4
3
  BinanceToolbox,
5
4
  DepositParam,
@@ -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;