@subwallet/extension-base 1.1.51-2 → 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/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 +8 -71
- 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 +277 -75
- 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 +1 -9
- 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/storage-service/DatabaseService.js +10 -1
- 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 +1 -12
- package/koni/background/handlers/State.js +9 -72
- package/koni/background/subscription.d.ts +1 -5
- package/koni/background/subscription.js +1 -60
- package/package.json +23 -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 +64 -6
- package/services/balance-service/index.js +279 -77
- 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.js +2 -10
- package/services/chain-service/utils/patch.js +1 -1
- package/services/earning-service/handlers/liquid-staking/stella-swap.js +2 -2
- package/services/storage-service/DatabaseService.js +7 -1
- 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,25 +1,50 @@
|
|
|
1
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 {
|
|
9
|
-
private
|
|
12
|
+
export declare class BalanceService implements StoppableServiceInterface {
|
|
13
|
+
private state;
|
|
14
|
+
private balanceMap;
|
|
15
|
+
private balanceUpdateCache;
|
|
16
|
+
startPromiseHandler: PromiseHandler<void>;
|
|
17
|
+
stopPromiseHandler: PromiseHandler<void>;
|
|
18
|
+
status: ServiceStatus;
|
|
19
|
+
private isReload;
|
|
10
20
|
private readonly detectAccountBalanceStore;
|
|
11
21
|
private readonly balanceDetectSubject;
|
|
12
22
|
private readonly intervalTime;
|
|
13
23
|
private readonly cacheTime;
|
|
14
|
-
private readonly startHandler;
|
|
15
24
|
/**
|
|
16
25
|
* @constructor
|
|
17
26
|
* @param {KoniState} state - The state of extension.
|
|
18
27
|
*/
|
|
19
28
|
constructor(state: KoniState);
|
|
20
|
-
|
|
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;
|
|
21
45
|
getBalanceDetectCache(update: (value: DetectBalanceCache) => void): void;
|
|
22
46
|
setBalanceDetectCache(addresses: string[]): void;
|
|
47
|
+
/** Subscribe token free balance of a address on chain */
|
|
23
48
|
subscribeTokenFreeBalance(address: string, chain: string, tokenSlug: string | undefined, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
|
|
24
49
|
/**
|
|
25
50
|
* @public
|
|
@@ -32,6 +57,39 @@ export declare class BalanceService {
|
|
|
32
57
|
* @return {Promise<AmountData>} - Free token balance of address on chain
|
|
33
58
|
*/
|
|
34
59
|
getTokenFreeBalance(address: string, chain: string, tokenSlug?: string): Promise<AmountData>;
|
|
35
|
-
|
|
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 */
|
|
36
89
|
autoEnableChains(addresses: string[]): Promise<void>;
|
|
90
|
+
private _intervalScan;
|
|
91
|
+
private _unsubscribeBalanceDetectCache;
|
|
92
|
+
private startBalanceDetectCache;
|
|
93
|
+
private startScanBalance;
|
|
94
|
+
private stopScanBalance;
|
|
37
95
|
}
|
|
@@ -3,73 +3,144 @@
|
|
|
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 { _PURE_EVM_CHAINS } from '@subwallet/extension-base/services/chain-service/constants';
|
|
10
|
-
import { _getChainNativeTokenSlug, _isChainEvmCompatible, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
|
|
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';
|
|
11
9
|
import DetectAccountBalanceStore from '@subwallet/extension-base/stores/DetectAccountBalance';
|
|
12
|
-
import {
|
|
10
|
+
import { addLazy, createPromiseHandler, isAccountAll, waitTimeout } from '@subwallet/extension-base/utils';
|
|
13
11
|
import keyring from '@subwallet/ui-keyring';
|
|
14
12
|
import { t } from 'i18next';
|
|
15
13
|
import { BehaviorSubject } from 'rxjs';
|
|
16
14
|
import { noop } from '@polkadot/util';
|
|
15
|
+
import { BalanceMapImpl } from "./BalanceMapImpl.js";
|
|
16
|
+
import { subscribeBalance } from "./helpers/index.js";
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Balance service
|
|
20
20
|
* @class
|
|
21
21
|
*/
|
|
22
22
|
export class BalanceService {
|
|
23
|
+
balanceUpdateCache = [];
|
|
24
|
+
startPromiseHandler = createPromiseHandler();
|
|
25
|
+
stopPromiseHandler = createPromiseHandler();
|
|
26
|
+
status = ServiceStatus.NOT_INITIALIZED;
|
|
27
|
+
isReload = false;
|
|
23
28
|
detectAccountBalanceStore = new DetectAccountBalanceStore();
|
|
24
29
|
balanceDetectSubject = new BehaviorSubject({});
|
|
25
30
|
intervalTime = 3 * 60 * 1000;
|
|
26
31
|
cacheTime = 15 * 60 * 1000;
|
|
32
|
+
|
|
27
33
|
/**
|
|
28
34
|
* @constructor
|
|
29
35
|
* @param {KoniState} state - The state of extension.
|
|
30
36
|
*/
|
|
31
37
|
constructor(state) {
|
|
32
38
|
this.state = state;
|
|
33
|
-
|
|
34
|
-
// Todo: Start subscribe balance and data
|
|
35
|
-
// Todo: Listen change and apply to balanceSubject
|
|
36
|
-
// Todo: Active/Chain
|
|
37
|
-
// Todo: Add/remove account
|
|
38
|
-
// Todo: Add new account
|
|
39
|
-
// Todo: Optimize get balance for single account and chain with cache
|
|
40
|
-
// Todo: Move everything of fetching balance to this service
|
|
41
|
-
|
|
42
|
-
this.startHandler = createPromiseHandler();
|
|
43
|
-
const updateBalanceDetectCache = value => {
|
|
44
|
-
this.startHandler.resolve();
|
|
45
|
-
this.balanceDetectSubject.next(value || {});
|
|
46
|
-
};
|
|
47
|
-
this.getBalanceDetectCache(updateBalanceDetectCache);
|
|
48
|
-
this.detectAccountBalanceStore.getSubject().subscribe({
|
|
49
|
-
next: updateBalanceDetectCache
|
|
50
|
-
});
|
|
51
|
-
this.startDetectBalance().catch(console.error);
|
|
39
|
+
this.balanceMap = new BalanceMapImpl();
|
|
52
40
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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;
|
|
63
125
|
}
|
|
64
|
-
|
|
65
|
-
|
|
126
|
+
}
|
|
127
|
+
events.forEach(event => {
|
|
128
|
+
if (event.type === 'account.remove') {
|
|
129
|
+
removedAddresses.push(event.data[0]);
|
|
130
|
+
lazyTime = 1000;
|
|
66
131
|
}
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
+
}
|
|
73
144
|
}
|
|
74
145
|
getBalanceDetectCache(update) {
|
|
75
146
|
this.detectAccountBalanceStore.get('DetectBalanceCache', value => {
|
|
@@ -88,7 +159,7 @@ export class BalanceService {
|
|
|
88
159
|
});
|
|
89
160
|
}
|
|
90
161
|
|
|
91
|
-
|
|
162
|
+
/** Subscribe token free balance of a address on chain */
|
|
92
163
|
async subscribeTokenFreeBalance(address, chain, tokenSlug, callback) {
|
|
93
164
|
const chainInfo = this.state.chainService.getChainInfoByKey(chain);
|
|
94
165
|
const chainState = this.state.chainService.getChainStateByKey(chain);
|
|
@@ -110,7 +181,12 @@ export class BalanceService {
|
|
|
110
181
|
}
|
|
111
182
|
return new Promise((resolve, reject) => {
|
|
112
183
|
let hasError = true;
|
|
113
|
-
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];
|
|
114
190
|
if (rs.tokenSlug === tSlug) {
|
|
115
191
|
hasError = false;
|
|
116
192
|
const balance = {
|
|
@@ -150,45 +226,131 @@ export class BalanceService {
|
|
|
150
226
|
const [, balance] = await this.subscribeTokenFreeBalance(address, chain, tokenSlug);
|
|
151
227
|
return balance;
|
|
152
228
|
}
|
|
153
|
-
subscribeBalance(addresses, chains, _callback) {
|
|
154
|
-
const [substrateAddresses, evmAddresses] = categoryAddresses(addresses);
|
|
155
|
-
const chainInfoMap = this.state.chainService.getChainInfoMap();
|
|
156
|
-
const chainStateMap = this.state.chainService.getChainStateMap();
|
|
157
|
-
const substrateApiMap = this.state.chainService.getSubstrateApiMap();
|
|
158
|
-
const evmApiMap = this.state.chainService.getEvmApiMap();
|
|
159
229
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
|
168
247
|
};
|
|
248
|
+
}
|
|
169
249
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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);
|
|
180
275
|
}
|
|
181
|
-
|
|
182
|
-
|
|
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();
|
|
317
|
+
const chainInfoMap = this.state.chainService.getChainInfoMap();
|
|
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);
|
|
183
328
|
});
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
});
|
|
329
|
+
const unsub2 = this.state.subscribeMantaPayBalance();
|
|
330
|
+
this._unsubscribeBalance = () => {
|
|
331
|
+
cancel = true;
|
|
332
|
+
unsub && unsub();
|
|
333
|
+
unsub2 && unsub2();
|
|
190
334
|
};
|
|
191
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
|
+
}
|
|
351
|
+
|
|
352
|
+
/** Subscribe area */
|
|
353
|
+
|
|
192
354
|
async autoEnableChains(addresses) {
|
|
193
355
|
this.setBalanceDetectCache(addresses);
|
|
194
356
|
const assetMap = this.state.chainService.getAssetRegistry();
|
|
@@ -257,4 +419,44 @@ export class BalanceService {
|
|
|
257
419
|
});
|
|
258
420
|
}
|
|
259
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 || {});
|
|
431
|
+
};
|
|
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
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (needDetectAddresses.length) {
|
|
448
|
+
this.autoEnableChains(needDetectAddresses).finally(noop);
|
|
449
|
+
}
|
|
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;
|
|
461
|
+
}
|
|
260
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(),
|
|
@@ -11,7 +11,7 @@ import { _CHAIN_VALIDATION_ERROR } from '@subwallet/extension-base/services/chai
|
|
|
11
11
|
import { _ChainConnectionStatus, _CUSTOM_PREFIX, _NFT_CONTRACT_STANDARDS, _SMART_CONTRACT_STANDARDS } from '@subwallet/extension-base/services/chain-service/types';
|
|
12
12
|
import { _isAssetAutoEnable, _isAssetFungibleToken, _isChainEnabled, _isCustomAsset, _isCustomChain, _isCustomProvider, _isEqualContractAddress, _isEqualSmartContractAsset, _isMantaZkAsset, _isPureEvmChain, _isPureSubstrateChain, _parseAssetRefKey, fetchPatchData, randomizeProvider, updateLatestChainInfo } from '@subwallet/extension-base/services/chain-service/utils';
|
|
13
13
|
import AssetSettingStore from '@subwallet/extension-base/stores/AssetSetting';
|
|
14
|
-
import { addLazy, fetchStaticData, MODULE_SUPPORT } from '@subwallet/extension-base/utils';
|
|
14
|
+
import { addLazy, fetchStaticData, filterAssetsByChainAndType, MODULE_SUPPORT } from '@subwallet/extension-base/utils';
|
|
15
15
|
import { BehaviorSubject, Subject } from 'rxjs';
|
|
16
16
|
import Web3 from 'web3';
|
|
17
17
|
import { logger as createLogger } from '@polkadot/util/logger';
|
|
@@ -271,13 +271,7 @@ export class ChainService {
|
|
|
271
271
|
return destinationTokenInfo;
|
|
272
272
|
}
|
|
273
273
|
getAssetByChainAndType(chainSlug, assetTypes) {
|
|
274
|
-
|
|
275
|
-
Object.values(this.getAssetRegistry()).forEach(assetInfo => {
|
|
276
|
-
if (assetTypes.includes(assetInfo.assetType) && assetInfo.originChain === chainSlug) {
|
|
277
|
-
result[assetInfo.slug] = assetInfo;
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
return result;
|
|
274
|
+
return filterAssetsByChainAndType(this.getAssetRegistry(), chainSlug, assetTypes);
|
|
281
275
|
}
|
|
282
276
|
getSmartContractNfts() {
|
|
283
277
|
const result = [];
|
|
@@ -561,8 +555,6 @@ export class ChainService {
|
|
|
561
555
|
const chainState = chainStateMap[originChain];
|
|
562
556
|
if (!assetState) {
|
|
563
557
|
// If this asset not has asset setting, this token is not enabled before (not turned off before)
|
|
564
|
-
// @ts-ignore
|
|
565
|
-
// TODO: Merge issue detect balance to define manualTurnOff props
|
|
566
558
|
if (!chainState || !chainState.manualTurnOff) {
|
|
567
559
|
await this.updateAssetSetting(assetSlug, {
|
|
568
560
|
visible: true
|
|
@@ -5,7 +5,7 @@ import fetch from 'cross-fetch';
|
|
|
5
5
|
const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
|
|
6
6
|
const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
|
|
7
7
|
const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
|
|
8
|
-
const ChainListVersion = '0.2.
|
|
8
|
+
const ChainListVersion = '0.2.54';
|
|
9
9
|
export async function fetchPatchData(slug) {
|
|
10
10
|
try {
|
|
11
11
|
const fetchPromise = fetch(`${fetchDomain}/patch/${ChainListVersion}/${slug}`);
|
|
@@ -192,7 +192,7 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
|
|
|
192
192
|
const derivativeTokenInfo = this.state.getAssetBySlug(derivativeTokenSlug);
|
|
193
193
|
const inputTokenSlug = this.inputAsset;
|
|
194
194
|
const inputTokenInfo = this.state.getAssetBySlug(inputTokenSlug);
|
|
195
|
-
const inputTokenContract = getERC20Contract(
|
|
195
|
+
const inputTokenContract = getERC20Contract(_getContractAddressOfToken(inputTokenInfo), evmApi);
|
|
196
196
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
|
197
197
|
const allowanceCall = inputTokenContract.methods.allowance(params.address, _getContractAddressOfToken(derivativeTokenInfo));
|
|
198
198
|
const [allowance, gasPrice] = await Promise.all([
|
|
@@ -257,7 +257,7 @@ export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakin
|
|
|
257
257
|
const derivativeTokenInfo = this.state.getAssetBySlug(this.derivativeAssets[0]);
|
|
258
258
|
const derivativeTokenContractAddress = _getContractAddressOfToken(derivativeTokenInfo);
|
|
259
259
|
const evmApi = this.evmApi;
|
|
260
|
-
const inputTokenContract = getERC20Contract(
|
|
260
|
+
const inputTokenContract = getERC20Contract(_getContractAddressOfToken(inputTokenInfo), evmApi);
|
|
261
261
|
|
|
262
262
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
|
263
263
|
const approveCall = inputTokenContract.methods.approve(derivativeTokenContractAddress, MAX_INT); // TODO: need test
|
|
@@ -11,6 +11,7 @@ import NominatorMetadataStore from '@subwallet/extension-base/services/storage-s
|
|
|
11
11
|
import YieldPoolStore from '@subwallet/extension-base/services/storage-service/db-stores/YieldPoolStore';
|
|
12
12
|
import YieldPositionStore from '@subwallet/extension-base/services/storage-service/db-stores/YieldPositionStore';
|
|
13
13
|
import { reformatAddress } from '@subwallet/extension-base/utils';
|
|
14
|
+
import keyring from '@subwallet/ui-keyring';
|
|
14
15
|
import { exportDB } from 'dexie-export-import';
|
|
15
16
|
import { logger as createLogger } from '@polkadot/util';
|
|
16
17
|
export const DEXIE_BACKUP_TABLES = ['chain', 'asset', 'migrations', 'transactions', 'campaign'];
|
|
@@ -63,7 +64,12 @@ export default class DatabaseService {
|
|
|
63
64
|
|
|
64
65
|
// Balance
|
|
65
66
|
async getStoredBalance() {
|
|
66
|
-
|
|
67
|
+
const addresses = keyring.getPairs().map(({
|
|
68
|
+
address
|
|
69
|
+
}) => address);
|
|
70
|
+
|
|
71
|
+
// Filter not exist address
|
|
72
|
+
return this.stores.balance.table.filter(obj => addresses.includes(obj.address)).toArray();
|
|
67
73
|
}
|
|
68
74
|
async updateBalanceStore(item) {
|
|
69
75
|
if (item.state === APIItemState.READY) {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
|
|
1
2
|
import { APIItemState } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
|
+
import { _EvmApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
4
|
+
import { ApiPromise } from '@polkadot/api';
|
|
2
5
|
import { BN } from '@polkadot/util';
|
|
3
6
|
export interface TokenBalanceRaw {
|
|
4
7
|
reserved: BN;
|
|
@@ -37,3 +40,16 @@ export interface BalanceJson {
|
|
|
37
40
|
reset?: boolean;
|
|
38
41
|
details: BalanceMap;
|
|
39
42
|
}
|
|
43
|
+
export interface SubscribeBasePalletBalance {
|
|
44
|
+
addresses: string[];
|
|
45
|
+
assetMap: Record<string, _ChainAsset>;
|
|
46
|
+
chainInfo: _ChainInfo;
|
|
47
|
+
callback: (rs: BalanceItem[]) => void;
|
|
48
|
+
}
|
|
49
|
+
export interface SubscribeSubstratePalletBalance extends SubscribeBasePalletBalance {
|
|
50
|
+
substrateApi: ApiPromise;
|
|
51
|
+
includeNativeToken?: boolean;
|
|
52
|
+
}
|
|
53
|
+
export interface SubscribeEvmPalletBalance extends SubscribeBasePalletBalance {
|
|
54
|
+
evmApi: _EvmApi;
|
|
55
|
+
}
|
package/types/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
export * from "./balance.js";
|
|
4
|
+
export * from "./balance/index.js";
|
|
5
5
|
export * from "./buy.js";
|
|
6
6
|
export * from "./campaigns/index.js";
|
|
7
7
|
export * from "./fee/index.js";
|
package/utils/asset.d.ts
ADDED