@swapkit/core 1.0.0-rc.1 → 1.0.0-rc.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +163 -29
- package/dist/index.es.js +6502 -1061
- package/dist/index.es.js.map +1 -0
- package/package.json +23 -30
- package/src/__tests__/helpers.test.ts +79 -0
- package/src/aggregator/contracts/avaxGeneric.ts +50 -50
- package/src/aggregator/contracts/avaxWoofi.ts +80 -80
- package/src/aggregator/contracts/bscGeneric.ts +59 -59
- package/src/aggregator/contracts/ethGeneric.ts +50 -50
- package/src/aggregator/contracts/index.ts +30 -28
- package/src/aggregator/contracts/pancakeV2.ts +80 -80
- package/src/aggregator/contracts/pangolin.ts +65 -65
- package/src/aggregator/contracts/routers/index.ts +58 -0
- package/src/aggregator/contracts/routers/kyber.ts +402 -0
- package/src/aggregator/contracts/routers/oneinch.ts +2188 -0
- package/src/aggregator/contracts/routers/pancakeswap.ts +340 -0
- package/src/aggregator/contracts/routers/pangolin.ts +340 -0
- package/src/aggregator/contracts/routers/sushiswap.ts +340 -0
- package/src/aggregator/contracts/routers/traderJoe.ts +340 -0
- package/src/aggregator/contracts/routers/uniswapv2.ts +340 -0
- package/src/aggregator/contracts/routers/uniswapv3.ts +254 -0
- package/src/aggregator/contracts/routers/woofi.ts +171 -0
- package/src/aggregator/contracts/sushiswap.ts +65 -65
- package/src/aggregator/contracts/traderJoe.ts +65 -65
- package/src/aggregator/contracts/uniswapV2.ts +65 -65
- package/src/aggregator/contracts/uniswapV2Leg.ts +70 -70
- package/src/aggregator/contracts/uniswapV3_100.ts +70 -70
- package/src/aggregator/contracts/uniswapV3_10000.ts +70 -70
- package/src/aggregator/contracts/uniswapV3_3000.ts +70 -70
- package/src/aggregator/contracts/uniswapV3_500.ts +70 -70
- package/src/aggregator/getSwapParams.ts +12 -12
- package/src/client/index.ts +214 -651
- package/src/client/old.ts +837 -0
- package/src/{client → helpers}/explorerUrls.ts +10 -9
- package/src/{client → helpers}/thornode.ts +5 -5
- package/src/index.ts +6 -4
- package/src/types.ts +149 -0
- package/dist/index-9e36735e.cjs +0 -1
- package/dist/index-cf1865cd.js +0 -649
- package/src/client/__tests__/helpers.test.ts +0 -69
- package/src/client/types.ts +0 -101
package/src/client/index.ts
CHANGED
|
@@ -1,690 +1,253 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
AssetValue,
|
|
4
|
-
gasFeeMultiplier,
|
|
5
|
-
getMemoFor,
|
|
6
|
-
getMinAmountByChain,
|
|
7
|
-
SwapKitError,
|
|
8
|
-
SwapKitNumber,
|
|
9
|
-
} from '@swapkit/helpers';
|
|
10
|
-
import type { CosmosLikeToolbox } from '@swapkit/toolbox-cosmos';
|
|
11
|
-
import type { AVAXToolbox, BSCToolbox, ETHToolbox, EVMToolbox } from '@swapkit/toolbox-evm';
|
|
12
|
-
import type { UTXOToolbox } from '@swapkit/toolbox-utxo';
|
|
1
|
+
import { AssetValue, SwapKitError } from "@swapkit/helpers";
|
|
2
|
+
import { Chain } from "@swapkit/types";
|
|
13
3
|
import type {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
FeeOption,
|
|
25
|
-
MemoType,
|
|
26
|
-
SWAP_IN,
|
|
27
|
-
SWAP_OUT,
|
|
28
|
-
TCAvalancheDepositABI,
|
|
29
|
-
TCBscDepositABI,
|
|
30
|
-
TCEthereumVaultAbi,
|
|
31
|
-
} from '@swapkit/types';
|
|
32
|
-
|
|
33
|
-
import type { AGG_CONTRACT_ADDRESS } from '../aggregator/contracts/index.ts';
|
|
34
|
-
import { lowercasedContractAbiMapping } from '../aggregator/contracts/index.ts';
|
|
35
|
-
import { getSwapInParams } from '../aggregator/getSwapParams.ts';
|
|
36
|
-
|
|
37
|
-
import { getExplorerAddressUrl, getExplorerTxUrl } from './explorerUrls.ts';
|
|
38
|
-
import { getInboundData, getMimirData } from './thornode.ts';
|
|
39
|
-
import type {
|
|
40
|
-
CoreTxParams,
|
|
41
|
-
EVMWallet,
|
|
42
|
-
SwapParams,
|
|
43
|
-
ThorchainWallet,
|
|
44
|
-
Wallet,
|
|
45
|
-
WalletMethods,
|
|
46
|
-
} from './types.ts';
|
|
47
|
-
|
|
48
|
-
const getEmptyWalletStructure = () =>
|
|
49
|
-
(Object.values(Chain) as Chain[]).reduce(
|
|
50
|
-
(acc, chain) => {
|
|
51
|
-
acc[chain] = null;
|
|
52
|
-
return acc;
|
|
53
|
-
},
|
|
54
|
-
{} as Record<Chain, null>,
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
export class SwapKitCore<T = ''> {
|
|
58
|
-
public connectedChains: Wallet = getEmptyWalletStructure();
|
|
59
|
-
public connectedWallets: WalletMethods = getEmptyWalletStructure();
|
|
60
|
-
public readonly stagenet: boolean = false;
|
|
61
|
-
|
|
62
|
-
constructor({ stagenet }: { stagenet?: boolean } | undefined = {}) {
|
|
63
|
-
this.stagenet = !!stagenet;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
getAddress = (chain: Chain) => this.connectedChains[chain]?.address || '';
|
|
67
|
-
getExplorerTxUrl = (chain: Chain, txHash: string) => getExplorerTxUrl({ chain, txHash });
|
|
68
|
-
getWallet = <T extends Chain>(chain: Chain) => this.connectedWallets[chain] as WalletMethods[T];
|
|
69
|
-
getExplorerAddressUrl = (chain: Chain, address: string) =>
|
|
70
|
-
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);
|
|
74
|
-
|
|
75
|
-
return wallet?.balance || [];
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
swap = async ({ streamSwap, recipient, route, feeOptionKey }: SwapParams) => {
|
|
79
|
-
const { quoteMode } = route.meta;
|
|
80
|
-
const evmChain = quoteMode.startsWith('ERC20-')
|
|
81
|
-
? Chain.Ethereum
|
|
82
|
-
: quoteMode.startsWith('ARC20-')
|
|
83
|
-
? Chain.Avalanche
|
|
84
|
-
: Chain.BinanceSmartChain;
|
|
85
|
-
|
|
86
|
-
if (!route.complete) throw new SwapKitError('core_swap_route_not_complete');
|
|
87
|
-
|
|
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>;
|
|
114
|
-
}
|
|
115
|
-
|
|
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');
|
|
120
|
-
|
|
121
|
-
const { address: recipient } = await this.#getInboundDataByChain(asset.chain);
|
|
122
|
-
const {
|
|
123
|
-
contract: router,
|
|
124
|
-
calldata: { amountIn, memo, memoStreamingSwap },
|
|
125
|
-
} = route;
|
|
126
|
-
|
|
127
|
-
const assetValue = asset.add(SwapKitNumber.fromBigInt(BigInt(amountIn), asset.decimal));
|
|
128
|
-
const swapMemo = (streamSwap ? memoStreamingSwap || memo : memo) as string;
|
|
129
|
-
|
|
130
|
-
return this.deposit({ assetValue, memo: swapMemo, feeOptionKey, router, recipient });
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (SWAP_IN.includes(quoteMode)) {
|
|
134
|
-
const { calldata, contract: contractAddress } = route;
|
|
135
|
-
if (!contractAddress) throw new SwapKitError('core_swap_contract_not_found');
|
|
136
|
-
|
|
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
|
-
}
|
|
142
|
-
|
|
143
|
-
const { getProvider, toChecksumAddress } = await import('@swapkit/toolbox-evm');
|
|
144
|
-
const provider = getProvider(evmChain);
|
|
145
|
-
const abi = lowercasedContractAbiMapping[contractAddress.toLowerCase()];
|
|
146
|
-
|
|
147
|
-
if (!abi) throw new SwapKitError('core_swap_contract_not_supported', { contractAddress });
|
|
148
|
-
|
|
149
|
-
const contract = await walletMethods.createContract?.(contractAddress, abi, provider);
|
|
150
|
-
|
|
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
|
-
);
|
|
163
|
-
|
|
164
|
-
return walletMethods.sendTransaction(tx, feeOptionKey) as Promise<string>;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
throw new SwapKitError('core_swap_quote_mode_not_supported', { quoteMode });
|
|
168
|
-
} catch (error) {
|
|
169
|
-
throw new SwapKitError('core_swap_transaction_error', error);
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
getWalletByChain = async (chain: Chain) => {
|
|
174
|
-
const address = this.getAddress(chain);
|
|
175
|
-
if (!address) return null;
|
|
176
|
-
|
|
177
|
-
const balance = (await this.getWallet(chain)?.getBalance(address)) ?? [
|
|
178
|
-
AssetValue.fromChainOrSignature(chain),
|
|
179
|
-
];
|
|
180
|
-
|
|
181
|
-
this.connectedChains[chain] = {
|
|
182
|
-
address,
|
|
183
|
-
balance,
|
|
184
|
-
walletType: this.connectedChains[chain]?.walletType as WalletOption,
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
return { ...this.connectedChains[chain] };
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
approveAssetValue = (assetValue: AssetValue, contractAddress?: string) =>
|
|
191
|
-
this.#approve({ assetValue, type: 'approve', contractAddress });
|
|
4
|
+
ChainWallet,
|
|
5
|
+
ConnectWalletParamsLocal as ConnectWalletParams,
|
|
6
|
+
SwapWithRouteParams,
|
|
7
|
+
} from "../types.ts";
|
|
8
|
+
|
|
9
|
+
type ProviderName = "thorchain" | "chainflip" | "mayachain";
|
|
10
|
+
enum ApproveMode {
|
|
11
|
+
Approve = "approve",
|
|
12
|
+
CheckOnly = "checkOnly",
|
|
13
|
+
}
|
|
192
14
|
|
|
193
|
-
|
|
194
|
-
|
|
15
|
+
type ApproveReturnType<T extends ApproveMode> = T extends "checkOnly"
|
|
16
|
+
? Promise<boolean>
|
|
17
|
+
: Promise<string>;
|
|
18
|
+
|
|
19
|
+
type SwapKitProviders = {
|
|
20
|
+
[K in ProviderName]?: ProviderMethods;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type GenericSwapParams = {
|
|
24
|
+
buyAsset: AssetValue;
|
|
25
|
+
sellAsset: AssetValue;
|
|
26
|
+
recipient: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type SwapParams = (SwapWithRouteParams | GenericSwapParams) & {
|
|
30
|
+
provider?: {
|
|
31
|
+
name: ProviderName;
|
|
32
|
+
config: Record<string, any>;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type SwapKitReturnType = SwapKitProviders & {
|
|
37
|
+
getAddress: (chain: Chain) => string;
|
|
38
|
+
getWallet: (chain: Chain) => ChainWallet<Chain> | undefined;
|
|
39
|
+
getWalletWithBalance: (
|
|
40
|
+
chain: Chain,
|
|
41
|
+
potentialScamFilter?: boolean,
|
|
42
|
+
) => Promise<ChainWallet<Chain>>;
|
|
43
|
+
getBalance: (chain: Chain, potentialScamFilter?: boolean) => AssetValue[];
|
|
44
|
+
swap: (params: SwapParams) => Promise<string>;
|
|
45
|
+
validateAddress: (params: { address: string; chain: Chain }) =>
|
|
46
|
+
| boolean
|
|
47
|
+
| Promise<boolean>
|
|
48
|
+
| undefined;
|
|
49
|
+
approveAssetValue: (assetValue: AssetValue, contractAddress: string) => boolean | Promise<string>;
|
|
50
|
+
isAssetValueApproved: (
|
|
51
|
+
assetValue: AssetValue,
|
|
52
|
+
contractAddress: string,
|
|
53
|
+
) => boolean | Promise<boolean>;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
type Wallets = { [K in Chain]?: ChainWallet<K> };
|
|
57
|
+
type AvailableProviders<T> = T | { [K in ProviderName]?: ProviderMethods };
|
|
58
|
+
type ProviderMethods = {
|
|
59
|
+
swap: (swapParams: SwapParams) => Promise<string>;
|
|
60
|
+
[key: string]: any;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type SwapKitProvider = ({ wallets, stagenet }: { wallets: Wallets; stagenet?: boolean }) => {
|
|
64
|
+
name: ProviderName;
|
|
65
|
+
methods: ProviderMethods;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
type BaseSwapkitWalletConnectParams = {
|
|
69
|
+
chains: Chain[];
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type KeystoreWalletConnectParams = BaseSwapkitWalletConnectParams & {
|
|
73
|
+
phrase: string;
|
|
74
|
+
index?: number;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
type WalletConnectParams = KeystoreWalletConnectParams;
|
|
78
|
+
|
|
79
|
+
type SwapKitWallet = {
|
|
80
|
+
connectMethodName: string;
|
|
81
|
+
connect: (params: ConnectWalletParams) => (connectParams: WalletConnectParams) => void;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export function SwapKit<
|
|
85
|
+
ExtendedProviders extends {},
|
|
86
|
+
ConnectWalletMethods extends Record<string, ReturnType<SwapKitWallet["connect"]>>,
|
|
87
|
+
>({
|
|
88
|
+
stagenet,
|
|
89
|
+
wallets,
|
|
90
|
+
providers,
|
|
91
|
+
config = {},
|
|
92
|
+
apis,
|
|
93
|
+
rpcUrls,
|
|
94
|
+
}: {
|
|
95
|
+
providers: SwapKitProvider[];
|
|
96
|
+
stagenet: boolean;
|
|
97
|
+
wallets: SwapKitWallet[];
|
|
98
|
+
config?: Record<string, any>;
|
|
99
|
+
apis: Record<string, any>;
|
|
100
|
+
rpcUrls: Record<string, any>;
|
|
101
|
+
}): SwapKitReturnType & ConnectWalletMethods {
|
|
102
|
+
const connectedWallets: Wallets = {};
|
|
103
|
+
const availableProviders: AvailableProviders<ExtendedProviders> = {};
|
|
104
|
+
|
|
105
|
+
for (const provider of providers) {
|
|
106
|
+
const { name, methods } = provider({ wallets: connectedWallets, stagenet });
|
|
107
|
+
|
|
108
|
+
availableProviders[name] = methods;
|
|
109
|
+
}
|
|
195
110
|
|
|
196
|
-
|
|
197
|
-
|
|
111
|
+
const connectWalletMethods = wallets.reduce((acc, wallet) => {
|
|
112
|
+
(acc[wallet.connectMethodName] as ReturnType<SwapKitWallet["connect"]>) = wallet.connect({
|
|
113
|
+
addChain,
|
|
114
|
+
config,
|
|
115
|
+
apis,
|
|
116
|
+
rpcUrls,
|
|
117
|
+
});
|
|
198
118
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if (!walletInstance) throw new SwapKitError('core_wallet_connection_not_found');
|
|
119
|
+
return acc;
|
|
120
|
+
}, {} as ConnectWalletMethods);
|
|
202
121
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
122
|
+
/**
|
|
123
|
+
* @Private
|
|
124
|
+
* Internal helpers
|
|
125
|
+
*/
|
|
126
|
+
function getProvider(providerName?: ProviderName) {
|
|
127
|
+
const provider =
|
|
128
|
+
(availableProviders as SwapKitProviders)[providerName as ProviderName] ||
|
|
129
|
+
Object.values(availableProviders)[0];
|
|
130
|
+
|
|
131
|
+
if (!provider) {
|
|
132
|
+
throw new SwapKitError(
|
|
133
|
+
"core_swap_provider_not_found",
|
|
134
|
+
"Could not find the requested provider",
|
|
135
|
+
);
|
|
207
136
|
}
|
|
208
|
-
};
|
|
209
137
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
recipient,
|
|
213
|
-
router,
|
|
214
|
-
...rest
|
|
215
|
-
}: CoreTxParams & { router?: string }) => {
|
|
216
|
-
const { chain, symbol, ticker } = assetValue;
|
|
217
|
-
const walletInstance = this.connectedWallets[chain];
|
|
218
|
-
if (!walletInstance) throw new SwapKitError('core_wallet_connection_not_found');
|
|
219
|
-
|
|
220
|
-
const params = this.#prepareTxParams({ assetValue, recipient, router, ...rest });
|
|
138
|
+
return provider;
|
|
139
|
+
}
|
|
221
140
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const wallet = walletInstance as ThorchainWallet;
|
|
226
|
-
return await (recipient === '' ? wallet.deposit(params) : wallet.transfer(params));
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
case Chain.Ethereum:
|
|
230
|
-
case Chain.BinanceSmartChain:
|
|
231
|
-
case Chain.Avalanche: {
|
|
232
|
-
const { getChecksumAddressFromAsset } = await import('@swapkit/toolbox-evm');
|
|
233
|
-
|
|
234
|
-
const abi =
|
|
235
|
-
chain === Chain.Avalanche
|
|
236
|
-
? TCAvalancheDepositABI
|
|
237
|
-
: chain === Chain.BinanceSmartChain
|
|
238
|
-
? TCBscDepositABI
|
|
239
|
-
: TCEthereumVaultAbi;
|
|
240
|
-
|
|
241
|
-
return (await (
|
|
242
|
-
walletInstance as EVMWallet<typeof AVAXToolbox | typeof ETHToolbox | typeof BSCToolbox>
|
|
243
|
-
).call({
|
|
244
|
-
abi,
|
|
245
|
-
contractAddress:
|
|
246
|
-
router || ((await this.#getInboundDataByChain(chain as EVMChain)).router as string),
|
|
247
|
-
funcName: 'depositWithExpiry',
|
|
248
|
-
funcParams: [
|
|
249
|
-
recipient,
|
|
250
|
-
getChecksumAddressFromAsset({ chain, symbol, ticker }, chain),
|
|
251
|
-
// TODO: (@Towan) Re-Check on that conversion 🙏
|
|
252
|
-
assetValue.baseValueBigInt.toString(),
|
|
253
|
-
params.memo,
|
|
254
|
-
rest.expiration,
|
|
255
|
-
],
|
|
256
|
-
txOverrides: { from: params.from, value: assetValue.baseValueBigInt },
|
|
257
|
-
})) as Promise<string>;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
default: {
|
|
261
|
-
return await walletInstance.transfer(params);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
} catch (error: any) {
|
|
265
|
-
const errorMessage = (error?.message || error?.toString()).toLowerCase();
|
|
266
|
-
const isInsufficientFunds = errorMessage?.includes('insufficient funds');
|
|
267
|
-
const isGas = errorMessage?.includes('gas');
|
|
268
|
-
const isServer = errorMessage?.includes('server');
|
|
269
|
-
const errorKey: Keys = isInsufficientFunds
|
|
270
|
-
? 'core_transaction_deposit_insufficient_funds_error'
|
|
271
|
-
: isGas
|
|
272
|
-
? 'core_transaction_deposit_gas_error'
|
|
273
|
-
: isServer
|
|
274
|
-
? 'core_transaction_deposit_server_error'
|
|
275
|
-
: 'core_transaction_deposit_error';
|
|
276
|
-
|
|
277
|
-
throw new SwapKitError(errorKey, error);
|
|
278
|
-
}
|
|
279
|
-
};
|
|
141
|
+
function addChain(connectWallet: ChainWallet<Chain>) {
|
|
142
|
+
(connectedWallets[connectWallet.chain as Chain] as ChainWallet<Chain>) = connectWallet;
|
|
143
|
+
}
|
|
280
144
|
|
|
281
145
|
/**
|
|
282
|
-
*
|
|
146
|
+
* @Private
|
|
147
|
+
* Wallet interaction helpers
|
|
283
148
|
*/
|
|
284
|
-
|
|
285
|
-
runeAssetValue,
|
|
149
|
+
function approve<T extends ApproveMode>({
|
|
286
150
|
assetValue,
|
|
151
|
+
type = "checkOnly" as T,
|
|
152
|
+
contractAddress,
|
|
287
153
|
}: {
|
|
288
|
-
|
|
154
|
+
type: T;
|
|
289
155
|
assetValue: AssetValue;
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
let runeTx = '';
|
|
296
|
-
let assetTx = '';
|
|
156
|
+
contractAddress: string;
|
|
157
|
+
}): ApproveReturnType<T> {
|
|
158
|
+
const { address, chain, isGasAsset, isSynthetic } = assetValue;
|
|
159
|
+
const isEVMChain = [Chain.Ethereum, Chain.Avalanche, Chain.BinanceSmartChain].includes(chain);
|
|
160
|
+
const isNativeEVM = isEVMChain && isGasAsset;
|
|
297
161
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
assetValue: runeAssetValue,
|
|
301
|
-
memo: getMemoFor(MemoType.DEPOSIT, {
|
|
302
|
-
...assetValue,
|
|
303
|
-
address: this.getAddress(assetValue.chain),
|
|
304
|
-
}),
|
|
305
|
-
});
|
|
306
|
-
} catch (error) {
|
|
307
|
-
throw new SwapKitError('core_transaction_create_liquidity_rune_error', error);
|
|
162
|
+
if (isNativeEVM || !isEVMChain || isSynthetic) {
|
|
163
|
+
return Promise.resolve(type === "checkOnly" ? true : "approved") as ApproveReturnType<T>;
|
|
308
164
|
}
|
|
309
165
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
assetValue,
|
|
313
|
-
memo: getMemoFor(MemoType.DEPOSIT, {
|
|
314
|
-
...assetValue,
|
|
315
|
-
address: this.getAddress(Chain.THORChain),
|
|
316
|
-
}),
|
|
317
|
-
});
|
|
318
|
-
} catch (error) {
|
|
319
|
-
throw new SwapKitError('core_transaction_create_liquidity_asset_error', error);
|
|
320
|
-
}
|
|
166
|
+
const walletMethods =
|
|
167
|
+
connectedWallets[chain as Chain.Ethereum | Chain.BinanceSmartChain | Chain.Avalanche];
|
|
321
168
|
|
|
322
|
-
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
addLiquidity = async ({
|
|
326
|
-
poolIdentifier,
|
|
327
|
-
runeAssetValue,
|
|
328
|
-
assetValue,
|
|
329
|
-
runeAddr,
|
|
330
|
-
assetAddr,
|
|
331
|
-
isPendingSymmAsset,
|
|
332
|
-
mode = 'sym',
|
|
333
|
-
}: {
|
|
334
|
-
poolIdentifier: string;
|
|
335
|
-
runeAssetValue: AssetValue;
|
|
336
|
-
assetValue: AssetValue;
|
|
337
|
-
isPendingSymmAsset?: boolean;
|
|
338
|
-
runeAddr?: string;
|
|
339
|
-
assetAddr?: string;
|
|
340
|
-
mode?: 'sym' | 'rune' | 'asset';
|
|
341
|
-
}) => {
|
|
342
|
-
const [chain, ...symbolPath] = poolIdentifier.split('.') as [Chain, string];
|
|
343
|
-
const isSym = mode === 'sym';
|
|
344
|
-
const runeTransfer = runeAssetValue?.gt(0) && (isSym || mode === 'rune');
|
|
345
|
-
const assetTransfer = assetValue?.gt(0) && (isSym || mode === 'asset');
|
|
346
|
-
const includeRuneAddress = isPendingSymmAsset || runeTransfer;
|
|
347
|
-
const runeAddress = includeRuneAddress ? runeAddr || this.getAddress(Chain.THORChain) : '';
|
|
348
|
-
const assetAddress = isSym || mode === 'asset' ? assetAddr || this.getAddress(chain) : '';
|
|
349
|
-
|
|
350
|
-
if (!runeTransfer && !assetTransfer) {
|
|
351
|
-
throw new SwapKitError('core_transaction_add_liquidity_invalid_params');
|
|
352
|
-
}
|
|
353
|
-
if (includeRuneAddress && !runeAddress) {
|
|
354
|
-
throw new SwapKitError('core_transaction_add_liquidity_no_rune_address');
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
let runeTx, assetTx;
|
|
358
|
-
const sharedParams = { chain, symbol: symbolPath.join('.') };
|
|
359
|
-
|
|
360
|
-
if (runeTransfer && runeAssetValue) {
|
|
361
|
-
try {
|
|
362
|
-
runeTx = await this.#depositToPool({
|
|
363
|
-
assetValue: runeAssetValue,
|
|
364
|
-
memo: getMemoFor(MemoType.DEPOSIT, { ...sharedParams, address: assetAddress }),
|
|
365
|
-
});
|
|
366
|
-
} catch (error) {
|
|
367
|
-
throw new SwapKitError('core_transaction_add_liquidity_rune_error', error);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
169
|
+
const walletAction = type === "checkOnly" ? walletMethods?.isApproved : walletMethods?.approve;
|
|
370
170
|
|
|
371
|
-
if (
|
|
372
|
-
try {
|
|
373
|
-
assetTx = await this.#depositToPool({
|
|
374
|
-
assetValue,
|
|
375
|
-
memo: getMemoFor(MemoType.DEPOSIT, { ...sharedParams, address: runeAddress }),
|
|
376
|
-
});
|
|
377
|
-
} catch (error) {
|
|
378
|
-
throw new SwapKitError('core_transaction_add_liquidity_asset_error', error);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
171
|
+
if (!walletAction) throw new SwapKitError("core_wallet_connection_not_found");
|
|
381
172
|
|
|
382
|
-
|
|
383
|
-
};
|
|
173
|
+
const from = getAddress(chain);
|
|
384
174
|
|
|
385
|
-
|
|
386
|
-
memo,
|
|
387
|
-
assetValue,
|
|
388
|
-
percent,
|
|
389
|
-
from,
|
|
390
|
-
to,
|
|
391
|
-
}: {
|
|
392
|
-
memo?: string;
|
|
393
|
-
assetValue: AssetValue;
|
|
394
|
-
percent: number;
|
|
395
|
-
from: 'sym' | 'rune' | 'asset';
|
|
396
|
-
to: 'sym' | 'rune';
|
|
397
|
-
}) => {
|
|
398
|
-
const targetAsset =
|
|
399
|
-
to === 'rune'
|
|
400
|
-
? AssetValue.fromChainOrSignature(Chain.THORChain)
|
|
401
|
-
: (from === 'sym' && to === 'sym') || from === 'rune' || from === 'asset'
|
|
402
|
-
? undefined
|
|
403
|
-
: assetValue;
|
|
175
|
+
if (!(address && from)) throw new SwapKitError("core_approve_asset_address_or_from_not_found");
|
|
404
176
|
|
|
405
|
-
|
|
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
|
-
}),
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
return txHash;
|
|
421
|
-
} catch (error) {
|
|
422
|
-
throw new SwapKitError('core_transaction_withdraw_error', error);
|
|
423
|
-
}
|
|
424
|
-
};
|
|
177
|
+
const spenderAddress = contractAddress;
|
|
425
178
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
| { type: 'withdraw'; percent: number }
|
|
434
|
-
)) => {
|
|
435
|
-
const memoType = type === 'add' ? MemoType.DEPOSIT : MemoType.WITHDRAW;
|
|
436
|
-
const memoString =
|
|
437
|
-
memo ||
|
|
438
|
-
getMemoFor(memoType, {
|
|
439
|
-
ticker: assetValue.ticker,
|
|
440
|
-
symbol: assetValue.symbol,
|
|
441
|
-
chain: assetValue.chain,
|
|
442
|
-
singleSide: true,
|
|
443
|
-
basisPoints: percent ? Math.max(10000, Math.round(percent * 100)) : undefined,
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
return this.#depositToPool({ assetValue, memo: memoString });
|
|
447
|
-
};
|
|
179
|
+
return walletAction({
|
|
180
|
+
amount: assetValue.getBaseValue("bigint"),
|
|
181
|
+
assetAddress: address,
|
|
182
|
+
from,
|
|
183
|
+
spenderAddress,
|
|
184
|
+
}) as ApproveReturnType<T>;
|
|
185
|
+
}
|
|
448
186
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}),
|
|
469
|
-
});
|
|
187
|
+
/**
|
|
188
|
+
* @Public
|
|
189
|
+
* Wallet helpers
|
|
190
|
+
*/
|
|
191
|
+
function getWallet(chain: Chain) {
|
|
192
|
+
return connectedWallets[chain];
|
|
193
|
+
}
|
|
194
|
+
function getAddress(chain: Chain) {
|
|
195
|
+
return getWallet(chain)?.address || "";
|
|
196
|
+
}
|
|
197
|
+
function getBalance(chain: Chain) {
|
|
198
|
+
return getWallet(chain)?.balance || [];
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* TODO: Figure out validation without connecting to wallet
|
|
202
|
+
*/
|
|
203
|
+
function validateAddress({ address, chain }: { address: string; chain: Chain }) {
|
|
204
|
+
return getWallet(chain)?.validateAddress?.(address);
|
|
205
|
+
}
|
|
470
206
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
address,
|
|
475
|
-
}: { address: string } & (
|
|
476
|
-
| { type: 'bond' | 'unbond'; assetValue: AssetValue }
|
|
477
|
-
| { type: 'leave'; assetValue?: undefined }
|
|
478
|
-
)) => {
|
|
479
|
-
const memoType =
|
|
480
|
-
type === 'bond' ? MemoType.BOND : type === 'unbond' ? MemoType.UNBOND : MemoType.LEAVE;
|
|
481
|
-
const memo = getMemoFor(memoType, {
|
|
482
|
-
address,
|
|
483
|
-
unbondAmount: type === 'unbond' ? assetValue.baseValueNumber : undefined,
|
|
484
|
-
});
|
|
207
|
+
async function getWalletWithBalance(chain: Chain, potentialScamFilter?: boolean) {
|
|
208
|
+
const defaultBalance = [AssetValue.fromChainOrSignature(chain)];
|
|
209
|
+
const wallet = getWallet(chain);
|
|
485
210
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
});
|
|
490
|
-
};
|
|
211
|
+
try {
|
|
212
|
+
if (!wallet) throw new SwapKitError("core_wallet_connection_not_found");
|
|
213
|
+
const balance = await wallet?.getBalance(wallet.address, potentialScamFilter);
|
|
491
214
|
|
|
492
|
-
|
|
493
|
-
assetValue,
|
|
494
|
-
...param
|
|
495
|
-
}: ThornameRegisterParam & { assetValue: AssetValue }) =>
|
|
496
|
-
this.#thorchainTransfer({ assetValue, memo: getMemoFor(MemoType.THORNAME_REGISTER, param) });
|
|
215
|
+
wallet.balance = balance?.length ? balance : defaultBalance;
|
|
497
216
|
|
|
498
|
-
|
|
499
|
-
try {
|
|
500
|
-
wallets.forEach((wallet) => {
|
|
501
|
-
// @ts-expect-error ANCHOR - Not Worth
|
|
502
|
-
this[wallet.connectMethodName] = wallet.connect({
|
|
503
|
-
addChain: this.#addConnectedChain,
|
|
504
|
-
config: config || {},
|
|
505
|
-
apis,
|
|
506
|
-
rpcUrls,
|
|
507
|
-
});
|
|
508
|
-
});
|
|
217
|
+
return wallet;
|
|
509
218
|
} catch (error) {
|
|
510
|
-
throw new SwapKitError(
|
|
219
|
+
throw new SwapKitError("core_wallet_connection_not_found", error);
|
|
511
220
|
}
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
estimateMaxSendableAmount = async ({
|
|
515
|
-
chain,
|
|
516
|
-
params,
|
|
517
|
-
}: {
|
|
518
|
-
chain: Chain;
|
|
519
|
-
params: { from: string; recipient: string; assetValue: AssetValue };
|
|
520
|
-
}) => {
|
|
521
|
-
const walletMethods = this.getWallet<typeof chain>(chain);
|
|
522
|
-
|
|
523
|
-
switch (chain) {
|
|
524
|
-
case Chain.Arbitrum:
|
|
525
|
-
case Chain.Avalanche:
|
|
526
|
-
case Chain.BinanceSmartChain:
|
|
527
|
-
case Chain.Ethereum:
|
|
528
|
-
case Chain.Optimism:
|
|
529
|
-
case Chain.Polygon: {
|
|
530
|
-
const { estimateMaxSendableAmount } = await import('@swapkit/toolbox-evm');
|
|
531
|
-
return estimateMaxSendableAmount({
|
|
532
|
-
...params,
|
|
533
|
-
toolbox: walletMethods as EVMToolbox,
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
case Chain.Bitcoin:
|
|
538
|
-
case Chain.BitcoinCash:
|
|
539
|
-
case Chain.Dogecoin:
|
|
540
|
-
case Chain.Litecoin:
|
|
541
|
-
return (walletMethods as UTXOToolbox).estimateMaxSendableAmount(params);
|
|
542
|
-
|
|
543
|
-
case Chain.Binance:
|
|
544
|
-
case Chain.THORChain:
|
|
545
|
-
case Chain.Cosmos: {
|
|
546
|
-
const { estimateMaxSendableAmount } = await import('@swapkit/toolbox-cosmos');
|
|
547
|
-
return estimateMaxSendableAmount({
|
|
548
|
-
...params,
|
|
549
|
-
toolbox: walletMethods as CosmosLikeToolbox,
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
default:
|
|
554
|
-
throw new SwapKitError('core_estimated_max_spendable_chain_not_supported');
|
|
555
|
-
}
|
|
556
|
-
};
|
|
221
|
+
}
|
|
557
222
|
|
|
558
223
|
/**
|
|
559
|
-
*
|
|
224
|
+
* @Public
|
|
225
|
+
* Wallet interaction methods
|
|
560
226
|
*/
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
}
|
|
564
|
-
connectEVMWallet = async (_chains: Chain[] | Chain, _wallet: EVMWalletOptions): Promise<void> => {
|
|
565
|
-
throw new SwapKitError('core_wallet_evmwallet_not_installed');
|
|
566
|
-
};
|
|
567
|
-
connectWalletconnect = async (_chains: Chain[], _options?: any): Promise<void> => {
|
|
568
|
-
throw new SwapKitError('core_wallet_walletconnect_not_installed');
|
|
569
|
-
};
|
|
570
|
-
connectKeystore = async (_chains: Chain[], _phrase: string): Promise<void> => {
|
|
571
|
-
throw new SwapKitError('core_wallet_keystore_not_installed');
|
|
572
|
-
};
|
|
573
|
-
connectLedger = async (_chains: Chain, _derivationPath: number[]): Promise<void> => {
|
|
574
|
-
throw new SwapKitError('core_wallet_ledger_not_installed');
|
|
575
|
-
};
|
|
576
|
-
connectTrezor = async (_chains: Chain, _derivationPath: number[]): Promise<void> => {
|
|
577
|
-
throw new SwapKitError('core_wallet_trezor_not_installed');
|
|
578
|
-
};
|
|
579
|
-
connectKeplr = async (): Promise<void> => {
|
|
580
|
-
throw new SwapKitError('core_wallet_keplr_not_installed');
|
|
581
|
-
};
|
|
582
|
-
connectOkx = async (_chains: Chain[]): Promise<void> => {
|
|
583
|
-
throw new SwapKitError('core_wallet_okx_not_installed');
|
|
584
|
-
};
|
|
585
|
-
disconnectChain = (chain: Chain) => {
|
|
586
|
-
this.connectedChains[chain] = null;
|
|
587
|
-
this.connectedWallets[chain] = null;
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
#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);
|
|
602
|
-
|
|
603
|
-
if (!chainAddressData) throw new SwapKitError('core_inbound_data_not_found');
|
|
604
|
-
if (chainAddressData?.halted) throw new SwapKitError('core_chain_halted');
|
|
605
|
-
|
|
606
|
-
return chainAddressData;
|
|
607
|
-
};
|
|
608
|
-
|
|
609
|
-
#addConnectedChain = ({ chain, wallet, walletMethods }: AddChainWalletParams) => {
|
|
610
|
-
this.connectedChains[chain] = wallet;
|
|
611
|
-
this.connectedWallets[chain] = walletMethods;
|
|
612
|
-
};
|
|
613
|
-
|
|
614
|
-
#approve = async <T = string>({
|
|
615
|
-
assetValue: { baseValueBigInt, address, chain, isGasAsset, isSynthetic },
|
|
616
|
-
type = 'checkOnly',
|
|
617
|
-
contractAddress,
|
|
618
|
-
}: {
|
|
619
|
-
assetValue: AssetValue;
|
|
620
|
-
type?: 'checkOnly' | 'approve';
|
|
621
|
-
contractAddress?: string;
|
|
622
|
-
}) => {
|
|
623
|
-
const isEVMChain = [Chain.Ethereum, Chain.Avalanche, Chain.BinanceSmartChain].includes(chain);
|
|
624
|
-
const isNativeEVM = isEVMChain && isGasAsset;
|
|
625
|
-
|
|
626
|
-
if (isNativeEVM || !isEVMChain || isSynthetic) return true;
|
|
627
|
-
|
|
628
|
-
const walletMethods = this.connectedWallets[chain as EVMChain];
|
|
629
|
-
const walletAction = type === 'checkOnly' ? walletMethods?.isApproved : walletMethods?.approve;
|
|
630
|
-
|
|
631
|
-
if (!walletAction) throw new SwapKitError('core_wallet_connection_not_found');
|
|
632
|
-
|
|
633
|
-
const from = this.getAddress(chain);
|
|
634
|
-
|
|
635
|
-
if (!address || !from) throw new SwapKitError('core_approve_asset_address_or_from_not_found');
|
|
636
|
-
|
|
637
|
-
const spenderAddress =
|
|
638
|
-
contractAddress || ((await this.#getInboundDataByChain(chain)).router as string);
|
|
639
|
-
|
|
640
|
-
return walletAction({
|
|
641
|
-
amount: baseValueBigInt,
|
|
642
|
-
assetAddress: address,
|
|
643
|
-
from,
|
|
644
|
-
spenderAddress,
|
|
645
|
-
}) as Promise<T>;
|
|
646
|
-
};
|
|
227
|
+
function approveAssetValue(assetValue: AssetValue, contractAddress: string) {
|
|
228
|
+
return approve({ assetValue, contractAddress, type: ApproveMode.Approve });
|
|
229
|
+
}
|
|
647
230
|
|
|
648
|
-
|
|
649
|
-
assetValue,
|
|
650
|
-
|
|
651
|
-
feeOptionKey = FeeOption.Fast,
|
|
652
|
-
}: {
|
|
653
|
-
assetValue: AssetValue;
|
|
654
|
-
memo: string;
|
|
655
|
-
feeOptionKey?: FeeOption;
|
|
656
|
-
}) => {
|
|
657
|
-
const {
|
|
658
|
-
gas_rate,
|
|
659
|
-
router,
|
|
660
|
-
address: poolAddress,
|
|
661
|
-
} = await this.#getInboundDataByChain(assetValue.chain);
|
|
662
|
-
const feeRate = (parseInt(gas_rate) || 0) * gasFeeMultiplier[feeOptionKey];
|
|
663
|
-
|
|
664
|
-
return this.deposit({
|
|
665
|
-
assetValue,
|
|
666
|
-
recipient: poolAddress,
|
|
667
|
-
memo,
|
|
668
|
-
router,
|
|
669
|
-
feeRate,
|
|
670
|
-
});
|
|
671
|
-
};
|
|
231
|
+
function isAssetValueApproved(assetValue: AssetValue, contractAddress: string) {
|
|
232
|
+
return approve({ assetValue, contractAddress, type: ApproveMode.CheckOnly });
|
|
233
|
+
}
|
|
672
234
|
|
|
673
|
-
|
|
674
|
-
const
|
|
235
|
+
function swap({ provider: providerConfig, ...rest }: SwapParams) {
|
|
236
|
+
const provider = getProvider(providerConfig?.name);
|
|
675
237
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
throw new SwapKitError('core_chain_halted');
|
|
679
|
-
}
|
|
238
|
+
return provider.swap({ provider: providerConfig, ...rest });
|
|
239
|
+
}
|
|
680
240
|
|
|
681
|
-
|
|
241
|
+
return {
|
|
242
|
+
...availableProviders,
|
|
243
|
+
...connectWalletMethods,
|
|
244
|
+
approveAssetValue,
|
|
245
|
+
getAddress,
|
|
246
|
+
getBalance,
|
|
247
|
+
getWallet,
|
|
248
|
+
getWalletWithBalance,
|
|
249
|
+
isAssetValueApproved,
|
|
250
|
+
swap,
|
|
251
|
+
validateAddress,
|
|
682
252
|
};
|
|
683
|
-
|
|
684
|
-
#prepareTxParams = ({ assetValue, ...restTxParams }: CoreTxParams & { router?: string }) => ({
|
|
685
|
-
...restTxParams,
|
|
686
|
-
memo: restTxParams.memo || '',
|
|
687
|
-
from: this.getAddress(assetValue.chain),
|
|
688
|
-
assetValue,
|
|
689
|
-
});
|
|
690
253
|
}
|