@swapkit/core 1.0.0-rc.120 → 1.0.0-rc.122

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/src/client/old.ts DELETED
@@ -1,854 +0,0 @@
1
- import type { ErrorKeys, QuoteRoute, ThornameRegisterParam } from "@swapkit/helpers";
2
- import {
3
- AssetValue,
4
- SwapKitApi,
5
- SwapKitError,
6
- SwapKitNumber,
7
- gasFeeMultiplier,
8
- getMemoFor,
9
- getMinAmountByChain,
10
- wrapWithThrow,
11
- } from "@swapkit/helpers";
12
- import type { CosmosLikeToolbox } from "@swapkit/toolbox-cosmos";
13
- import type { AVAXToolbox, BSCToolbox, ETHToolbox, EVMToolbox } from "@swapkit/toolbox-evm";
14
- import type { UTXOToolbox } from "@swapkit/toolbox-utxo";
15
- import type {
16
- AddChainWalletParams,
17
- EVMChain,
18
- EVMWalletOptions,
19
- ExtendParams,
20
- WalletOption,
21
- } from "@swapkit/types";
22
- import {
23
- AGG_SWAP,
24
- Chain,
25
- ChainToChainId,
26
- FeeOption,
27
- MemoType,
28
- SWAP_IN,
29
- SWAP_OUT,
30
- TCAvalancheDepositABI,
31
- TCBscDepositABI,
32
- TCEthereumVaultAbi,
33
- } from "@swapkit/types";
34
-
35
- import type { AGG_CONTRACT_ADDRESS } from "../aggregator/contracts/index.ts";
36
- import { lowercasedContractAbiMapping } from "../aggregator/contracts/index.ts";
37
- import { getSwapInParams } from "../aggregator/getSwapParams.ts";
38
-
39
- import { getExplorerAddressUrl, getExplorerTxUrl } from "../helpers/explorerUrls.ts";
40
- import type {
41
- CoreTxParams,
42
- EVMWallet,
43
- OldWallet,
44
- SwapWithRouteParams,
45
- ThorchainWallet,
46
- WalletMethods,
47
- } from "../types.ts";
48
-
49
- const getEmptyWalletStructure = () =>
50
- (Object.values(Chain) as Chain[]).reduce(
51
- (acc, chain) => {
52
- acc[chain] = null;
53
- return acc;
54
- },
55
- {} as Record<Chain, null>,
56
- );
57
-
58
- const validateAddressType = ({
59
- chain,
60
- address,
61
- }: {
62
- chain: Chain;
63
- address?: string;
64
- }) => {
65
- if (!address) return false;
66
-
67
- switch (chain) {
68
- case Chain.Bitcoin:
69
- // filter out taproot addresses
70
- return !address.startsWith("bc1p");
71
- default:
72
- return true;
73
- }
74
- };
75
-
76
- /**
77
- * @deprecated Use SwapKit instead (import { SwapKit } from "@swapkit/core")
78
- */
79
- export class SwapKitCore<T = ""> {
80
- public connectedChains: OldWallet = getEmptyWalletStructure();
81
- public connectedWallets: WalletMethods = getEmptyWalletStructure();
82
- public readonly stagenet: boolean = false;
83
-
84
- constructor({ stagenet }: { stagenet?: boolean } | undefined = {}) {
85
- this.stagenet = !!stagenet;
86
- }
87
-
88
- getAddress = (chain: Chain) => this.connectedChains[chain]?.address || "";
89
- getExplorerTxUrl = (chain: Chain, txHash: string) => getExplorerTxUrl({ chain, txHash });
90
- getWallet = <T extends Chain>(chain: Chain) => this.connectedWallets[chain] as WalletMethods[T];
91
- getExplorerAddressUrl = (chain: Chain, address: string) =>
92
- getExplorerAddressUrl({ chain, address });
93
- getBalance = async (chain: Chain, potentialScamFilter?: boolean) => {
94
- const wallet = await this.getWalletByChain(chain, potentialScamFilter);
95
-
96
- return wallet?.balance || [];
97
- };
98
-
99
- swap = async ({
100
- streamSwap,
101
- recipient,
102
- route,
103
- feeOptionKey = FeeOption.Average,
104
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
105
- }: SwapWithRouteParams) => {
106
- const {
107
- meta: { quoteMode },
108
- // evmTransactionDetails: contractCallParams,
109
- } = route as QuoteRoute;
110
- const evmChain = quoteMode.startsWith("ERC20-")
111
- ? Chain.Ethereum
112
- : quoteMode.startsWith("ARC20-")
113
- ? Chain.Avalanche
114
- : quoteMode.startsWith("BEP20-")
115
- ? Chain.BinanceSmartChain
116
- : undefined;
117
-
118
- if (!(route as QuoteRoute).complete) throw new SwapKitError("core_swap_route_not_complete");
119
-
120
- // TODO enable when BE is ready
121
- // if (contractCallParams && evmChain) {
122
- // const walletMethods = this.connectedWallets[evmChain];
123
-
124
- // if (!walletMethods?.call) {
125
- // throw new SwapKitError('core_wallet_connection_not_found');
126
- // }
127
-
128
- // const { contractAddress, contractMethod, contractParams, contractParamsStreaming } =
129
- // contractCallParams;
130
-
131
- // if (!(streamSwap ? contractParamsStreaming : contractParams)) {
132
- // throw new SwapKitError('core_swap_route_transaction_not_found');
133
- // }
134
-
135
- // return await walletMethods.call<string>({
136
- // contractAddress,
137
- // abi: lowercasedContractAbiMapping[contractAddress.toLowerCase()],
138
- // funcName: contractMethod,
139
- // funcParams: streamSwap ? contractParamsStreaming : contractParams,
140
- // });
141
- // }
142
-
143
- if (AGG_SWAP.includes(quoteMode) && evmChain) {
144
- const walletMethods = this.connectedWallets[evmChain];
145
- if (!walletMethods?.sendTransaction) {
146
- throw new SwapKitError("core_wallet_connection_not_found");
147
- }
148
-
149
- const transaction = streamSwap
150
- ? (route as QuoteRoute)?.streamingSwap?.transaction
151
- : (route as QuoteRoute)?.transaction;
152
- if (!transaction) throw new SwapKitError("core_swap_route_transaction_not_found");
153
-
154
- const { data, from, to, value } = (route as QuoteRoute).transaction;
155
-
156
- const params = {
157
- data,
158
- from,
159
- to: to.toLowerCase(),
160
- chainId: BigInt(ChainToChainId[evmChain]),
161
- value: value ? BigInt(value) : 0n,
162
- };
163
-
164
- return walletMethods.sendTransaction(params, feeOptionKey) as Promise<string>;
165
- }
166
-
167
- if (SWAP_OUT.includes(quoteMode)) {
168
- if (!(route as QuoteRoute).calldata.fromAsset)
169
- throw new SwapKitError("core_swap_asset_not_recognized");
170
- // @ts-expect-error
171
- const asset = await AssetValue.fromString((route as QuoteRoute).calldata.fromAsset);
172
- if (!asset) throw new SwapKitError("core_swap_asset_not_recognized");
173
-
174
- const { address: recipient } = await this.#getInboundDataByChain(asset.chain);
175
- const {
176
- contract: router,
177
- calldata: { expiration, amountIn, memo, memoStreamingSwap },
178
- } = route as QuoteRoute;
179
-
180
- const assetValue = asset.add(SwapKitNumber.fromBigInt(BigInt(amountIn), asset.decimal));
181
- const swapMemo = (streamSwap ? memoStreamingSwap || memo : memo) as string;
182
-
183
- return this.deposit({
184
- expiration,
185
- assetValue,
186
- memo: swapMemo,
187
- feeOptionKey,
188
- router,
189
- recipient,
190
- });
191
- }
192
-
193
- if (SWAP_IN.includes(quoteMode) && evmChain) {
194
- const { calldata, contract: contractAddress } = route as QuoteRoute;
195
- if (!contractAddress) throw new SwapKitError("core_swap_contract_not_found");
196
-
197
- const walletMethods = this.connectedWallets[evmChain];
198
- const from = this.getAddress(evmChain);
199
-
200
- if (!(walletMethods?.sendTransaction && from)) {
201
- throw new SwapKitError("core_wallet_connection_not_found");
202
- }
203
-
204
- const { getProvider, toChecksumAddress } = await import("@swapkit/toolbox-evm");
205
- const provider = getProvider(evmChain);
206
- const abi = lowercasedContractAbiMapping[contractAddress.toLowerCase()];
207
-
208
- if (!abi)
209
- throw new SwapKitError("core_swap_contract_not_supported", {
210
- contractAddress,
211
- });
212
-
213
- const contract = await walletMethods.createContract?.(contractAddress, abi, provider);
214
-
215
- const tx = await contract.getFunction("swapIn").populateTransaction(
216
- ...getSwapInParams({
217
- streamSwap,
218
- toChecksumAddress,
219
- contractAddress: contractAddress as AGG_CONTRACT_ADDRESS,
220
- recipient,
221
- calldata,
222
- }),
223
- { from },
224
- );
225
-
226
- return walletMethods.sendTransaction(tx, feeOptionKey) as Promise<string>;
227
- }
228
-
229
- throw new SwapKitError("core_swap_quote_mode_not_supported", { quoteMode });
230
- };
231
-
232
- getWalletByChain = async (chain: Chain, potentialScamFilter?: boolean) => {
233
- const address = this.getAddress(chain);
234
- if (!address) return null;
235
- const defaultBalance = [AssetValue.fromChainOrSignature(chain)];
236
- const walletType = this.connectedChains[chain]?.walletType as WalletOption;
237
-
238
- try {
239
- const balance = await this.getWallet(chain)?.getBalance(address, potentialScamFilter);
240
-
241
- this.connectedChains[chain] = {
242
- address,
243
- balance: balance?.length ? balance : defaultBalance,
244
- walletType,
245
- };
246
-
247
- return { ...this.connectedChains[chain] };
248
- } catch (error) {
249
- console.error(error);
250
-
251
- return { address, balance: defaultBalance, walletType };
252
- }
253
- };
254
-
255
- approveAssetValue = (assetValue: AssetValue, contractAddress?: string) =>
256
- this.#approve({ assetValue, type: "approve", contractAddress });
257
-
258
- isAssetValueApproved = (assetValue: AssetValue, contractAddress?: string) =>
259
- this.#approve<boolean>({ assetValue, contractAddress, type: "checkOnly" });
260
-
261
- validateAddress = ({ address, chain }: { address: string; chain: Chain }) =>
262
- this.getWallet(chain)?.validateAddress?.(address);
263
-
264
- transfer = async (params: CoreTxParams & { router?: string }) => {
265
- const walletInstance = this.connectedWallets[params.assetValue.chain];
266
- if (!walletInstance) throw new SwapKitError("core_wallet_connection_not_found");
267
-
268
- try {
269
- const tx = await walletInstance.transfer(this.#prepareTxParams(params));
270
-
271
- return tx;
272
- } catch (error) {
273
- throw new SwapKitError("core_swap_transaction_error", error);
274
- }
275
- };
276
-
277
- deposit = async ({
278
- assetValue,
279
- recipient,
280
- router,
281
- ...rest
282
- }: // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: TODO: Refactor
283
- CoreTxParams & { router?: string }) => {
284
- const { chain, symbol, ticker } = assetValue;
285
- const walletInstance = this.connectedWallets[chain];
286
- const connectedWallet = this.connectedChains[chain];
287
- const isAddressValidated = await validateAddressType({
288
- address: connectedWallet?.address,
289
- chain,
290
- });
291
-
292
- if (!isAddressValidated) {
293
- throw new SwapKitError("core_transaction_invalid_sender_address");
294
- }
295
- if (!walletInstance) {
296
- throw new SwapKitError("core_wallet_connection_not_found");
297
- }
298
-
299
- const params = this.#prepareTxParams({
300
- assetValue,
301
- recipient,
302
- router,
303
- ...rest,
304
- });
305
-
306
- try {
307
- switch (chain) {
308
- case Chain.THORChain:
309
- case Chain.Maya: {
310
- const wallet = walletInstance as ThorchainWallet;
311
- const tx = await (recipient === "" ? wallet.deposit(params) : wallet.transfer(params));
312
- return tx;
313
- }
314
-
315
- case Chain.Ethereum:
316
- case Chain.BinanceSmartChain:
317
- case Chain.Avalanche: {
318
- const { getChecksumAddressFromAsset } = await import("@swapkit/toolbox-evm");
319
-
320
- const abi =
321
- chain === Chain.Avalanche
322
- ? TCAvalancheDepositABI
323
- : chain === Chain.BinanceSmartChain
324
- ? TCBscDepositABI
325
- : TCEthereumVaultAbi;
326
-
327
- const wallet = walletInstance as EVMWallet<
328
- typeof AVAXToolbox | typeof ETHToolbox | typeof BSCToolbox
329
- >;
330
-
331
- const response = await wallet.call({
332
- abi,
333
- contractAddress:
334
- router || ((await this.#getInboundDataByChain(chain as EVMChain)).router as string),
335
- funcName: "depositWithExpiry",
336
- funcParams: [
337
- recipient,
338
- getChecksumAddressFromAsset({ chain, symbol, ticker }, chain),
339
- assetValue.getBaseValue("string"),
340
- params.memo,
341
- rest.expiration ||
342
- Number.parseInt(`${(new Date().getTime() + 15 * 60 * 1000) / 1000}`),
343
- ],
344
- txOverrides: {
345
- from: params.from,
346
- value: assetValue.isGasAsset ? assetValue.getBaseValue("bigint") : undefined,
347
- },
348
- });
349
-
350
- return response as string;
351
- }
352
-
353
- default: {
354
- const tx = await walletInstance.transfer(params);
355
- return tx;
356
- }
357
- }
358
- } catch (error) {
359
- const errorMessage =
360
- // @ts-expect-error - this is fine as we are checking for string
361
- typeof error === "string" ? error.toLowerCase() : error?.message?.toLowerCase();
362
-
363
- const isInsufficientFunds = errorMessage?.includes("insufficient funds");
364
- const isGas = errorMessage?.includes("gas");
365
- const isServer = errorMessage?.includes("server");
366
- const isUserRejected = errorMessage?.includes("user rejected");
367
- const errorKey: ErrorKeys = isInsufficientFunds
368
- ? "core_transaction_deposit_insufficient_funds_error"
369
- : isGas
370
- ? "core_transaction_deposit_gas_error"
371
- : isServer
372
- ? "core_transaction_deposit_server_error"
373
- : isUserRejected
374
- ? "core_transaction_user_rejected"
375
- : "core_transaction_deposit_error";
376
-
377
- throw new SwapKitError(errorKey, error);
378
- }
379
- };
380
-
381
- /**
382
- * TC related Methods
383
- */
384
- createLiquidity = async ({
385
- runeAssetValue,
386
- assetValue,
387
- }: {
388
- runeAssetValue: AssetValue;
389
- assetValue: AssetValue;
390
- }) => {
391
- if (runeAssetValue.lte(0) || assetValue.lte(0)) {
392
- throw new SwapKitError("core_transaction_create_liquidity_invalid_params");
393
- }
394
-
395
- const assetAddress = this.getAddress(assetValue.chain);
396
- const runeAddress = this.getAddress(Chain.THORChain);
397
-
398
- const runeTx = await wrapWithThrow(() => {
399
- return this.#depositToPool({
400
- assetValue: runeAssetValue,
401
- memo: getMemoFor(MemoType.DEPOSIT, { ...assetValue, address: assetAddress }),
402
- });
403
- }, "core_transaction_create_liquidity_rune_error");
404
-
405
- const assetTx = await wrapWithThrow(() => {
406
- return this.#depositToPool({
407
- assetValue,
408
- memo: getMemoFor(MemoType.DEPOSIT, { ...assetValue, address: runeAddress }),
409
- });
410
- }, "core_transaction_create_liquidity_asset_error");
411
-
412
- return { runeTx, assetTx };
413
- };
414
-
415
- addLiquidity = async ({
416
- runeAssetValue,
417
- assetValue,
418
- runeAddr,
419
- assetAddr,
420
- isPendingSymmAsset,
421
- mode = "sym",
422
- }: {
423
- runeAssetValue: AssetValue;
424
- assetValue: AssetValue;
425
- isPendingSymmAsset?: boolean;
426
- runeAddr?: string;
427
- assetAddr?: string;
428
- mode?: "sym" | "rune" | "asset";
429
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: TODO: Refactor
430
- }) => {
431
- const { chain, symbol } = assetValue;
432
- const isSym = mode === "sym";
433
- const runeTransfer = runeAssetValue?.gt(0) && (isSym || mode === "rune");
434
- const assetTransfer = assetValue?.gt(0) && (isSym || mode === "asset");
435
- const includeRuneAddress = isPendingSymmAsset || runeTransfer;
436
- const runeAddress = includeRuneAddress ? runeAddr || this.getAddress(Chain.THORChain) : "";
437
- const assetAddress = isSym || mode === "asset" ? assetAddr || this.getAddress(chain) : "";
438
-
439
- if (!(runeTransfer || assetTransfer)) {
440
- throw new SwapKitError("core_transaction_add_liquidity_invalid_params");
441
- }
442
- if (includeRuneAddress && !runeAddress) {
443
- throw new SwapKitError("core_transaction_add_liquidity_no_rune_address");
444
- }
445
-
446
- const runeTx = await wrapWithThrow(() => {
447
- return this.#depositToPool({
448
- assetValue: runeAssetValue,
449
- memo: getMemoFor(MemoType.DEPOSIT, { chain, symbol, address: assetAddress }),
450
- });
451
- }, "core_transaction_add_liquidity_rune_error");
452
-
453
- const assetTx =
454
- assetTransfer && assetValue
455
- ? wrapWithThrow(() => {
456
- return this.#depositToPool({
457
- assetValue,
458
- memo: getMemoFor(MemoType.DEPOSIT, { chain, symbol, address: runeAddress }),
459
- });
460
- }, "core_transaction_add_liquidity_asset_error")
461
- : null;
462
-
463
- return { runeTx, assetTx };
464
- };
465
-
466
- addLiquidityPart = ({
467
- assetValue,
468
- poolAddress,
469
- address,
470
- symmetric,
471
- }: {
472
- assetValue: AssetValue;
473
- address?: string;
474
- poolAddress: string;
475
- symmetric: boolean;
476
- }) => {
477
- if (symmetric && !address) {
478
- throw new SwapKitError("core_transaction_add_liquidity_invalid_params");
479
- }
480
-
481
- const memo = getMemoFor(MemoType.DEPOSIT, {
482
- chain: poolAddress.split(".")[0] as Chain,
483
- symbol: poolAddress.split(".")[1] as string,
484
- address: symmetric ? address : "",
485
- });
486
-
487
- return this.#depositToPool({ assetValue, memo });
488
- };
489
-
490
- withdraw = ({
491
- memo,
492
- assetValue,
493
- percent,
494
- from,
495
- to,
496
- }: {
497
- memo?: string;
498
- assetValue: AssetValue;
499
- percent: number;
500
- from: "sym" | "rune" | "asset";
501
- to: "sym" | "rune" | "asset";
502
- }) => {
503
- const targetAsset =
504
- to === "rune" && from !== "rune"
505
- ? AssetValue.fromChainOrSignature(Chain.THORChain)
506
- : (from === "sym" && to === "sym") || from === "rune" || from === "asset"
507
- ? undefined
508
- : assetValue;
509
-
510
- const value = getMinAmountByChain(from === "asset" ? assetValue.chain : Chain.THORChain);
511
- const memoString =
512
- memo ||
513
- getMemoFor(MemoType.WITHDRAW, {
514
- symbol: assetValue.symbol,
515
- chain: assetValue.chain,
516
- ticker: assetValue.ticker,
517
- basisPoints: Math.min(10000, Math.round(percent * 100)),
518
- targetAssetString: targetAsset?.toString(),
519
- singleSide: false,
520
- });
521
-
522
- return this.#depositToPool({ assetValue: value, memo: memoString });
523
- };
524
-
525
- savings = ({
526
- assetValue,
527
- memo,
528
- percent,
529
- type,
530
- }: { assetValue: AssetValue; memo?: string } & (
531
- | { type: "add"; percent?: undefined }
532
- | { type: "withdraw"; percent: number }
533
- )) => {
534
- const memoType = type === "add" ? MemoType.DEPOSIT : MemoType.WITHDRAW;
535
- const memoString =
536
- memo ||
537
- getMemoFor(memoType, {
538
- ticker: assetValue.ticker,
539
- symbol: assetValue.symbol,
540
- chain: assetValue.chain,
541
- singleSide: true,
542
- basisPoints: percent ? Math.min(10000, Math.round(percent * 100)) : undefined,
543
- });
544
-
545
- const value =
546
- memoType === MemoType.DEPOSIT ? assetValue : getMinAmountByChain(assetValue.chain);
547
-
548
- return this.#depositToPool({ memo: memoString, assetValue: value });
549
- };
550
-
551
- loan = ({
552
- assetValue,
553
- memo,
554
- minAmount,
555
- type,
556
- }: {
557
- assetValue: AssetValue;
558
- memo?: string;
559
- minAmount: AssetValue;
560
- type: "open" | "close";
561
- }) =>
562
- this.#depositToPool({
563
- assetValue,
564
- memo:
565
- memo ||
566
- getMemoFor(type === "open" ? MemoType.OPEN_LOAN : MemoType.CLOSE_LOAN, {
567
- asset: assetValue.toString(),
568
- minAmount: minAmount.toString(),
569
- address: this.getAddress(assetValue.chain),
570
- }),
571
- });
572
-
573
- nodeAction = ({
574
- type,
575
- assetValue,
576
- address,
577
- }: { address: string } & (
578
- | { type: "bond" | "unbond"; assetValue: AssetValue }
579
- | { type: "leave"; assetValue?: undefined }
580
- )) => {
581
- const memoType =
582
- type === "bond" ? MemoType.BOND : type === "unbond" ? MemoType.UNBOND : MemoType.LEAVE;
583
- const memo = getMemoFor(memoType, {
584
- address,
585
- unbondAmount: type === "unbond" ? assetValue.getBaseValue("number") : undefined,
586
- });
587
-
588
- return this.#thorchainTransfer({
589
- memo,
590
- assetValue: type === "bond" ? assetValue : getMinAmountByChain(Chain.THORChain),
591
- });
592
- };
593
-
594
- registerThorname = ({
595
- assetValue,
596
- ...param
597
- }: ThornameRegisterParam & { assetValue: AssetValue }) =>
598
- this.#thorchainTransfer({
599
- assetValue,
600
- memo: getMemoFor(MemoType.THORNAME_REGISTER, param),
601
- });
602
-
603
- registerMayaname = ({
604
- assetValue,
605
- ...param
606
- }: ThornameRegisterParam & { assetValue: AssetValue }) =>
607
- this.#mayachainTransfer({
608
- assetValue,
609
- memo: getMemoFor(MemoType.THORNAME_REGISTER, param),
610
- });
611
-
612
- extend = ({ wallets, config, apis = {}, rpcUrls = {} }: ExtendParams<T>) => {
613
- try {
614
- for (const wallet of wallets) {
615
- // @ts-expect-error - this is fine as we are extending the class
616
- this[wallet.connectMethodName] = wallet.connect({
617
- addChain: this.#addConnectedChain,
618
- config: config || {},
619
- apis,
620
- rpcUrls,
621
- });
622
- }
623
- } catch (error) {
624
- throw new SwapKitError("core_extend_error", error);
625
- }
626
- };
627
-
628
- estimateMaxSendableAmount = async ({
629
- chain,
630
- params,
631
- }: {
632
- chain: Chain;
633
- params: { from: string; recipient: string; assetValue: AssetValue };
634
- }) => {
635
- const walletMethods = this.getWallet<typeof chain>(chain);
636
-
637
- switch (chain) {
638
- case Chain.Arbitrum:
639
- case Chain.Avalanche:
640
- case Chain.BinanceSmartChain:
641
- case Chain.Ethereum:
642
- case Chain.Optimism:
643
- case Chain.Polygon: {
644
- const { estimateMaxSendableAmount } = await import("@swapkit/toolbox-evm");
645
- return estimateMaxSendableAmount({
646
- ...params,
647
- toolbox: walletMethods as EVMToolbox,
648
- });
649
- }
650
-
651
- case Chain.Bitcoin:
652
- case Chain.BitcoinCash:
653
- case Chain.Dogecoin:
654
- case Chain.Litecoin:
655
- return (walletMethods as UTXOToolbox).estimateMaxSendableAmount(params);
656
-
657
- case Chain.Binance:
658
- case Chain.THORChain:
659
- case Chain.Cosmos: {
660
- const { estimateMaxSendableAmount } = await import("@swapkit/toolbox-cosmos");
661
- return estimateMaxSendableAmount({
662
- ...params,
663
- toolbox: walletMethods as CosmosLikeToolbox,
664
- });
665
- }
666
-
667
- default:
668
- throw new SwapKitError("core_estimated_max_spendable_chain_not_supported");
669
- }
670
- };
671
-
672
- /**
673
- * Wallet connection methods
674
- */
675
- // biome-ignore lint/suspicious/useAwait: Extended methods
676
- connectXDEFI = async (_chains: Chain[]): Promise<void> => {
677
- throw new SwapKitError("core_wallet_xdefi_not_installed");
678
- };
679
- // biome-ignore lint/suspicious/useAwait: Extended methods
680
- connectEVMWallet = async (_chains: Chain[] | Chain, _wallet: EVMWalletOptions): Promise<void> => {
681
- throw new SwapKitError("core_wallet_evmwallet_not_installed");
682
- };
683
- // biome-ignore lint/suspicious/useAwait: Extended methods
684
- connectWalletconnect = async (_chains: Chain[], _options?: Todo): Promise<void> => {
685
- throw new SwapKitError("core_wallet_walletconnect_not_installed");
686
- };
687
- // biome-ignore lint/suspicious/useAwait: Extended methods
688
- connectKeepkey = async (_chains: Chain[], _derivationPath: number[][]): Promise<string> => {
689
- throw new SwapKitError("core_wallet_keepkey_not_installed");
690
- };
691
- // biome-ignore lint/suspicious/useAwait: Extended methods
692
- connectKeystore = async (_chains: Chain[], _phrase: string): Promise<void> => {
693
- throw new SwapKitError("core_wallet_keystore_not_installed");
694
- };
695
- // biome-ignore lint/suspicious/useAwait: Extended methods
696
- connectLedger = async (_chains: Chain, _derivationPath: number[]): Promise<void> => {
697
- throw new SwapKitError("core_wallet_ledger_not_installed");
698
- };
699
- // biome-ignore lint/suspicious/useAwait: Extended methods
700
- connectTrezor = async (_chains: Chain, _derivationPath: number[]): Promise<void> => {
701
- throw new SwapKitError("core_wallet_trezor_not_installed");
702
- };
703
- // biome-ignore lint/suspicious/useAwait: Extended methods
704
- connectKeplr = async (_chain: Chain): Promise<void> => {
705
- throw new SwapKitError("core_wallet_keplr_not_installed");
706
- };
707
- // biome-ignore lint/suspicious/useAwait: Extended methods
708
- connectOkx = async (_chains: Chain[]): Promise<void> => {
709
- throw new SwapKitError("core_wallet_okx_not_installed");
710
- };
711
-
712
- disconnectChain = (chain: Chain) => {
713
- this.connectedChains[chain] = null;
714
- this.connectedWallets[chain] = null;
715
- };
716
-
717
- #getInboundDataByChain = async (chain: Chain) => {
718
- switch (chain) {
719
- case Chain.Maya:
720
- case Chain.THORChain:
721
- return { gas_rate: "0", router: "", address: "", halted: false, chain };
722
-
723
- default: {
724
- const inboundData = await SwapKitApi.getInboundAddresses({ stagenet: this.stagenet });
725
- const chainAddressData = inboundData.find((item) => item.chain === chain);
726
-
727
- if (!chainAddressData) throw new SwapKitError("core_inbound_data_not_found");
728
- if (chainAddressData?.halted) throw new SwapKitError("core_chain_halted");
729
-
730
- return chainAddressData;
731
- }
732
- }
733
- };
734
-
735
- #addConnectedChain = ({
736
- chain,
737
- address,
738
- balance,
739
- walletType,
740
- ...rest
741
- }: AddChainWalletParams<Todo>) => {
742
- this.connectedChains[chain as Chain] = {
743
- address: address || "",
744
- balance: balance || [],
745
- walletType: walletType || "unknown",
746
- };
747
- this.connectedWallets[chain as Chain] = { ...rest } as Todo;
748
- };
749
-
750
- #approve = async <T = string>({
751
- assetValue,
752
- type = "checkOnly",
753
- contractAddress,
754
- }: {
755
- assetValue: AssetValue;
756
- type?: "checkOnly" | "approve";
757
- contractAddress?: string;
758
- }) => {
759
- const { address, chain, isGasAsset, isSynthetic } = assetValue;
760
- const isEVMChain = [Chain.Ethereum, Chain.Avalanche, Chain.BinanceSmartChain].includes(chain);
761
- const isNativeEVM = isEVMChain && isGasAsset;
762
-
763
- if (isNativeEVM || !isEVMChain || isSynthetic) return true;
764
-
765
- const walletMethods = this.connectedWallets[chain as EVMChain];
766
- const walletAction = type === "checkOnly" ? walletMethods?.isApproved : walletMethods?.approve;
767
-
768
- if (!walletAction) {
769
- throw new SwapKitError("core_wallet_connection_not_found");
770
- }
771
-
772
- const from = this.getAddress(chain);
773
-
774
- if (!(address && from)) {
775
- throw new SwapKitError("core_approve_asset_address_or_from_not_found");
776
- }
777
-
778
- const spenderAddress =
779
- contractAddress || ((await this.#getInboundDataByChain(chain)).router as string);
780
-
781
- return walletAction({
782
- amount: assetValue.getBaseValue("bigint"),
783
- assetAddress: address,
784
- from,
785
- spenderAddress,
786
- }) as Promise<T>;
787
- };
788
-
789
- #depositToPool = async ({
790
- assetValue,
791
- memo,
792
- feeOptionKey = FeeOption.Fast,
793
- }: {
794
- assetValue: AssetValue;
795
- memo: string;
796
- feeOptionKey?: FeeOption;
797
- }) => {
798
- const {
799
- gas_rate = "0",
800
- router,
801
- address: poolAddress,
802
- } = await this.#getInboundDataByChain(assetValue.chain);
803
- const feeRate = Number.parseInt(gas_rate) * gasFeeMultiplier[feeOptionKey];
804
-
805
- return this.deposit({
806
- assetValue,
807
- recipient: poolAddress,
808
- memo,
809
- router,
810
- feeRate,
811
- }) as Promise<string>;
812
- };
813
-
814
- #thorchainTransfer = async ({
815
- memo,
816
- assetValue,
817
- }: {
818
- assetValue: AssetValue;
819
- memo: string;
820
- }) => {
821
- const mimir = await SwapKitApi.getMimirInfo({ stagenet: this.stagenet });
822
-
823
- // check if trading is halted or not
824
- if (mimir.HALTCHAINGLOBAL >= 1 || mimir.HALTTHORCHAIN >= 1) {
825
- throw new SwapKitError("core_chain_halted");
826
- }
827
-
828
- return this.deposit({ assetValue, recipient: "", memo });
829
- };
830
-
831
- #mayachainTransfer = async ({
832
- memo,
833
- assetValue,
834
- }: {
835
- assetValue: AssetValue;
836
- memo: string;
837
- }) => {
838
- const mimir = await SwapKitApi.getMimirInfo({ type: "mayachain", stagenet: this.stagenet });
839
-
840
- // check if trading is halted or not
841
- if (mimir.HALTCHAINGLOBAL >= 1 || mimir.HALTTHORCHAIN >= 1) {
842
- throw new SwapKitError("core_chain_halted");
843
- }
844
-
845
- return this.deposit({ assetValue, recipient: "", memo });
846
- };
847
-
848
- #prepareTxParams = ({ assetValue, ...restTxParams }: CoreTxParams & { router?: string }) => ({
849
- ...restTxParams,
850
- memo: restTxParams.memo || "",
851
- from: this.getAddress(assetValue.chain),
852
- assetValue,
853
- });
854
- }