@subwallet/extension-base 1.2.3-0 → 1.2.3-1
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/background/KoniTypes.d.ts +4 -0
- package/cjs/core/logic-validation/earning.js +47 -0
- package/cjs/core/logic-validation/swap.js +99 -0
- package/cjs/core/logic-validation/transfer.js +219 -0
- package/cjs/core/substrate/nominationpools-pallet.js +12 -0
- package/cjs/core/substrate/system-pallet.js +78 -0
- package/cjs/koni/api/dotsama/transfer.js +49 -4
- package/cjs/koni/api/staking/bonding/utils.js +1 -1
- package/cjs/koni/api/xcm/index.js +30 -2
- package/cjs/koni/background/handlers/Extension.js +135 -245
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/group.js +4 -27
- package/cjs/services/balance-service/helpers/subscribe/index.js +2 -30
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +41 -80
- package/cjs/services/balance-service/index.js +11 -9
- package/cjs/services/chain-service/index.js +0 -1
- package/cjs/services/chain-service/utils/index.js +6 -0
- package/cjs/services/earning-service/handlers/base.js +1 -1
- package/cjs/services/earning-service/handlers/special.js +11 -12
- package/cjs/services/swap-service/handler/base-handler.js +28 -44
- package/cjs/services/swap-service/handler/chainflip-handler.js +23 -21
- package/cjs/services/swap-service/handler/hydradx-handler.js +40 -38
- package/cjs/services/swap-service/index.js +6 -0
- package/cjs/services/swap-service/utils.js +8 -49
- package/cjs/services/transaction-service/index.js +66 -155
- package/core/logic-validation/earning.d.ts +10 -0
- package/core/logic-validation/earning.js +37 -0
- package/core/logic-validation/swap.d.ts +8 -0
- package/core/logic-validation/swap.js +89 -0
- package/core/logic-validation/transfer.d.ts +16 -0
- package/core/logic-validation/transfer.js +206 -0
- package/core/substrate/nominationpools-pallet.d.ts +7 -0
- package/core/substrate/nominationpools-pallet.js +6 -0
- package/core/substrate/system-pallet.d.ts +27 -0
- package/core/substrate/system-pallet.js +71 -0
- package/koni/api/dotsama/transfer.d.ts +3 -1
- package/koni/api/dotsama/transfer.js +44 -1
- package/koni/api/staking/bonding/relayChain.d.ts +2 -1
- package/koni/api/staking/bonding/utils.js +1 -1
- package/koni/api/xcm/index.d.ts +2 -0
- package/koni/api/xcm/index.js +27 -1
- package/koni/background/handlers/Extension.d.ts +5 -5
- package/koni/background/handlers/Extension.js +111 -221
- package/package.json +34 -9
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/group.js +4 -27
- package/services/balance-service/helpers/subscribe/index.d.ts +2 -1
- package/services/balance-service/helpers/subscribe/index.js +2 -30
- package/services/balance-service/helpers/subscribe/substrate/index.d.ts +2 -1
- package/services/balance-service/helpers/subscribe/substrate/index.js +26 -64
- package/services/balance-service/index.d.ts +7 -6
- package/services/balance-service/index.js +12 -10
- package/services/chain-service/index.js +0 -1
- package/services/chain-service/utils/index.d.ts +1 -0
- package/services/chain-service/utils/index.js +4 -0
- package/services/earning-service/handlers/base.js +1 -1
- package/services/earning-service/handlers/nomination-pool/index.d.ts +2 -1
- package/services/earning-service/handlers/special.js +11 -12
- package/services/swap-service/handler/base-handler.d.ts +3 -2
- package/services/swap-service/handler/base-handler.js +26 -42
- package/services/swap-service/handler/chainflip-handler.d.ts +2 -1
- package/services/swap-service/handler/chainflip-handler.js +4 -2
- package/services/swap-service/handler/hydradx-handler.d.ts +2 -1
- package/services/swap-service/handler/hydradx-handler.js +7 -5
- package/services/swap-service/index.js +7 -1
- package/services/swap-service/utils.d.ts +2 -4
- package/services/swap-service/utils.js +7 -47
- package/services/transaction-service/index.d.ts +1 -1
- package/services/transaction-service/index.js +30 -119
- package/services/transaction-service/types.d.ts +1 -0
- package/types/balance/index.d.ts +6 -10
- package/types/yield/info/pallet.d.ts +0 -6
|
@@ -67,18 +67,8 @@ const filterAddress = (addresses, chainInfo) => {
|
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
// interface SubscribeBlanceOptions {
|
|
71
|
-
// addresses: string[];
|
|
72
|
-
// chains: string[];
|
|
73
|
-
// tokens: string[];
|
|
74
|
-
// chainInfoMap: Record<string, _ChainInfo>;
|
|
75
|
-
// substrateApiMap: Record<string, _SubstrateApi>;
|
|
76
|
-
// evmApiMap: Record<string, _EvmApi>;
|
|
77
|
-
// callback: (rs: BalanceItem[]) => void;
|
|
78
|
-
// }
|
|
79
|
-
|
|
80
70
|
// main subscription, use for multiple chains, multiple addresses and multiple tokens
|
|
81
|
-
export function subscribeBalance(addresses, chains, tokens, _chainAssetMap, _chainInfoMap, substrateApiMap, evmApiMap, callback) {
|
|
71
|
+
export function subscribeBalance(addresses, chains, tokens, _chainAssetMap, _chainInfoMap, substrateApiMap, evmApiMap, callback, extrinsicType) {
|
|
82
72
|
// Filter chain and token
|
|
83
73
|
const chainAssetMap = Object.fromEntries(Object.entries(_chainAssetMap).filter(([token]) => tokens.includes(token)));
|
|
84
74
|
const chainInfoMap = Object.fromEntries(Object.entries(_chainInfoMap).filter(([chain]) => chains.includes(chain)));
|
|
@@ -112,26 +102,8 @@ export function subscribeBalance(addresses, chains, tokens, _chainAssetMap, _cha
|
|
|
112
102
|
evmApi
|
|
113
103
|
});
|
|
114
104
|
}
|
|
115
|
-
|
|
116
|
-
// if (!useAddresses || useAddresses.length === 0 || _PURE_EVM_CHAINS.indexOf(chainSlug) > -1) {
|
|
117
|
-
// const fungibleTokensByChain = state.chainService.getFungibleTokensByChain(chainSlug, true);
|
|
118
|
-
// const now = new Date().getTime();
|
|
119
|
-
//
|
|
120
|
-
// Object.values(fungibleTokensByChain).map((token) => {
|
|
121
|
-
// return {
|
|
122
|
-
// tokenSlug: token.slug,
|
|
123
|
-
// free: '0',
|
|
124
|
-
// locked: '0',
|
|
125
|
-
// state: APIItemState.READY,
|
|
126
|
-
// timestamp: now
|
|
127
|
-
// } as BalanceItem;
|
|
128
|
-
// }).forEach(callback);
|
|
129
|
-
//
|
|
130
|
-
// return undefined;
|
|
131
|
-
// }
|
|
132
|
-
|
|
133
105
|
const substrateApi = await substrateApiMap[chainSlug].isReady;
|
|
134
|
-
return subscribeSubstrateBalance(useAddresses, chainInfo, chainAssetMap, substrateApi, evmApi, callback);
|
|
106
|
+
return subscribeSubstrateBalance(useAddresses, chainInfo, chainAssetMap, substrateApi, evmApi, callback, extrinsicType);
|
|
135
107
|
});
|
|
136
108
|
return () => {
|
|
137
109
|
unsubList.forEach(subProm => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
|
+
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
3
|
import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
3
4
|
import { BalanceItem } from '@subwallet/extension-base/types';
|
|
4
|
-
export declare const subscribeSubstrateBalance: (addresses: string[], chainInfo: _ChainInfo, assetMap: Record<string, _ChainAsset>, substrateApi: _SubstrateApi, evmApi: _EvmApi, callback: (rs: BalanceItem[]) => void) => Promise<() => void>;
|
|
5
|
+
export declare const subscribeSubstrateBalance: (addresses: string[], chainInfo: _ChainInfo, assetMap: Record<string, _ChainAsset>, substrateApi: _SubstrateApi, evmApi: _EvmApi, callback: (rs: BalanceItem[]) => void, extrinsicType?: ExtrinsicType) => Promise<() => void>;
|
|
@@ -5,10 +5,12 @@ import { GearApi } from '@gear-js/api';
|
|
|
5
5
|
import { _AssetType } from '@subwallet/chain-list/types';
|
|
6
6
|
import { APIItemState } from '@subwallet/extension-base/background/KoniTypes';
|
|
7
7
|
import { SUB_TOKEN_REFRESH_BALANCE_INTERVAL } from '@subwallet/extension-base/constants';
|
|
8
|
+
import { _getActiveStakeInNominationPool } from '@subwallet/extension-base/core/substrate/nominationpools-pallet';
|
|
9
|
+
import { _getSystemPalletTotalBalance, _getSystemPalletTransferable } from '@subwallet/extension-base/core/substrate/system-pallet';
|
|
8
10
|
import { getPSP22ContractPromise } from '@subwallet/extension-base/koni/api/tokens/wasm';
|
|
9
11
|
import { getDefaultWeightV2 } from '@subwallet/extension-base/koni/api/tokens/wasm/utils';
|
|
10
12
|
import { _BALANCE_CHAIN_GROUP, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX } from '@subwallet/extension-base/services/chain-service/constants';
|
|
11
|
-
import { _checkSmartContractSupportByChain, _getChainNativeTokenSlug, _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _getTokenTypesSupportedByChain, _getXcmAssetMultilocation, _isBridgedToken, _isChainEvmCompatible, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
|
|
13
|
+
import { _checkSmartContractSupportByChain, _getChainExistentialDeposit, _getChainNativeTokenSlug, _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _getTokenTypesSupportedByChain, _getXcmAssetMultilocation, _isBridgedToken, _isChainEvmCompatible, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
|
|
12
14
|
import { filterAssetsByChainAndType, getGRC20ContractPromise } from '@subwallet/extension-base/utils';
|
|
13
15
|
import BigN from 'bignumber.js';
|
|
14
16
|
import { combineLatest, Observable } from 'rxjs';
|
|
@@ -16,7 +18,7 @@ import { BN, BN_ZERO, noop, u8aToHex } from '@polkadot/util';
|
|
|
16
18
|
import { decodeAddress } from '@polkadot/util-crypto';
|
|
17
19
|
import { subscribeERC20Interval } from "../evm.js";
|
|
18
20
|
import { subscribeEquilibriumTokenBalance } from "./equilibrium.js";
|
|
19
|
-
export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap, substrateApi, evmApi, callback) => {
|
|
21
|
+
export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap, substrateApi, evmApi, callback, extrinsicType) => {
|
|
20
22
|
let unsubNativeToken;
|
|
21
23
|
let unsubLocalToken;
|
|
22
24
|
let unsubEvmContractToken;
|
|
@@ -28,7 +30,8 @@ export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap,
|
|
|
28
30
|
addresses,
|
|
29
31
|
chainInfo,
|
|
30
32
|
assetMap,
|
|
31
|
-
callback
|
|
33
|
+
callback,
|
|
34
|
+
extrinsicType
|
|
32
35
|
};
|
|
33
36
|
const substrateParams = {
|
|
34
37
|
...baseParams,
|
|
@@ -98,11 +101,13 @@ const subscribeWithSystemAccountPallet = async ({
|
|
|
98
101
|
addresses,
|
|
99
102
|
callback,
|
|
100
103
|
chainInfo,
|
|
104
|
+
extrinsicType,
|
|
101
105
|
substrateApi
|
|
102
106
|
}) => {
|
|
103
107
|
const chainNativeTokenSlug = _getChainNativeTokenSlug(chainInfo);
|
|
104
108
|
const balanceSubscribe = substrateApi.rx.query.system.account.multi(addresses);
|
|
105
|
-
let poolSubscribe;
|
|
109
|
+
let poolSubscribe; // add points in nomination pool back to user's balance
|
|
110
|
+
|
|
106
111
|
if (_isSubstrateRelayChain(chainInfo) && substrateApi.query.nominationPools) {
|
|
107
112
|
var _substrateApi$rx$quer;
|
|
108
113
|
poolSubscribe = (_substrateApi$rx$quer = substrateApi.rx.query.nominationPools.poolMembers) === null || _substrateApi$rx$quer === void 0 ? void 0 : _substrateApi$rx$quer.multi(addresses);
|
|
@@ -118,52 +123,25 @@ const subscribeWithSystemAccountPallet = async ({
|
|
|
118
123
|
}
|
|
119
124
|
const subscription = combineLatest({
|
|
120
125
|
balances: balanceSubscribe,
|
|
121
|
-
|
|
126
|
+
poolMemberInfos: poolSubscribe
|
|
122
127
|
}).subscribe(({
|
|
123
|
-
balances
|
|
124
|
-
|
|
128
|
+
balances,
|
|
129
|
+
poolMemberInfos
|
|
125
130
|
}) => {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
pooled = pooled.add(new BN(amount));
|
|
134
|
-
});
|
|
135
|
-
pooledStakingBalances.push(pooled);
|
|
136
|
-
} else {
|
|
137
|
-
pooledStakingBalances.push(BN_ZERO);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
const items = balances.map((balance, index) => {
|
|
141
|
-
var _balance$data, _balance$data$free, _balance$data2, _balance$data2$reserv, _balance$data3, _balance$data3$miscFr, _balance$data4, _balance$data4$frozen, _balance$data5, _balance$data5$feeFro;
|
|
142
|
-
let total = ((_balance$data = balance.data) === null || _balance$data === void 0 ? void 0 : (_balance$data$free = _balance$data.free) === null || _balance$data$free === void 0 ? void 0 : _balance$data$free.toBn()) || new BN(0);
|
|
143
|
-
const reserved = ((_balance$data2 = balance.data) === null || _balance$data2 === void 0 ? void 0 : (_balance$data2$reserv = _balance$data2.reserved) === null || _balance$data2$reserv === void 0 ? void 0 : _balance$data2$reserv.toBn()) || new BN(0);
|
|
144
|
-
// @ts-ignore
|
|
145
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
146
|
-
const miscFrozen = ((_balance$data3 = balance.data) === null || _balance$data3 === void 0 ? void 0 : (_balance$data3$miscFr = _balance$data3.miscFrozen) === null || _balance$data3$miscFr === void 0 ? void 0 : _balance$data3$miscFr.toBn()) || (balance === null || balance === void 0 ? void 0 : (_balance$data4 = balance.data) === null || _balance$data4 === void 0 ? void 0 : (_balance$data4$frozen = _balance$data4.frozen) === null || _balance$data4$frozen === void 0 ? void 0 : _balance$data4$frozen.toBn()) || new BN(0);
|
|
147
|
-
const feeFrozen = ((_balance$data5 = balance.data) === null || _balance$data5 === void 0 ? void 0 : (_balance$data5$feeFro = _balance$data5.feeFrozen) === null || _balance$data5$feeFro === void 0 ? void 0 : _balance$data5$feeFro.toBn()) || new BN(0);
|
|
148
|
-
let locked = reserved.add(miscFrozen);
|
|
149
|
-
total = total.add(reserved);
|
|
150
|
-
const pooledStakingBalance = pooledStakingBalances[index] || BN_ZERO;
|
|
151
|
-
if (pooledStakingBalance.gt(BN_ZERO)) {
|
|
152
|
-
total = total.add(pooledStakingBalance);
|
|
153
|
-
locked = locked.add(pooledStakingBalance);
|
|
154
|
-
}
|
|
155
|
-
const free = total.sub(locked);
|
|
131
|
+
const items = balances.map((_balance, index) => {
|
|
132
|
+
const balanceInfo = _balance.toPrimitive();
|
|
133
|
+
const poolMemberInfo = poolMemberInfos[index].toPrimitive();
|
|
134
|
+
const nominationPoolBalance = poolMemberInfo ? _getActiveStakeInNominationPool(poolMemberInfo) : '0';
|
|
135
|
+
const transferableBalance = _getSystemPalletTransferable(balanceInfo, _getChainExistentialDeposit(chainInfo), extrinsicType);
|
|
136
|
+
const totalBalance = _getSystemPalletTotalBalance(balanceInfo);
|
|
137
|
+
const totalLockedFromTransfer = new BigN(totalBalance).minus(transferableBalance).plus(nominationPoolBalance);
|
|
156
138
|
return {
|
|
157
139
|
address: addresses[index],
|
|
158
140
|
tokenSlug: chainNativeTokenSlug,
|
|
159
|
-
free:
|
|
160
|
-
locked:
|
|
141
|
+
free: transferableBalance,
|
|
142
|
+
locked: totalLockedFromTransfer.toFixed(),
|
|
161
143
|
state: APIItemState.READY,
|
|
162
|
-
|
|
163
|
-
miscFrozen: miscFrozen.toString(),
|
|
164
|
-
reserved: reserved.toString(),
|
|
165
|
-
feeFrozen: feeFrozen.toString()
|
|
166
|
-
}
|
|
144
|
+
metadata: balanceInfo
|
|
167
145
|
};
|
|
168
146
|
});
|
|
169
147
|
callback(items);
|
|
@@ -211,11 +189,7 @@ const subscribeBridgedBalance = async ({
|
|
|
211
189
|
tokenSlug: tokenInfo.slug,
|
|
212
190
|
free: free.toString(),
|
|
213
191
|
locked: frozen.toString(),
|
|
214
|
-
state: APIItemState.READY
|
|
215
|
-
substrateInfo: {
|
|
216
|
-
miscFrozen: frozen.toString(),
|
|
217
|
-
reserved: '0'
|
|
218
|
-
}
|
|
192
|
+
state: APIItemState.READY
|
|
219
193
|
};
|
|
220
194
|
});
|
|
221
195
|
callback(items);
|
|
@@ -331,11 +305,7 @@ const subscribeTokensAccountsPallet = async ({
|
|
|
331
305
|
tokenSlug: tokenInfo.slug,
|
|
332
306
|
state: APIItemState.READY,
|
|
333
307
|
free: freeBalance.toString(),
|
|
334
|
-
locked: lockedBalance.toString()
|
|
335
|
-
substrateInfo: {
|
|
336
|
-
reserved: tokenBalance.reserved.toString(),
|
|
337
|
-
miscFrozen: tokenBalance.frozen.toString()
|
|
338
|
-
}
|
|
308
|
+
locked: lockedBalance.toString()
|
|
339
309
|
};
|
|
340
310
|
});
|
|
341
311
|
callback(items);
|
|
@@ -393,11 +363,7 @@ const subscribeAssetsAccountPallet = async ({
|
|
|
393
363
|
tokenSlug: tokenInfo.slug,
|
|
394
364
|
free: free.toString(),
|
|
395
365
|
locked: frozen.toString(),
|
|
396
|
-
state: APIItemState.READY
|
|
397
|
-
substrateInfo: {
|
|
398
|
-
miscFrozen: frozen.toString(),
|
|
399
|
-
reserved: '0'
|
|
400
|
-
}
|
|
366
|
+
state: APIItemState.READY
|
|
401
367
|
};
|
|
402
368
|
});
|
|
403
369
|
callback(items);
|
|
@@ -448,11 +414,7 @@ const subscribeOrmlTokensPallet = async ({
|
|
|
448
414
|
tokenSlug: tokenInfo.slug,
|
|
449
415
|
state: APIItemState.READY,
|
|
450
416
|
free: freeBalance.toString(),
|
|
451
|
-
locked: lockedBalance.toString()
|
|
452
|
-
substrateInfo: {
|
|
453
|
-
reserved: tokenBalance.reserved.toString(),
|
|
454
|
-
miscFrozen: tokenBalance.frozen.toString()
|
|
455
|
-
}
|
|
417
|
+
locked: lockedBalance.toString()
|
|
456
418
|
};
|
|
457
419
|
});
|
|
458
420
|
callback(items);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AmountData, DetectBalanceCache } from '@subwallet/extension-base/background/KoniTypes';
|
|
1
|
+
import { AmountData, DetectBalanceCache, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
2
|
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
|
|
3
3
|
import { ServiceStatus, StoppableServiceInterface } from '@subwallet/extension-base/services/base/types';
|
|
4
4
|
import { EventItem, EventType } from '@subwallet/extension-base/services/event-service/types';
|
|
@@ -44,19 +44,20 @@ export declare class BalanceService implements StoppableServiceInterface {
|
|
|
44
44
|
handleEvents(events: EventItem<EventType>[], eventTypes: EventType[]): void;
|
|
45
45
|
getBalanceDetectCache(update: (value: DetectBalanceCache) => void): void;
|
|
46
46
|
setBalanceDetectCache(addresses: string[]): void;
|
|
47
|
-
/** Subscribe token free balance of
|
|
48
|
-
|
|
47
|
+
/** Subscribe token free balance of an address on chain */
|
|
48
|
+
subscribeTransferableBalance(address: string, chain: string, tokenSlug: string | undefined, extrinsicType?: ExtrinsicType, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
|
|
49
49
|
/**
|
|
50
50
|
* @public
|
|
51
51
|
* @async
|
|
52
|
-
* @function
|
|
52
|
+
* @function getTransferableBalance
|
|
53
53
|
* @desc Fetch free balance on chain
|
|
54
54
|
* @param {string} address - Address
|
|
55
55
|
* @param {string} chain - Slug of chain
|
|
56
56
|
* @param {string} [tokenSlug] - Slug of token
|
|
57
|
+
* @param extrinsicType - Customize transferable based on context
|
|
57
58
|
* @return {Promise<AmountData>} - Free token balance of address on chain
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
*/
|
|
60
|
+
getTransferableBalance(address: string, chain: string, tokenSlug?: string, extrinsicType?: ExtrinsicType): Promise<AmountData>;
|
|
60
61
|
/** Remove balance from the subject object by addresses */
|
|
61
62
|
removeBalanceByAddresses(addresses: string[]): void;
|
|
62
63
|
/** Remove inactive asset from the balance map */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { BalanceError } from '@subwallet/extension-base/background/errors/BalanceError';
|
|
5
|
-
import { BalanceErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
|
+
import { BalanceErrorType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
6
|
import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
|
|
7
7
|
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
8
8
|
import { _getChainNativeTokenSlug } from '@subwallet/extension-base/services/chain-service/utils';
|
|
@@ -159,8 +159,8 @@ export class BalanceService {
|
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
/** Subscribe token free balance of
|
|
163
|
-
async
|
|
162
|
+
/** Subscribe token free balance of an address on chain */
|
|
163
|
+
async subscribeTransferableBalance(address, chain, tokenSlug, extrinsicType, callback) {
|
|
164
164
|
const chainInfo = this.state.chainService.getChainInfoByKey(chain);
|
|
165
165
|
const chainState = this.state.chainService.getChainStateByKey(chain);
|
|
166
166
|
if (!chainInfo || !chainState || !chainState.active) {
|
|
@@ -193,7 +193,8 @@ export class BalanceService {
|
|
|
193
193
|
const balance = {
|
|
194
194
|
value: rs.free,
|
|
195
195
|
decimals: tokenInfo.decimals || 0,
|
|
196
|
-
symbol: tokenInfo.symbol
|
|
196
|
+
symbol: tokenInfo.symbol,
|
|
197
|
+
metadata: rs.metadata
|
|
197
198
|
};
|
|
198
199
|
if (callback) {
|
|
199
200
|
callback(balance);
|
|
@@ -204,7 +205,7 @@ export class BalanceService {
|
|
|
204
205
|
}
|
|
205
206
|
resolve([unsub, balance]);
|
|
206
207
|
}
|
|
207
|
-
});
|
|
208
|
+
}, extrinsicType);
|
|
208
209
|
setTimeout(() => {
|
|
209
210
|
if (hasError) {
|
|
210
211
|
var _unsub2;
|
|
@@ -218,15 +219,16 @@ export class BalanceService {
|
|
|
218
219
|
/**
|
|
219
220
|
* @public
|
|
220
221
|
* @async
|
|
221
|
-
* @function
|
|
222
|
+
* @function getTransferableBalance
|
|
222
223
|
* @desc Fetch free balance on chain
|
|
223
224
|
* @param {string} address - Address
|
|
224
225
|
* @param {string} chain - Slug of chain
|
|
225
226
|
* @param {string} [tokenSlug] - Slug of token
|
|
227
|
+
* @param extrinsicType - Customize transferable based on context
|
|
226
228
|
* @return {Promise<AmountData>} - Free token balance of address on chain
|
|
227
|
-
|
|
228
|
-
async
|
|
229
|
-
const [, balance] = await this.
|
|
229
|
+
*/
|
|
230
|
+
async getTransferableBalance(address, chain, tokenSlug, extrinsicType) {
|
|
231
|
+
const [, balance] = await this.subscribeTransferableBalance(address, chain, tokenSlug, extrinsicType);
|
|
230
232
|
return balance;
|
|
231
233
|
}
|
|
232
234
|
|
|
@@ -328,7 +330,7 @@ export class BalanceService {
|
|
|
328
330
|
}).map(asset => asset.slug);
|
|
329
331
|
const unsub = subscribeBalance(addresses, activeChainSlugs, assets, assetMap, chainInfoMap, substrateApiMap, evmApiMap, result => {
|
|
330
332
|
!cancel && this.setBalanceItem(result);
|
|
331
|
-
});
|
|
333
|
+
}, ExtrinsicType.TRANSFER_BALANCE);
|
|
332
334
|
const unsub2 = this.state.subscribeMantaPayBalance();
|
|
333
335
|
this._unsubscribeBalance = () => {
|
|
334
336
|
cancel = true;
|
|
@@ -474,7 +474,6 @@ export class ChainService {
|
|
|
474
474
|
needUpdateChainApiList,
|
|
475
475
|
storedChainInfoList
|
|
476
476
|
} = updateLatestChainInfo(this.dataMap, latestChainInfo);
|
|
477
|
-
console.log('here', needUpdateChainApiList, storedChainInfoList);
|
|
478
477
|
this.dbService.bulkUpdateChainStore(storedChainInfoList).catch(console.error);
|
|
479
478
|
this.updateChainSubscription();
|
|
480
479
|
needUpdateChainApiList.forEach(chainInfo => {
|
|
@@ -88,6 +88,7 @@ export declare function _generateCustomProviderKey(index: number): string;
|
|
|
88
88
|
export declare const findChainInfoByHalfGenesisHash: (chainMap: Record<string, _ChainInfo>, halfGenesisHash?: string) => _ChainInfo | null;
|
|
89
89
|
export declare const findChainInfoByChainId: (chainMap: Record<string, _ChainInfo>, chainId?: number) => _ChainInfo | null;
|
|
90
90
|
export declare function _isMantaZkAsset(chainAsset: _ChainAsset): boolean;
|
|
91
|
+
export declare function _getChainExistentialDeposit(chainInfo: _ChainInfo): string;
|
|
91
92
|
export declare function randomizeProvider(providers: Record<string, string>, excludedKeys?: string[]): {
|
|
92
93
|
providerKey: string;
|
|
93
94
|
providerValue: string;
|
|
@@ -406,6 +406,10 @@ export const findChainInfoByChainId = (chainMap, chainId) => {
|
|
|
406
406
|
export function _isMantaZkAsset(chainAsset) {
|
|
407
407
|
return _MANTA_ZK_CHAIN_GROUP.includes(chainAsset.originChain) && chainAsset.symbol.startsWith(_ZK_ASSET_PREFIX);
|
|
408
408
|
}
|
|
409
|
+
export function _getChainExistentialDeposit(chainInfo) {
|
|
410
|
+
var _chainInfo$substrateI18;
|
|
411
|
+
return (chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI18 = chainInfo.substrateInfo) === null || _chainInfo$substrateI18 === void 0 ? void 0 : _chainInfo$substrateI18.existentialDeposit) || '0';
|
|
412
|
+
}
|
|
409
413
|
export function randomizeProvider(providers, excludedKeys) {
|
|
410
414
|
if (Object.keys(providers).length === 0) {
|
|
411
415
|
return {
|
|
@@ -129,7 +129,7 @@ export default class BasePoolHandler {
|
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
131
|
const nativeTokenInfo = this.state.chainService.getNativeTokenInfo(this.chain);
|
|
132
|
-
const nativeTokenBalance = await this.state.balanceService.
|
|
132
|
+
const nativeTokenBalance = await this.state.balanceService.getTransferableBalance(request.address, this.chain);
|
|
133
133
|
const bnNativeTokenBalance = new BN(nativeTokenBalance.value);
|
|
134
134
|
const bnMinBalanceToJoin = new BN(((_poolInfo$statistic2 = poolInfo.statistic) === null || _poolInfo$statistic2 === void 0 ? void 0 : (_poolInfo$statistic2$ = _poolInfo$statistic2.earningThreshold) === null || _poolInfo$statistic2$ === void 0 ? void 0 : _poolInfo$statistic2$.join) || '0').add(new BN(poolInfo.metadata.maintainBalance));
|
|
135
135
|
if (bnNativeTokenBalance.lte(bnMinBalanceToJoin)) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
2
2
|
import { ExtrinsicType, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
|
+
import { PalletNominationPoolsPoolMember } from '@subwallet/extension-base/core/substrate/nominationpools-pallet';
|
|
3
4
|
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
|
|
4
5
|
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
5
|
-
import { BaseYieldPositionInfo, EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, NominationPoolInfo, OptimalYieldPath, OptimalYieldPathParams,
|
|
6
|
+
import { BaseYieldPositionInfo, EarningRewardHistoryItem, EarningRewardItem, HandleYieldStepData, NominationPoolInfo, OptimalYieldPath, OptimalYieldPathParams, StakeCancelWithdrawalParams, SubmitJoinNominationPool, SubmitYieldJoinData, TransactionData, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
6
7
|
import { DeriveSessionProgress } from '@polkadot/api-derive/types';
|
|
7
8
|
import BasePoolHandler from '../base';
|
|
8
9
|
export default class NominationPoolHandler extends BasePoolHandler {
|
|
@@ -67,11 +67,11 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
67
67
|
const feeAssetInfo = this.state.chainService.getAssetBySlug(this.feeAssets[0]);
|
|
68
68
|
const altInputAssetInfo = this.state.chainService.getAssetBySlug(this.altInputAsset);
|
|
69
69
|
const inputAssetInfo = this.state.chainService.getAssetBySlug(this.inputAsset);
|
|
70
|
-
const [inputAssetBalance, altInputAssetBalance, feeAssetBalance] = await Promise.all([this.state.balanceService.
|
|
70
|
+
const [inputAssetBalance, altInputAssetBalance, feeAssetBalance] = await Promise.all([this.state.balanceService.getTransferableBalance(request.address, inputAssetInfo.originChain, inputAssetInfo.slug), altInputAssetInfo ? this.state.balanceService.getTransferableBalance(request.address, altInputAssetInfo.originChain, altInputAssetInfo.slug) : Promise.resolve({
|
|
71
71
|
symbol: '',
|
|
72
72
|
decimals: 0,
|
|
73
73
|
value: '0'
|
|
74
|
-
}), this.state.balanceService.
|
|
74
|
+
}), this.state.balanceService.getTransferableBalance(request.address, feeAssetInfo.originChain, feeAssetInfo.slug)]);
|
|
75
75
|
const bnInputAssetBalance = new BN(inputAssetBalance.value);
|
|
76
76
|
const bnAltInputAssetBalance = new BN(altInputAssetBalance.value);
|
|
77
77
|
const bnMinJoinPool = new BN(poolInfo.statistic.earningThreshold.join);
|
|
@@ -193,13 +193,13 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
193
193
|
const bnAmount = new BN(amount);
|
|
194
194
|
const inputTokenSlug = this.inputAsset; // assume that the pool only has 1 input token, will update later
|
|
195
195
|
const inputTokenInfo = this.state.getAssetBySlug(inputTokenSlug);
|
|
196
|
-
const inputTokenBalance = await this.state.balanceService.
|
|
196
|
+
const inputTokenBalance = await this.state.balanceService.getTransferableBalance(address, inputTokenInfo.originChain, inputTokenSlug);
|
|
197
197
|
const bnInputTokenBalance = new BN(inputTokenBalance.value);
|
|
198
198
|
if (!bnInputTokenBalance.gte(bnAmount)) {
|
|
199
199
|
if (this.altInputAsset) {
|
|
200
200
|
const altInputTokenSlug = this.altInputAsset;
|
|
201
201
|
const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
|
|
202
|
-
const altInputTokenBalance = await this.state.balanceService.
|
|
202
|
+
const altInputTokenBalance = await this.state.balanceService.getTransferableBalance(address, altInputTokenInfo.originChain, altInputTokenSlug);
|
|
203
203
|
const bnAltInputTokenBalance = new BN(altInputTokenBalance.value || '0');
|
|
204
204
|
if (bnAltInputTokenBalance.gt(BN_ZERO)) {
|
|
205
205
|
const altChainInfo = this.state.getChainInfo(altInputTokenInfo.originChain);
|
|
@@ -272,17 +272,16 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
272
272
|
const altInputTokenSlug = this.altInputAsset || '';
|
|
273
273
|
const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
|
|
274
274
|
const inputTokenInfo = this.state.getAssetBySlug(this.inputAsset);
|
|
275
|
-
const altInputTokenBalance = await this.state.balanceService.
|
|
275
|
+
const altInputTokenBalance = await this.state.balanceService.getTransferableBalance(params.address, altInputTokenInfo.originChain, altInputTokenSlug);
|
|
276
276
|
const missingAmount = bnAmount.sub(bnInputTokenBalance); // TODO: what if input token is not LOCAL ??
|
|
277
277
|
const xcmFee = new BN(path.totalFee[1].amount || '0');
|
|
278
278
|
const xcmAmount = missingAmount.add(xcmFee);
|
|
279
279
|
const bnAltInputTokenBalance = new BN(altInputTokenBalance.value || '0');
|
|
280
|
-
|
|
281
|
-
if (!bnAltInputTokenBalance.sub(xcmAmount).gte(altInputTokenMinAmount)) {
|
|
280
|
+
if (!bnAltInputTokenBalance.sub(xcmAmount).gt(BN_ZERO)) {
|
|
282
281
|
processValidation.failedStep = path.steps[1];
|
|
283
282
|
processValidation.ok = false;
|
|
284
283
|
processValidation.status = YieldValidationStatus.NOT_ENOUGH_BALANCE;
|
|
285
|
-
const maxBn = bnInputTokenBalance.add(new BN(altInputTokenBalance.value)).sub(xcmFee)
|
|
284
|
+
const maxBn = bnInputTokenBalance.add(new BN(altInputTokenBalance.value)).sub(xcmFee);
|
|
286
285
|
const maxValue = formatNumber(maxBn.toString(), inputTokenInfo.decimals || 0);
|
|
287
286
|
const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
|
|
288
287
|
const symbol = altInputTokenInfo.symbol;
|
|
@@ -290,7 +289,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
290
289
|
const inputNetworkName = this.chainInfo.name;
|
|
291
290
|
const altNetworkName = altNetwork.name;
|
|
292
291
|
const currentValue = formatNumber(bnInputTokenBalance.toString(), inputTokenInfo.decimals || 0);
|
|
293
|
-
const bnMaxXCM = new BN(altInputTokenBalance.value).sub(xcmFee)
|
|
292
|
+
const bnMaxXCM = new BN(altInputTokenBalance.value).sub(xcmFee);
|
|
294
293
|
const maxXCMValue = formatNumber(bnMaxXCM.toString(), inputTokenInfo.decimals || 0);
|
|
295
294
|
processValidation.message = t('You can only enter a maximum of {{maxValue}} {{symbol}}, which is {{currentValue}} {{symbol}} ({{inputNetworkName}}) and {{maxXCMValue}} {{symbol}} ({{altNetworkName}}). Lower your amount and try again.', {
|
|
296
295
|
replace: {
|
|
@@ -327,7 +326,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
327
326
|
if (this.feeAssets.length === 1 && feeTokenSlug === defaultFeeTokenSlug) {
|
|
328
327
|
var _path$totalFee$id;
|
|
329
328
|
const bnFeeAmount = new BN(((_path$totalFee$id = path.totalFee[id]) === null || _path$totalFee$id === void 0 ? void 0 : _path$totalFee$id.amount) || '0');
|
|
330
|
-
const feeTokenBalance = await this.state.balanceService.
|
|
329
|
+
const feeTokenBalance = await this.state.balanceService.getTransferableBalance(params.address, feeTokenInfo.originChain, feeTokenSlug);
|
|
331
330
|
const bnFeeTokenBalance = new BN(feeTokenBalance.value || '0');
|
|
332
331
|
const bnFeeTokenMinAmount = new BN((feeTokenInfo === null || feeTokenInfo === void 0 ? void 0 : feeTokenInfo.minAmount) || '0');
|
|
333
332
|
if (!bnFeeTokenBalance.sub(bnFeeAmount).gte(bnFeeTokenMinAmount)) {
|
|
@@ -365,7 +364,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
365
364
|
const inputTokenSlug = this.inputAsset;
|
|
366
365
|
const inputTokenInfo = this.state.getAssetBySlug(inputTokenSlug);
|
|
367
366
|
const balanceService = this.state.balanceService;
|
|
368
|
-
const inputTokenBalance = await balanceService.
|
|
367
|
+
const inputTokenBalance = await balanceService.getTransferableBalance(params.address, inputTokenInfo.originChain, inputTokenSlug);
|
|
369
368
|
const bnInputTokenBalance = new BN(inputTokenBalance.value || '0');
|
|
370
369
|
const bnAmount = new BN(params.amount);
|
|
371
370
|
if (bnAmount.lte(BN_ZERO)) {
|
|
@@ -415,7 +414,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
415
414
|
const originTokenInfo = this.state.getAssetBySlug(originTokenSlug);
|
|
416
415
|
const destinationTokenInfo = this.state.getAssetBySlug(destinationTokenSlug);
|
|
417
416
|
const substrateApi = this.state.getSubstrateApi(originChainInfo.slug);
|
|
418
|
-
const inputTokenBalance = await this.state.balanceService.
|
|
417
|
+
const inputTokenBalance = await this.state.balanceService.getTransferableBalance(address, destinationTokenInfo.originChain, destinationTokenSlug);
|
|
419
418
|
const bnInputTokenBalance = new BN(inputTokenBalance.value);
|
|
420
419
|
const bnXcmFee = new BN(xcmFee);
|
|
421
420
|
const bnAmount = new BN(amount);
|
|
@@ -3,8 +3,9 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
|
|
|
3
3
|
import { BalanceService } from '@subwallet/extension-base/services/balance-service';
|
|
4
4
|
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
5
5
|
import { BaseStepDetail } from '@subwallet/extension-base/types/service-base';
|
|
6
|
-
import { GenSwapStepFunc, OptimalSwapPath, OptimalSwapPathParams, SwapEarlyValidation, SwapFeeInfo, SwapProvider, SwapQuote, SwapRequest, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types/swap';
|
|
6
|
+
import { GenSwapStepFunc, OptimalSwapPath, OptimalSwapPathParams, SwapEarlyValidation, SwapFeeInfo, SwapProvider, SwapProviderId, SwapQuote, SwapRequest, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types/swap';
|
|
7
7
|
export interface SwapBaseInterface {
|
|
8
|
+
providerSlug: SwapProviderId;
|
|
8
9
|
getSwapQuote: (request: SwapRequest) => Promise<SwapQuote | SwapError>;
|
|
9
10
|
generateOptimalProcess: (params: OptimalSwapPathParams) => Promise<OptimalSwapPath>;
|
|
10
11
|
getSubmitStep: (params: OptimalSwapPathParams) => Promise<[BaseStepDetail, SwapFeeInfo] | undefined>;
|
|
@@ -16,7 +17,7 @@ export interface SwapBaseInterface {
|
|
|
16
17
|
init?: () => Promise<void>;
|
|
17
18
|
}
|
|
18
19
|
export interface SwapBaseHandlerInitParams {
|
|
19
|
-
providerSlug:
|
|
20
|
+
providerSlug: SwapProviderId;
|
|
20
21
|
providerName: string;
|
|
21
22
|
chainService: ChainService;
|
|
22
23
|
balanceService: BalanceService;
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
|
|
4
4
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
5
|
import { BasicTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
-
import {
|
|
6
|
+
import { _validateBalanceToSwap, _validateSwapRecipient } from '@subwallet/extension-base/core/logic-validation/swap';
|
|
7
|
+
import { _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
|
|
7
8
|
import { DEFAULT_SWAP_FIRST_STEP, getSwapAlternativeAsset, MOCK_SWAP_FEE } from '@subwallet/extension-base/services/swap-service/utils';
|
|
8
9
|
import { SwapErrorType, SwapFeeType } from '@subwallet/extension-base/types/swap';
|
|
9
10
|
import { formatNumber } from '@subwallet/extension-base/utils';
|
|
10
11
|
import BigNumber from 'bignumber.js';
|
|
11
12
|
import { t } from 'i18next';
|
|
12
|
-
import { isEthereumAddress } from '@polkadot/util-crypto';
|
|
13
13
|
export class SwapBaseHandler {
|
|
14
14
|
constructor({
|
|
15
15
|
balanceService,
|
|
@@ -54,7 +54,7 @@ export class SwapBaseHandler {
|
|
|
54
54
|
}
|
|
55
55
|
const alternativeAsset = this.chainService.getAssetBySlug(alternativeAssetSlug);
|
|
56
56
|
const fromAsset = this.chainService.getAssetBySlug(swapPair.from);
|
|
57
|
-
const [alternativeAssetBalance, fromAssetBalance] = await Promise.all([this.balanceService.
|
|
57
|
+
const [alternativeAssetBalance, fromAssetBalance] = await Promise.all([this.balanceService.getTransferableBalance(params.address, alternativeAsset.originChain, alternativeAssetSlug), this.balanceService.getTransferableBalance(params.address, fromAsset.originChain, fromAsset.slug)]);
|
|
58
58
|
const bnAlternativeAssetBalance = new BigNumber(alternativeAssetBalance.value);
|
|
59
59
|
const bnFromAssetBalance = new BigNumber(fromAssetBalance.value);
|
|
60
60
|
const xcmFeeComponent = params.process.totalFee[stepIndex].feeComponent[0]; // todo: can do better than indexing
|
|
@@ -63,9 +63,8 @@ export class SwapBaseHandler {
|
|
|
63
63
|
if (_isNativeToken(alternativeAsset)) {
|
|
64
64
|
xcmAmount = xcmAmount.plus(xcmFee);
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const maxBn = bnFromAssetBalance.plus(new BigNumber(alternativeAssetBalance.value)).minus(xcmFee).minus(alternativeTokenMinAmount);
|
|
66
|
+
if (!bnAlternativeAssetBalance.minus(xcmAmount).gt(0)) {
|
|
67
|
+
const maxBn = bnFromAssetBalance.plus(new BigNumber(alternativeAssetBalance.value)).minus(xcmFee);
|
|
69
68
|
const maxValue = formatNumber(maxBn.toString(), fromAsset.decimals || 0);
|
|
70
69
|
const altInputTokenInfo = this.chainService.getAssetBySlug(alternativeAssetSlug);
|
|
71
70
|
const symbol = altInputTokenInfo.symbol;
|
|
@@ -74,7 +73,7 @@ export class SwapBaseHandler {
|
|
|
74
73
|
const inputNetworkName = chain.name;
|
|
75
74
|
const altNetworkName = alternativeChain.name;
|
|
76
75
|
const currentValue = formatNumber(bnFromAssetBalance.toString(), fromAsset.decimals || 0);
|
|
77
|
-
const bnMaxXCM = new BigNumber(alternativeAssetBalance.value).minus(xcmFee)
|
|
76
|
+
const bnMaxXCM = new BigNumber(alternativeAssetBalance.value).minus(xcmFee);
|
|
78
77
|
const maxXCMValue = formatNumber(bnMaxXCM.toString(), fromAsset.decimals || 0);
|
|
79
78
|
if (maxBn.lte(0) || bnFromAssetBalance.lte(0) || bnMaxXCM.lte(0)) {
|
|
80
79
|
return [new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, t(`Insufficient balance. Deposit ${fromAsset.symbol} and try again.`))];
|
|
@@ -102,7 +101,7 @@ export class SwapBaseHandler {
|
|
|
102
101
|
const feeInfo = params.process.totalFee[stepIndex];
|
|
103
102
|
const feeAmount = feeInfo.feeComponent[0];
|
|
104
103
|
const feeTokenInfo = this.chainService.getAssetBySlug(feeInfo.defaultFeeToken);
|
|
105
|
-
const feeTokenBalance = await this.balanceService.
|
|
104
|
+
const feeTokenBalance = await this.balanceService.getTransferableBalance(params.address, feeTokenInfo.originChain, feeTokenInfo.slug);
|
|
106
105
|
const bnFeeTokenBalance = new BigNumber(feeTokenBalance.value);
|
|
107
106
|
const bnFeeAmount = new BigNumber(feeAmount.amount);
|
|
108
107
|
if (bnFeeAmount.gte(bnFeeTokenBalance)) {
|
|
@@ -111,6 +110,9 @@ export class SwapBaseHandler {
|
|
|
111
110
|
return [];
|
|
112
111
|
}
|
|
113
112
|
async validateSwapStep(params, isXcmOk, stepIndex) {
|
|
113
|
+
// check swap quote timestamp
|
|
114
|
+
// check balance to pay transaction fee
|
|
115
|
+
// check balance against spending amount
|
|
114
116
|
if (!params.selectedQuote) {
|
|
115
117
|
return Promise.resolve([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
|
|
116
118
|
}
|
|
@@ -119,49 +121,31 @@ export class SwapBaseHandler {
|
|
|
119
121
|
if (selectedQuote.aliveUntil <= currentTimestamp) {
|
|
120
122
|
return Promise.resolve([new TransactionError(SwapErrorType.QUOTE_TIMEOUT)]);
|
|
121
123
|
}
|
|
122
|
-
const bnAmount = new BigNumber(params.selectedQuote.fromAmount);
|
|
123
|
-
const fromAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
|
|
124
124
|
const stepFee = params.process.totalFee[stepIndex].feeComponent;
|
|
125
125
|
const networkFee = stepFee.find(fee => fee.feeType === SwapFeeType.NETWORK_FEE);
|
|
126
126
|
if (!networkFee) {
|
|
127
127
|
return Promise.resolve([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
|
|
128
128
|
}
|
|
129
|
+
const fromAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
|
|
129
130
|
const feeTokenInfo = this.chainService.getAssetBySlug(networkFee.tokenSlug);
|
|
130
131
|
const feeTokenChain = this.chainService.getChainInfoByKey(feeTokenInfo.originChain);
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
const {
|
|
133
|
+
fromAmount,
|
|
134
|
+
minSwap
|
|
135
|
+
} = params.selectedQuote;
|
|
136
|
+
const [feeTokenBalance, fromAssetBalance] = await Promise.all([this.balanceService.getTransferableBalance(params.address, feeTokenInfo.originChain, feeTokenInfo.slug), this.balanceService.getTransferableBalance(params.address, fromAsset.originChain, fromAsset.slug)]);
|
|
137
|
+
const balanceError = _validateBalanceToSwap(fromAsset, feeTokenInfo, feeTokenChain, networkFee.amount, fromAssetBalance.value, feeTokenBalance.value, fromAmount, isXcmOk, minSwap);
|
|
138
|
+
if (balanceError) {
|
|
139
|
+
return Promise.resolve([balanceError]);
|
|
137
140
|
}
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
return Promise.resolve([new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, `Insufficient balance. Deposit ${fromAsset.symbol} and try again.`)]);
|
|
141
|
-
}
|
|
141
|
+
if (!params.recipient) {
|
|
142
|
+
return Promise.resolve([]);
|
|
142
143
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const bnSrcAssetMinAmount = new BigNumber(_getTokenMinAmount(fromAsset));
|
|
152
|
-
const bnMaxBalanceSwap = bnFromAssetBalance.minus(bnSrcAssetMinAmount);
|
|
153
|
-
if (!isXcmOk && bnAmount.gte(bnMaxBalanceSwap)) {
|
|
154
|
-
const parsedMaxBalanceSwap = formatNumber(bnMaxBalanceSwap, _getAssetDecimals(fromAsset));
|
|
155
|
-
return Promise.resolve([new TransactionError(SwapErrorType.SWAP_EXCEED_ALLOWANCE, `Amount too high. Lower your amount ${bnMaxBalanceSwap.gt(0) ? `below ${parsedMaxBalanceSwap} ${fromAsset.symbol}` : ''} and try again`)]);
|
|
156
|
-
}
|
|
157
|
-
if (params.recipient) {
|
|
158
|
-
const toAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.to);
|
|
159
|
-
const destChainInfo = this.chainService.getChainInfoByKey(toAsset.originChain);
|
|
160
|
-
const isEvmAddress = isEthereumAddress(params.recipient);
|
|
161
|
-
const isEvmDestChain = _isChainEvmCompatible(destChainInfo);
|
|
162
|
-
if (isEvmAddress && !isEvmDestChain || !isEvmAddress && isEvmDestChain) {
|
|
163
|
-
return Promise.resolve([new TransactionError(SwapErrorType.INVALID_RECIPIENT)]);
|
|
164
|
-
}
|
|
144
|
+
const toAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.to);
|
|
145
|
+
const toAssetChain = this.chainService.getChainInfoByKey(toAsset.originChain);
|
|
146
|
+
const recipientError = _validateSwapRecipient(toAssetChain, params.recipient);
|
|
147
|
+
if (recipientError) {
|
|
148
|
+
return Promise.resolve([recipientError]);
|
|
165
149
|
}
|
|
166
150
|
return Promise.resolve([]);
|
|
167
151
|
}
|