@subwallet/extension-base 1.1.51-1 → 1.1.52-0
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 +1 -0
- package/cjs/koni/api/tokens/evm/balance.js +1 -2
- package/cjs/koni/api/tokens/evm/transfer.js +3 -5
- package/cjs/koni/api/tokens/evm/web3.js +3 -3
- package/cjs/koni/background/handlers/Extension.js +5 -4
- package/cjs/koni/background/handlers/State.js +21 -122
- package/cjs/koni/background/subscription.js +3 -63
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/BalanceMapImpl.js +2 -2
- package/cjs/services/balance-service/helpers/index.js +27 -0
- package/cjs/services/balance-service/helpers/subscribe/evm.js +33 -15
- package/cjs/services/balance-service/helpers/subscribe/{balance.js → index.js} +46 -29
- package/cjs/services/balance-service/helpers/subscribe/substrate/equilibrium.js +34 -15
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +156 -72
- package/cjs/services/balance-service/index.js +371 -44
- package/cjs/services/chain-service/constants.js +2 -1
- package/cjs/services/chain-service/health-check/utils/asset-info.js +1 -3
- package/cjs/services/chain-service/index.js +60 -26
- package/cjs/services/chain-service/utils/index.js +10 -2
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +2 -2
- package/cjs/services/earning-service/handlers/native-staking/para-chain.js +1 -1
- package/cjs/services/migration-service/scripts/AutoEnableChainsTokens.js +1 -1
- package/cjs/services/storage-service/DatabaseService.js +10 -1
- package/cjs/stores/DetectAccountBalance.js +18 -0
- package/cjs/utils/asset.js +19 -0
- package/cjs/utils/index.js +12 -0
- package/koni/api/tokens/evm/balance.d.ts +1 -1
- package/koni/api/tokens/evm/balance.js +1 -2
- package/koni/api/tokens/evm/transfer.d.ts +2 -2
- package/koni/api/tokens/evm/transfer.js +3 -5
- package/koni/api/tokens/evm/web3.d.ts +1 -1
- package/koni/api/tokens/evm/web3.js +2 -2
- package/koni/background/handlers/Extension.js +5 -4
- package/koni/background/handlers/State.d.ts +2 -13
- package/koni/background/handlers/State.js +21 -121
- package/koni/background/subscription.d.ts +1 -5
- package/koni/background/subscription.js +1 -60
- package/package.json +28 -13
- package/packageInfo.js +1 -1
- package/services/balance-service/BalanceMapImpl.js +1 -1
- package/services/balance-service/helpers/index.d.ts +2 -0
- package/services/balance-service/helpers/index.js +5 -0
- package/services/balance-service/helpers/subscribe/evm.d.ts +3 -5
- package/services/balance-service/helpers/subscribe/evm.js +31 -14
- package/services/balance-service/helpers/subscribe/{balance.d.ts → index.d.ts} +2 -2
- package/services/balance-service/helpers/subscribe/{balance.js → index.js} +41 -28
- package/services/balance-service/helpers/subscribe/substrate/equilibrium.d.ts +3 -4
- package/services/balance-service/helpers/subscribe/substrate/equilibrium.js +29 -13
- package/services/balance-service/helpers/subscribe/substrate/index.d.ts +2 -2
- package/services/balance-service/helpers/subscribe/substrate/index.js +143 -67
- package/services/balance-service/index.d.ts +71 -4
- package/services/balance-service/index.js +372 -46
- package/services/chain-service/constants.js +2 -1
- package/services/chain-service/health-check/utils/asset-info.js +1 -3
- package/services/chain-service/index.d.ts +2 -1
- package/services/chain-service/index.js +61 -27
- package/services/chain-service/types.d.ts +1 -0
- package/services/chain-service/utils/index.js +10 -2
- package/services/chain-service/utils/patch.js +1 -1
- package/services/earning-service/handlers/liquid-staking/stella-swap.js +2 -2
- package/services/earning-service/handlers/native-staking/para-chain.js +1 -1
- package/services/migration-service/scripts/AutoEnableChainsTokens.js +1 -1
- package/services/storage-service/DatabaseService.js +7 -1
- package/services/storage-service/databases/index.d.ts +1 -0
- package/stores/DetectAccountBalance.d.ts +5 -0
- package/stores/DetectAccountBalance.js +10 -0
- package/types/{balance.d.ts → balance/index.d.ts} +16 -0
- package/types/index.js +1 -1
- package/utils/asset.d.ts +2 -0
- package/utils/asset.js +12 -0
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- /package/cjs/types/{balance.js → balance/index.js} +0 -0
- /package/types/{balance.js → balance/index.js} +0 -0
|
@@ -1,17 +1,50 @@
|
|
|
1
|
-
import { AmountData } from '@subwallet/extension-base/background/KoniTypes';
|
|
1
|
+
import { AmountData, DetectBalanceCache } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
2
|
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
|
|
3
|
-
import {
|
|
3
|
+
import { ServiceStatus, StoppableServiceInterface } from '@subwallet/extension-base/services/base/types';
|
|
4
|
+
import { EventItem, EventType } from '@subwallet/extension-base/services/event-service/types';
|
|
5
|
+
import { BalanceItem, BalanceJson } from '@subwallet/extension-base/types';
|
|
6
|
+
import { PromiseHandler } from '@subwallet/extension-base/utils';
|
|
7
|
+
import { BehaviorSubject } from 'rxjs';
|
|
4
8
|
/**
|
|
5
9
|
* Balance service
|
|
6
10
|
* @class
|
|
7
11
|
*/
|
|
8
|
-
export declare class BalanceService {
|
|
12
|
+
export declare class BalanceService implements StoppableServiceInterface {
|
|
9
13
|
private state;
|
|
14
|
+
private balanceMap;
|
|
15
|
+
private balanceUpdateCache;
|
|
16
|
+
startPromiseHandler: PromiseHandler<void>;
|
|
17
|
+
stopPromiseHandler: PromiseHandler<void>;
|
|
18
|
+
status: ServiceStatus;
|
|
19
|
+
private isReload;
|
|
20
|
+
private readonly detectAccountBalanceStore;
|
|
21
|
+
private readonly balanceDetectSubject;
|
|
22
|
+
private readonly intervalTime;
|
|
23
|
+
private readonly cacheTime;
|
|
10
24
|
/**
|
|
11
25
|
* @constructor
|
|
12
26
|
* @param {KoniState} state - The state of extension.
|
|
13
27
|
*/
|
|
14
28
|
constructor(state: KoniState);
|
|
29
|
+
/** Init service */
|
|
30
|
+
init(): Promise<void>;
|
|
31
|
+
/** Restore balance map */
|
|
32
|
+
loadData(): Promise<void>;
|
|
33
|
+
/** Start service */
|
|
34
|
+
start(): Promise<void>;
|
|
35
|
+
/** Stop service */
|
|
36
|
+
stop(): Promise<void>;
|
|
37
|
+
/** Wait service start */
|
|
38
|
+
waitForStarted(): Promise<void>;
|
|
39
|
+
/** Wait service stop */
|
|
40
|
+
waitForStopped(): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Handle when data change
|
|
43
|
+
* */
|
|
44
|
+
handleEvents(events: EventItem<EventType>[], eventTypes: EventType[]): void;
|
|
45
|
+
getBalanceDetectCache(update: (value: DetectBalanceCache) => void): void;
|
|
46
|
+
setBalanceDetectCache(addresses: string[]): void;
|
|
47
|
+
/** Subscribe token free balance of a address on chain */
|
|
15
48
|
subscribeTokenFreeBalance(address: string, chain: string, tokenSlug: string | undefined, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
|
|
16
49
|
/**
|
|
17
50
|
* @public
|
|
@@ -24,5 +57,39 @@ export declare class BalanceService {
|
|
|
24
57
|
* @return {Promise<AmountData>} - Free token balance of address on chain
|
|
25
58
|
*/
|
|
26
59
|
getTokenFreeBalance(address: string, chain: string, tokenSlug?: string): Promise<AmountData>;
|
|
27
|
-
|
|
60
|
+
/** Remove balance from the subject object by addresses */
|
|
61
|
+
removeBalanceByAddresses(addresses: string[]): void;
|
|
62
|
+
/** Remove inactive asset from the balance map */
|
|
63
|
+
removeInactiveChainBalances(): Promise<void>;
|
|
64
|
+
getBalance(reset?: boolean): Promise<BalanceJson>;
|
|
65
|
+
/** Get stored balance from db */
|
|
66
|
+
getStoredBalance(address: string): Promise<BalanceItem[]>;
|
|
67
|
+
handleResetBalance(forceRefresh?: boolean): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Update value for balance map
|
|
70
|
+
* Note: items must be same tokenSlug */
|
|
71
|
+
setBalanceItem(items: BalanceItem[]): void;
|
|
72
|
+
/**
|
|
73
|
+
* Store balance map to db
|
|
74
|
+
* */
|
|
75
|
+
private updateBalanceStore;
|
|
76
|
+
/**
|
|
77
|
+
* Subscribe balance map with subject object
|
|
78
|
+
* */
|
|
79
|
+
subscribeBalanceMap(): BehaviorSubject<import("@subwallet/extension-base/types").BalanceMap>;
|
|
80
|
+
/** Subscribe area */
|
|
81
|
+
private _unsubscribeBalance;
|
|
82
|
+
/** Subscribe balance subscription */
|
|
83
|
+
runSubscribeBalances(): Promise<void>;
|
|
84
|
+
/** Unsubscribe balance subscription */
|
|
85
|
+
runUnsubscribeBalances(): void;
|
|
86
|
+
/** Reload balance subscription */
|
|
87
|
+
reloadBalance(): Promise<void>;
|
|
88
|
+
/** Subscribe area */
|
|
89
|
+
autoEnableChains(addresses: string[]): Promise<void>;
|
|
90
|
+
private _intervalScan;
|
|
91
|
+
private _unsubscribeBalanceDetectCache;
|
|
92
|
+
private startBalanceDetectCache;
|
|
93
|
+
private startScanBalance;
|
|
94
|
+
private stopScanBalance;
|
|
28
95
|
}
|
|
@@ -3,36 +3,163 @@
|
|
|
3
3
|
|
|
4
4
|
import { BalanceError } from '@subwallet/extension-base/background/errors/BalanceError';
|
|
5
5
|
import { BalanceErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
6
|
+
import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
|
|
7
|
+
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
8
|
+
import { _getChainNativeTokenSlug } from '@subwallet/extension-base/services/chain-service/utils';
|
|
9
|
+
import DetectAccountBalanceStore from '@subwallet/extension-base/stores/DetectAccountBalance';
|
|
10
|
+
import { addLazy, createPromiseHandler, isAccountAll, waitTimeout } from '@subwallet/extension-base/utils';
|
|
11
|
+
import keyring from '@subwallet/ui-keyring';
|
|
12
12
|
import { t } from 'i18next';
|
|
13
|
+
import { BehaviorSubject } from 'rxjs';
|
|
14
|
+
import { noop } from '@polkadot/util';
|
|
15
|
+
import { BalanceMapImpl } from "./BalanceMapImpl.js";
|
|
16
|
+
import { subscribeBalance } from "./helpers/index.js";
|
|
13
17
|
|
|
14
18
|
/**
|
|
15
19
|
* Balance service
|
|
16
20
|
* @class
|
|
17
21
|
*/
|
|
18
22
|
export class BalanceService {
|
|
23
|
+
balanceUpdateCache = [];
|
|
24
|
+
startPromiseHandler = createPromiseHandler();
|
|
25
|
+
stopPromiseHandler = createPromiseHandler();
|
|
26
|
+
status = ServiceStatus.NOT_INITIALIZED;
|
|
27
|
+
isReload = false;
|
|
28
|
+
detectAccountBalanceStore = new DetectAccountBalanceStore();
|
|
29
|
+
balanceDetectSubject = new BehaviorSubject({});
|
|
30
|
+
intervalTime = 3 * 60 * 1000;
|
|
31
|
+
cacheTime = 15 * 60 * 1000;
|
|
32
|
+
|
|
19
33
|
/**
|
|
20
34
|
* @constructor
|
|
21
35
|
* @param {KoniState} state - The state of extension.
|
|
22
36
|
*/
|
|
23
37
|
constructor(state) {
|
|
24
38
|
this.state = state;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
39
|
+
this.balanceMap = new BalanceMapImpl();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Init service */
|
|
43
|
+
async init() {
|
|
44
|
+
this.status = ServiceStatus.INITIALIZING;
|
|
45
|
+
await this.state.eventService.waitChainReady;
|
|
46
|
+
await this.state.eventService.waitAccountReady;
|
|
47
|
+
|
|
48
|
+
// Load data from db to balanceSubject
|
|
49
|
+
await this.loadData();
|
|
50
|
+
this.status = ServiceStatus.INITIALIZED;
|
|
51
|
+
|
|
52
|
+
// Start service
|
|
53
|
+
await this.start();
|
|
54
|
+
|
|
55
|
+
// Handle events
|
|
56
|
+
this.state.eventService.onLazy(this.handleEvents.bind(this));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Restore balance map */
|
|
60
|
+
async loadData() {
|
|
61
|
+
const backupBalanceData = await this.state.dbService.getStoredBalance();
|
|
62
|
+
this.balanceMap.updateBalanceItems(backupBalanceData, true);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Start service */
|
|
66
|
+
async start() {
|
|
67
|
+
if (this.status === ServiceStatus.STOPPING) {
|
|
68
|
+
await this.waitForStopped();
|
|
69
|
+
}
|
|
70
|
+
if (this.status === ServiceStatus.STARTED || this.status === ServiceStatus.STARTING) {
|
|
71
|
+
return await this.waitForStarted();
|
|
72
|
+
}
|
|
73
|
+
this.status = ServiceStatus.STARTING;
|
|
74
|
+
await this.startScanBalance();
|
|
75
|
+
|
|
76
|
+
// Run subscribe balance
|
|
77
|
+
await this.runSubscribeBalances();
|
|
78
|
+
|
|
79
|
+
// Update status
|
|
80
|
+
this.stopPromiseHandler = createPromiseHandler();
|
|
81
|
+
this.status = ServiceStatus.STARTED;
|
|
82
|
+
this.startPromiseHandler.resolve();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Stop service */
|
|
86
|
+
async stop() {
|
|
87
|
+
if (this.status === ServiceStatus.STARTING) {
|
|
88
|
+
await this.waitForStarted();
|
|
89
|
+
}
|
|
90
|
+
if (this.status === ServiceStatus.STOPPED || this.status === ServiceStatus.STOPPING) {
|
|
91
|
+
return await this.waitForStopped();
|
|
92
|
+
}
|
|
93
|
+
this.runUnsubscribeBalances();
|
|
94
|
+
this.stopScanBalance();
|
|
95
|
+
|
|
96
|
+
// Update status
|
|
97
|
+
this.startPromiseHandler = createPromiseHandler();
|
|
98
|
+
this.status = ServiceStatus.STOPPING;
|
|
99
|
+
this.stopPromiseHandler.resolve();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Wait service start */
|
|
103
|
+
waitForStarted() {
|
|
104
|
+
return this.startPromiseHandler.promise;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Wait service stop */
|
|
108
|
+
waitForStopped() {
|
|
109
|
+
return this.stopPromiseHandler.promise;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Handle when data change
|
|
114
|
+
* */
|
|
115
|
+
handleEvents(events, eventTypes) {
|
|
116
|
+
const removedAddresses = [];
|
|
117
|
+
let needReload = false;
|
|
118
|
+
let lazyTime = 2000;
|
|
119
|
+
|
|
120
|
+
// Account changed or chain changed (active or inactive)
|
|
121
|
+
if (eventTypes.includes('account.updateCurrent') || eventTypes.includes('account.add') || eventTypes.includes('chain.updateState') || eventTypes.includes('asset.updateState')) {
|
|
122
|
+
needReload = true;
|
|
123
|
+
if (eventTypes.includes('account.updateCurrent')) {
|
|
124
|
+
lazyTime = 1000;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
events.forEach(event => {
|
|
128
|
+
if (event.type === 'account.remove') {
|
|
129
|
+
removedAddresses.push(event.data[0]);
|
|
130
|
+
lazyTime = 1000;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
if (removedAddresses.length > 0) {
|
|
134
|
+
this.balanceMap.removeBalanceItems([...removedAddresses, ALL_ACCOUNT_KEY]); // Add all account key to recalculate all account balances
|
|
135
|
+
needReload = true;
|
|
136
|
+
}
|
|
137
|
+
if (needReload) {
|
|
138
|
+
addLazy('reloadBalanceByEvents', () => {
|
|
139
|
+
if (!this.isReload) {
|
|
140
|
+
this.runSubscribeBalances().catch(console.error);
|
|
141
|
+
}
|
|
142
|
+
}, lazyTime, undefined, true);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
getBalanceDetectCache(update) {
|
|
146
|
+
this.detectAccountBalanceStore.get('DetectBalanceCache', value => {
|
|
147
|
+
update(value);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
setBalanceDetectCache(addresses) {
|
|
151
|
+
this.detectAccountBalanceStore.get('DetectBalanceCache', value => {
|
|
152
|
+
const rs = {
|
|
153
|
+
...value
|
|
154
|
+
};
|
|
155
|
+
for (const address of addresses) {
|
|
156
|
+
rs[address] = Date.now();
|
|
157
|
+
}
|
|
158
|
+
this.detectAccountBalanceStore.set('DetectBalanceCache', rs);
|
|
159
|
+
});
|
|
33
160
|
}
|
|
34
161
|
|
|
35
|
-
|
|
162
|
+
/** Subscribe token free balance of a address on chain */
|
|
36
163
|
async subscribeTokenFreeBalance(address, chain, tokenSlug, callback) {
|
|
37
164
|
const chainInfo = this.state.chainService.getChainInfoByKey(chain);
|
|
38
165
|
const chainState = this.state.chainService.getChainStateByKey(chain);
|
|
@@ -54,7 +181,12 @@ export class BalanceService {
|
|
|
54
181
|
}
|
|
55
182
|
return new Promise((resolve, reject) => {
|
|
56
183
|
let hasError = true;
|
|
57
|
-
const
|
|
184
|
+
const assetMap = this.state.chainService.getAssetRegistry();
|
|
185
|
+
const chainInfoMap = this.state.chainService.getChainInfoMap();
|
|
186
|
+
const evmApiMap = this.state.chainService.getEvmApiMap();
|
|
187
|
+
const substrateApiMap = this.state.chainService.getSubstrateApiMap();
|
|
188
|
+
const unsub = subscribeBalance([address], [chain], [tSlug], assetMap, chainInfoMap, substrateApiMap, evmApiMap, result => {
|
|
189
|
+
const rs = result[0];
|
|
58
190
|
if (rs.tokenSlug === tSlug) {
|
|
59
191
|
hasError = false;
|
|
60
192
|
const balance = {
|
|
@@ -94,43 +226,237 @@ export class BalanceService {
|
|
|
94
226
|
const [, balance] = await this.subscribeTokenFreeBalance(address, chain, tokenSlug);
|
|
95
227
|
return balance;
|
|
96
228
|
}
|
|
97
|
-
|
|
98
|
-
|
|
229
|
+
|
|
230
|
+
/** Remove balance from the subject object by addresses */
|
|
231
|
+
removeBalanceByAddresses(addresses) {
|
|
232
|
+
this.balanceMap.removeBalanceItems([...addresses, ALL_ACCOUNT_KEY]);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Remove inactive asset from the balance map */
|
|
236
|
+
async removeInactiveChainBalances() {
|
|
237
|
+
const assetSettings = await this.state.chainService.getAssetSettings();
|
|
238
|
+
this.balanceMap.removeBalanceItemByFilter(item => {
|
|
239
|
+
return !assetSettings[item.tokenSlug];
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
async getBalance(reset) {
|
|
243
|
+
await this.removeInactiveChainBalances();
|
|
244
|
+
return {
|
|
245
|
+
details: this.balanceMap.map,
|
|
246
|
+
reset
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Get stored balance from db */
|
|
251
|
+
async getStoredBalance(address) {
|
|
252
|
+
return await this.state.dbService.stores.balance.getBalanceMapByAddresses(address);
|
|
253
|
+
}
|
|
254
|
+
async handleResetBalance(forceRefresh) {
|
|
255
|
+
if (forceRefresh) {
|
|
256
|
+
this.balanceMap.setData({});
|
|
257
|
+
await this.state.dbService.stores.balance.clear();
|
|
258
|
+
} else {
|
|
259
|
+
await Promise.all([this.removeInactiveChainBalances()]);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Update value for balance map
|
|
265
|
+
* Note: items must be same tokenSlug */
|
|
266
|
+
setBalanceItem(items) {
|
|
267
|
+
if (items.length) {
|
|
268
|
+
const nowTime = new Date().getTime();
|
|
269
|
+
for (const item of items) {
|
|
270
|
+
const balance = {
|
|
271
|
+
timestamp: nowTime,
|
|
272
|
+
...item
|
|
273
|
+
};
|
|
274
|
+
this.balanceUpdateCache.push(balance);
|
|
275
|
+
}
|
|
276
|
+
addLazy('updateBalanceStore', () => {
|
|
277
|
+
const isAllAccount = isAccountAll(this.state.keyringService.currentAccount.address);
|
|
278
|
+
this.balanceMap.updateBalanceItems(this.balanceUpdateCache, isAllAccount);
|
|
279
|
+
if (isAllAccount) {
|
|
280
|
+
this.balanceUpdateCache = [...this.balanceUpdateCache, ...Object.values(this.balanceMap.map[ALL_ACCOUNT_KEY])];
|
|
281
|
+
}
|
|
282
|
+
this.updateBalanceStore(this.balanceUpdateCache);
|
|
283
|
+
this.balanceUpdateCache = [];
|
|
284
|
+
}, 300, 1800);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Store balance map to db
|
|
290
|
+
* */
|
|
291
|
+
updateBalanceStore(items) {
|
|
292
|
+
this.state.dbService.updateBulkBalanceStore(items).catch(console.warn);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Subscribe balance map with subject object
|
|
297
|
+
* */
|
|
298
|
+
subscribeBalanceMap() {
|
|
299
|
+
return this.balanceMap.mapSubject;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/** Subscribe area */
|
|
303
|
+
|
|
304
|
+
/** Subscribe balance subscription */
|
|
305
|
+
async runSubscribeBalances() {
|
|
306
|
+
await Promise.all([this.state.eventService.waitKeyringReady, this.state.eventService.waitChainReady]);
|
|
307
|
+
this.runUnsubscribeBalances();
|
|
308
|
+
const addresses = this.state.getDecodedAddresses();
|
|
309
|
+
if (!addresses.length) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Reset balance before subscribe
|
|
314
|
+
await this.handleResetBalance();
|
|
315
|
+
let cancel = false;
|
|
316
|
+
const assetMap = this.state.chainService.getAssetRegistry();
|
|
99
317
|
const chainInfoMap = this.state.chainService.getChainInfoMap();
|
|
100
|
-
const chainStateMap = this.state.chainService.getChainStateMap();
|
|
101
|
-
const substrateApiMap = this.state.chainService.getSubstrateApiMap();
|
|
102
318
|
const evmApiMap = this.state.chainService.getEvmApiMap();
|
|
319
|
+
const substrateApiMap = this.state.chainService.getSubstrateApiMap();
|
|
320
|
+
const activeChainSlugs = Object.keys(this.state.getActiveChainInfoMap());
|
|
321
|
+
const assetState = this.state.chainService.subscribeAssetSettings().value;
|
|
322
|
+
const assets = Object.values(assetMap).filter(asset => {
|
|
323
|
+
var _assetState$asset$slu;
|
|
324
|
+
return activeChainSlugs.includes(asset.originChain) && ((_assetState$asset$slu = assetState[asset.slug]) === null || _assetState$asset$slu === void 0 ? void 0 : _assetState$asset$slu.visible);
|
|
325
|
+
}).map(asset => asset.slug);
|
|
326
|
+
const unsub = subscribeBalance(addresses, activeChainSlugs, assets, assetMap, chainInfoMap, substrateApiMap, evmApiMap, result => {
|
|
327
|
+
!cancel && this.setBalanceItem(result);
|
|
328
|
+
});
|
|
329
|
+
const unsub2 = this.state.subscribeMantaPayBalance();
|
|
330
|
+
this._unsubscribeBalance = () => {
|
|
331
|
+
cancel = true;
|
|
332
|
+
unsub && unsub();
|
|
333
|
+
unsub2 && unsub2();
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** Unsubscribe balance subscription */
|
|
338
|
+
runUnsubscribeBalances() {
|
|
339
|
+
this._unsubscribeBalance && this._unsubscribeBalance();
|
|
340
|
+
this._unsubscribeBalance = undefined;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/** Reload balance subscription */
|
|
344
|
+
async reloadBalance() {
|
|
345
|
+
this.isReload = true;
|
|
346
|
+
await this.handleResetBalance(true);
|
|
347
|
+
await this.runSubscribeBalances();
|
|
348
|
+
await waitTimeout(1800);
|
|
349
|
+
this.isReload = false;
|
|
350
|
+
}
|
|
103
351
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
352
|
+
/** Subscribe area */
|
|
353
|
+
|
|
354
|
+
async autoEnableChains(addresses) {
|
|
355
|
+
this.setBalanceDetectCache(addresses);
|
|
356
|
+
const assetMap = this.state.chainService.getAssetRegistry();
|
|
357
|
+
const promiseList = addresses.map(address => {
|
|
358
|
+
return this.state.subscanService.getMultiChainBalance(address).catch(e => {
|
|
359
|
+
console.error(e);
|
|
360
|
+
return null;
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
const needEnableChains = [];
|
|
364
|
+
const needActiveTokens = [];
|
|
365
|
+
const balanceDataList = await Promise.all(promiseList);
|
|
366
|
+
const currentAssetSettings = await this.state.chainService.getAssetSettings();
|
|
367
|
+
const chainInfoMap = this.state.chainService.getChainInfoMap();
|
|
368
|
+
const detectBalanceChainSlugMap = this.state.chainService.detectBalanceChainSlugMap;
|
|
369
|
+
for (const balanceData of balanceDataList) {
|
|
370
|
+
if (balanceData) {
|
|
371
|
+
for (const balanceDatum of balanceData) {
|
|
372
|
+
var _currentAssetSettings;
|
|
373
|
+
const {
|
|
374
|
+
balance,
|
|
375
|
+
bonded,
|
|
376
|
+
category,
|
|
377
|
+
locked,
|
|
378
|
+
network,
|
|
379
|
+
symbol
|
|
380
|
+
} = balanceDatum;
|
|
381
|
+
const chain = detectBalanceChainSlugMap[network];
|
|
382
|
+
const chainInfo = chain ? chainInfoMap[chain] : null;
|
|
383
|
+
const chainState = this.state.chainService.getChainStateByKey(chain);
|
|
384
|
+
const balanceIsEmpty = (!balance || balance === '0') && (!locked || locked === '0') && (!bonded || bonded === '0');
|
|
385
|
+
const tokenKey = `${chain}-${category === 'native' ? 'NATIVE' : 'LOCAL'}-${symbol.toUpperCase()}`;
|
|
386
|
+
const existedKey = Object.keys(assetMap).find(v => v.toLowerCase() === tokenKey.toLowerCase());
|
|
387
|
+
|
|
388
|
+
// Cancel if chain is not supported or is testnet
|
|
389
|
+
if (!chainInfo || chainInfo.isTestnet) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Cancel is balance is 0
|
|
394
|
+
if (balanceIsEmpty) {
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Cancel is chain is turned off by user
|
|
399
|
+
if (chainState && chainState.manualTurnOff) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// const a = this.state.chainService.getChainStateByKey(chain);
|
|
404
|
+
|
|
405
|
+
if (existedKey && !((_currentAssetSettings = currentAssetSettings[existedKey]) !== null && _currentAssetSettings !== void 0 && _currentAssetSettings.visible)) {
|
|
406
|
+
needEnableChains.push(chain);
|
|
407
|
+
needActiveTokens.push(existedKey);
|
|
408
|
+
currentAssetSettings[existedKey] = {
|
|
409
|
+
visible: true
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
}
|
|
111
413
|
}
|
|
414
|
+
}
|
|
415
|
+
if (needActiveTokens.length) {
|
|
416
|
+
await this.state.chainService.enableChains(needEnableChains);
|
|
417
|
+
this.state.chainService.setAssetSettings({
|
|
418
|
+
...currentAssetSettings
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
async startScanBalance() {
|
|
423
|
+
var _this$startBalanceDet2;
|
|
424
|
+
await Promise.all([this.state.eventService.waitAccountReady, this.state.eventService.waitChainReady]);
|
|
425
|
+
this.stopScanBalance();
|
|
426
|
+
this.startBalanceDetectCache = createPromiseHandler();
|
|
427
|
+
const updateBalanceDetectCache = value => {
|
|
428
|
+
var _this$startBalanceDet;
|
|
429
|
+
(_this$startBalanceDet = this.startBalanceDetectCache) === null || _this$startBalanceDet === void 0 ? void 0 : _this$startBalanceDet.resolve();
|
|
430
|
+
this.balanceDetectSubject.next(value || {});
|
|
112
431
|
};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
432
|
+
this.getBalanceDetectCache(updateBalanceDetectCache);
|
|
433
|
+
const subscription = this.detectAccountBalanceStore.getSubject().subscribe({
|
|
434
|
+
next: updateBalanceDetectCache
|
|
435
|
+
});
|
|
436
|
+
this._unsubscribeBalanceDetectCache = subscription.unsubscribe;
|
|
437
|
+
const scanBalance = () => {
|
|
438
|
+
const addresses = keyring.getPairs().map(account => account.address);
|
|
439
|
+
const cache = this.balanceDetectSubject.value;
|
|
440
|
+
const now = Date.now();
|
|
441
|
+
const needDetectAddresses = [];
|
|
442
|
+
for (const address of addresses) {
|
|
443
|
+
if (!cache[address] || now - cache[address] > this.cacheTime) {
|
|
444
|
+
needDetectAddresses.push(address);
|
|
445
|
+
}
|
|
121
446
|
}
|
|
122
|
-
if (
|
|
123
|
-
|
|
447
|
+
if (needDetectAddresses.length) {
|
|
448
|
+
this.autoEnableChains(needDetectAddresses).finally(noop);
|
|
124
449
|
}
|
|
125
|
-
const networkAPI = await substrateApiMap[chainSlug].isReady;
|
|
126
|
-
return subscribeSubstrateBalance(useAddresses, chainInfo, chainSlug, networkAPI, evmApiMap, callback);
|
|
127
|
-
});
|
|
128
|
-
return () => {
|
|
129
|
-
unsubList.forEach(subProm => {
|
|
130
|
-
subProm.then(unsub => {
|
|
131
|
-
unsub && unsub();
|
|
132
|
-
}).catch(console.error);
|
|
133
|
-
});
|
|
134
450
|
};
|
|
451
|
+
await ((_this$startBalanceDet2 = this.startBalanceDetectCache) === null || _this$startBalanceDet2 === void 0 ? void 0 : _this$startBalanceDet2.promise);
|
|
452
|
+
scanBalance();
|
|
453
|
+
this._intervalScan = setInterval(scanBalance, this.intervalTime);
|
|
454
|
+
}
|
|
455
|
+
stopScanBalance() {
|
|
456
|
+
this._intervalScan && clearInterval(this._intervalScan);
|
|
457
|
+
this._unsubscribeBalanceDetectCache && this._unsubscribeBalanceDetectCache();
|
|
458
|
+
this._intervalScan = undefined;
|
|
459
|
+
this._unsubscribeBalanceDetectCache = undefined;
|
|
460
|
+
this.startBalanceDetectCache = undefined;
|
|
135
461
|
}
|
|
136
462
|
}
|
|
@@ -240,7 +240,8 @@ export const _DEFAULT_ACTIVE_CHAINS = [..._DEFAULT_CHAINS, 'vara_network'];
|
|
|
240
240
|
export const EVM_PASS_CONNECT_STATUS = {
|
|
241
241
|
arbitrum_one: ['*'],
|
|
242
242
|
okxTest: ['*'],
|
|
243
|
-
astarZkEvm: ['*']
|
|
243
|
+
astarZkEvm: ['*'],
|
|
244
|
+
xlayer: ['*']
|
|
244
245
|
};
|
|
245
246
|
export const EVM_REFORMAT_DECIMALS = {
|
|
246
247
|
acala: ['acala_evm', 'karura_evm']
|
|
@@ -216,9 +216,7 @@ export const getEvmNativeInfo = async api => {
|
|
|
216
216
|
};
|
|
217
217
|
export const getErc20AssetInfo = async (asset, api) => {
|
|
218
218
|
const contractAddress = _getContractAddressOfToken(asset);
|
|
219
|
-
const tokenContract = getERC20Contract(
|
|
220
|
-
chain: api
|
|
221
|
-
});
|
|
219
|
+
const tokenContract = getERC20Contract(contractAddress, api);
|
|
222
220
|
const [_decimals, _symbol, _name] = await Promise.all([
|
|
223
221
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
224
222
|
tokenContract.methods.decimals().call(),
|
|
@@ -83,7 +83,7 @@ export declare class ChainService {
|
|
|
83
83
|
initAssetRefMap(): void;
|
|
84
84
|
checkLatestData(): void;
|
|
85
85
|
stopCheckLatestChainData(): void;
|
|
86
|
-
|
|
86
|
+
handleLatestChainData(latestChainInfo: _ChainInfo[]): void;
|
|
87
87
|
handleLatestAssetRef(latestBlockedAssetRefList: string[], latestAssetRefMap: Record<string, _AssetRef> | null): void;
|
|
88
88
|
handleLatestPriceId(latestPriceIds: Record<string, string | null>): void;
|
|
89
89
|
handleLatestAssetData(latestAssetInfo: Record<string, _ChainAsset> | null, latestAssetLogoMap: Record<string, string> | null): void;
|
|
@@ -138,4 +138,5 @@ export declare class ChainService {
|
|
|
138
138
|
upsertMetadata(chain: string, metadata: IMetadataItem): import("dexie").PromiseExtended<unknown>;
|
|
139
139
|
getMetadataByHash(hash: string): import("dexie").PromiseExtended<IMetadataItem | undefined>;
|
|
140
140
|
getSubscanChainMap(reverse?: boolean): Record<string, string>;
|
|
141
|
+
get detectBalanceChainSlugMap(): Record<string, string>;
|
|
141
142
|
}
|