@subwallet/extension-base 1.3.69-0 → 1.3.70-2
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 +11 -0
- package/background/KoniTypes.js +3 -0
- package/cjs/background/KoniTypes.js +3 -0
- package/cjs/koni/background/handlers/Extension.js +62 -0
- package/cjs/koni/background/handlers/State.js +5 -2
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/constants.js +15 -4
- package/cjs/services/chain-service/utils/index.js +13 -5
- package/cjs/services/event-service/index.js +1 -0
- package/cjs/services/open-gov/handler.js +563 -0
- package/cjs/services/open-gov/index.js +273 -0
- package/cjs/services/open-gov/interface.js +28 -0
- package/cjs/services/open-gov/utils.js +66 -0
- package/cjs/services/storage-service/DatabaseService.js +19 -1
- package/cjs/services/storage-service/databases/index.js +3 -0
- package/cjs/services/storage-service/db-stores/GovLockedInfoStore.js +35 -0
- package/cjs/services/transaction-service/helpers/index.js +6 -0
- package/cjs/services/transaction-service/index.js +43 -0
- package/cjs/utils/account/transform.js +5 -4
- package/koni/background/handlers/Extension.d.ts +4 -0
- package/koni/background/handlers/Extension.js +62 -0
- package/koni/background/handlers/State.d.ts +2 -0
- package/koni/background/handlers/State.js +5 -2
- package/package.json +30 -5
- package/packageInfo.js +1 -1
- package/services/chain-service/constants.d.ts +8 -0
- package/services/chain-service/constants.js +12 -2
- package/services/chain-service/utils/index.js +13 -5
- package/services/event-service/index.d.ts +1 -0
- package/services/event-service/index.js +1 -0
- package/services/event-service/types.d.ts +1 -0
- package/services/open-gov/handler.d.ts +27 -0
- package/services/open-gov/handler.js +547 -0
- package/services/open-gov/index.d.ts +45 -0
- package/services/open-gov/index.js +265 -0
- package/services/open-gov/interface.d.ts +141 -0
- package/services/open-gov/interface.js +21 -0
- package/services/open-gov/utils.d.ts +14 -0
- package/services/open-gov/utils.js +52 -0
- package/services/storage-service/DatabaseService.d.ts +7 -0
- package/services/storage-service/DatabaseService.js +19 -1
- package/services/storage-service/databases/index.d.ts +2 -0
- package/services/storage-service/databases/index.js +3 -0
- package/services/storage-service/db-stores/GovLockedInfoStore.d.ts +10 -0
- package/services/storage-service/db-stores/GovLockedInfoStore.js +27 -0
- package/services/transaction-service/helpers/index.js +6 -0
- package/services/transaction-service/index.js +43 -0
- package/utils/account/transform.js +5 -4
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
+
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
+
import { BasicTxErrorType } from '@subwallet/extension-base/types';
|
|
7
|
+
import { addLazy, createPromiseHandler, filterAddressByChainInfo } from '@subwallet/extension-base/utils';
|
|
8
|
+
import { BehaviorSubject } from 'rxjs';
|
|
9
|
+
import { ServiceStatus } from "../base/types.js";
|
|
10
|
+
import { _GOVERNANCE_CHAIN_GROUP } from "../chain-service/constants.js";
|
|
11
|
+
import { _isChainEnabled } from "../chain-service/utils/index.js";
|
|
12
|
+
import BaseOpenGovHandler from "./handler.js";
|
|
13
|
+
class OpenGovChainHandler extends BaseOpenGovHandler {
|
|
14
|
+
constructor(state, chain) {
|
|
15
|
+
super(state, chain);
|
|
16
|
+
this.slug = chain;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export default class OpenGovService {
|
|
20
|
+
handlers = {};
|
|
21
|
+
|
|
22
|
+
// subjects
|
|
23
|
+
govLockedInfoSubject = new BehaviorSubject({});
|
|
24
|
+
govLockedInfoListSubject = new BehaviorSubject([]);
|
|
25
|
+
govLockedInfoPersistQueue = [];
|
|
26
|
+
status = ServiceStatus.NOT_INITIALIZED;
|
|
27
|
+
startPromiseHandler = createPromiseHandler();
|
|
28
|
+
stopPromiseHandler = createPromiseHandler();
|
|
29
|
+
constructor(state) {
|
|
30
|
+
this.state = state;
|
|
31
|
+
this.eventService = state.eventService;
|
|
32
|
+
this.dbService = state.dbService;
|
|
33
|
+
}
|
|
34
|
+
async init() {
|
|
35
|
+
this.status = ServiceStatus.INITIALIZING;
|
|
36
|
+
this.eventService.emit('open-gov.ready', true);
|
|
37
|
+
await this.initHandlers();
|
|
38
|
+
await this.getGovLockedInfoFromDB();
|
|
39
|
+
this.status = ServiceStatus.INITIALIZED;
|
|
40
|
+
this.govLockedInfoListSubject.next(Object.values(this.govLockedInfoSubject.getValue()));
|
|
41
|
+
this.handleActions();
|
|
42
|
+
}
|
|
43
|
+
handleActions() {
|
|
44
|
+
this.eventService.onLazy((events, eventTypes) => {
|
|
45
|
+
let delayReload = false;
|
|
46
|
+
const removedAddresses = [];
|
|
47
|
+
const removeChains = [];
|
|
48
|
+
(async () => {
|
|
49
|
+
for (const event of events) {
|
|
50
|
+
if (event.type === 'account.remove') {
|
|
51
|
+
removedAddresses.push(event.data[0]);
|
|
52
|
+
}
|
|
53
|
+
if (event.type === 'account.add' || event.type === 'account.updateCurrent') {
|
|
54
|
+
delayReload = true;
|
|
55
|
+
}
|
|
56
|
+
if (event.type === 'chain.updateState') {
|
|
57
|
+
const chainKey = event.data[0];
|
|
58
|
+
const chainState = this.state.getChainStateByKey(chainKey);
|
|
59
|
+
if (chainState && !_isChainEnabled(chainState)) {
|
|
60
|
+
removeChains.push(chainKey);
|
|
61
|
+
}
|
|
62
|
+
delayReload = true;
|
|
63
|
+
}
|
|
64
|
+
if (event.type === 'transaction.done') {
|
|
65
|
+
const tx = event.data[0];
|
|
66
|
+
const govRelatedTypes = [ExtrinsicType.GOV_VOTE, ExtrinsicType.GOV_UNVOTE, ExtrinsicType.GOV_UNLOCK_VOTE];
|
|
67
|
+
if (govRelatedTypes.includes(tx.extrinsicType)) {
|
|
68
|
+
delayReload = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (removeChains.length || removedAddresses.length) {
|
|
73
|
+
await this.removeGovLockedInfos(removeChains, removedAddresses);
|
|
74
|
+
}
|
|
75
|
+
if (eventTypes.includes('account.updateCurrent') || eventTypes.includes('account.remove') || eventTypes.includes('chain.updateState') || delayReload) {
|
|
76
|
+
if (delayReload) {
|
|
77
|
+
this.delayReloadTimeout = setTimeout(() => {
|
|
78
|
+
this.resetGovLockedInfo().then(() => this.runSubscribeGovLockedInfo()).catch(console.error);
|
|
79
|
+
}, 3000);
|
|
80
|
+
} else {
|
|
81
|
+
this.delayReloadTimeout && clearTimeout(this.delayReloadTimeout);
|
|
82
|
+
this.delayReloadTimeout = undefined;
|
|
83
|
+
await this.resetGovLockedInfo();
|
|
84
|
+
await this.runSubscribeGovLockedInfo();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
})().catch(console.error);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
async removeGovLockedInfos(chains, addresses) {
|
|
91
|
+
const current = this.govLockedInfoSubject.getValue();
|
|
92
|
+
const removeKeys = [];
|
|
93
|
+
if (chains && chains.length > 0) {
|
|
94
|
+
for (const [key, value] of Object.entries(current)) {
|
|
95
|
+
if (chains.includes(value.chain)) {
|
|
96
|
+
removeKeys.push(key);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (addresses && addresses.length > 0) {
|
|
101
|
+
for (const [key, value] of Object.entries(current)) {
|
|
102
|
+
if (addresses.includes(value.address)) {
|
|
103
|
+
removeKeys.push(key);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (const key of removeKeys) {
|
|
108
|
+
delete current[key];
|
|
109
|
+
}
|
|
110
|
+
this.govLockedInfoSubject.next(current);
|
|
111
|
+
this.govLockedInfoListSubject.next(Object.values(current));
|
|
112
|
+
if (addresses && addresses.length > 0) {
|
|
113
|
+
await this.dbService.removeGovLockedInfosByAddresses(addresses);
|
|
114
|
+
}
|
|
115
|
+
if (chains && chains.length > 0) {
|
|
116
|
+
await this.dbService.removeGovLockedInfosByChains(chains);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async initHandlers() {
|
|
120
|
+
await this.eventService.waitChainReady;
|
|
121
|
+
const chains = [];
|
|
122
|
+
const supportedSlugs = Object.values(_GOVERNANCE_CHAIN_GROUP).flat();
|
|
123
|
+
for (const chain of Object.values(this.state.getChainInfoMap())) {
|
|
124
|
+
if (chain.chainStatus === 'ACTIVE' && supportedSlugs.includes(chain.slug)) {
|
|
125
|
+
chains.push(chain.slug);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (const chain of chains) {
|
|
129
|
+
this.handlers[chain] = new OpenGovChainHandler(this.state, chain);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async handleVote(request) {
|
|
133
|
+
const handler = this.handlers[request.chain];
|
|
134
|
+
if (!handler) {
|
|
135
|
+
return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
|
|
136
|
+
}
|
|
137
|
+
return handler.handleVote(request);
|
|
138
|
+
}
|
|
139
|
+
async handleRemoveVote(request) {
|
|
140
|
+
const handler = this.handlers[request.chain];
|
|
141
|
+
if (!handler) {
|
|
142
|
+
return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
|
|
143
|
+
}
|
|
144
|
+
return handler.handleRemoveVote(request);
|
|
145
|
+
}
|
|
146
|
+
async handleUnlockVote(request) {
|
|
147
|
+
const handler = this.handlers[request.chain];
|
|
148
|
+
if (!handler) {
|
|
149
|
+
return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
|
|
150
|
+
}
|
|
151
|
+
return handler.handleUnlockVote(request);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* Gov Locked Info */
|
|
155
|
+
|
|
156
|
+
async runSubscribeGovLockedInfo() {
|
|
157
|
+
await this.eventService.waitKeyringReady;
|
|
158
|
+
this.runUnsubscribeGovLockedInfo();
|
|
159
|
+
const addresses = this.state.keyringService.context.getDecodedAddresses();
|
|
160
|
+
this.subscribeGovLockedInfos(addresses, data => {
|
|
161
|
+
this.updateGovLockedInfo(data);
|
|
162
|
+
}).then(rs => {
|
|
163
|
+
this.govLockedInfoUnsub = rs;
|
|
164
|
+
}).catch(console.error);
|
|
165
|
+
}
|
|
166
|
+
runUnsubscribeGovLockedInfo() {
|
|
167
|
+
var _this$govLockedInfoUn;
|
|
168
|
+
(_this$govLockedInfoUn = this.govLockedInfoUnsub) === null || _this$govLockedInfoUn === void 0 ? void 0 : _this$govLockedInfoUn.call(this);
|
|
169
|
+
this.govLockedInfoUnsub = undefined;
|
|
170
|
+
this.govLockedInfoPersistQueue = [];
|
|
171
|
+
}
|
|
172
|
+
async subscribeGovLockedInfos(addresses, cb) {
|
|
173
|
+
let cancel = false;
|
|
174
|
+
await this.eventService.waitChainReady;
|
|
175
|
+
const activeChains = this.state.activeChainSlugs;
|
|
176
|
+
const unsubList = [];
|
|
177
|
+
for (const handler of Object.values(this.handlers)) {
|
|
178
|
+
if (activeChains.includes(handler.chain)) {
|
|
179
|
+
const [useAddresses] = filterAddressByChainInfo(addresses, handler.chainInfo);
|
|
180
|
+
handler.subscribeGovLockedInfo(useAddresses, cb).then(unsub => {
|
|
181
|
+
if (cancel) {
|
|
182
|
+
unsub();
|
|
183
|
+
} else {
|
|
184
|
+
unsubList.push(unsub);
|
|
185
|
+
}
|
|
186
|
+
}).catch(console.error);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return () => {
|
|
190
|
+
cancel = true;
|
|
191
|
+
unsubList.forEach(unsub => unsub === null || unsub === void 0 ? void 0 : unsub());
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
updateGovLockedInfo(data) {
|
|
195
|
+
this.govLockedInfoPersistQueue.push(data);
|
|
196
|
+
addLazy('persistGovLockedInfo', () => {
|
|
197
|
+
const govInfo = this.govLockedInfoSubject.getValue();
|
|
198
|
+
const queue = [...this.govLockedInfoPersistQueue];
|
|
199
|
+
this.govLockedInfoPersistQueue = [];
|
|
200
|
+
|
|
201
|
+
// Update info in memory
|
|
202
|
+
queue.forEach(item => {
|
|
203
|
+
const key = `${item.chain}---${item.address}`;
|
|
204
|
+
govInfo[key] = item;
|
|
205
|
+
});
|
|
206
|
+
this.govLockedInfoSubject.next(govInfo);
|
|
207
|
+
this.govLockedInfoListSubject.next(Object.values(govInfo));
|
|
208
|
+
|
|
209
|
+
// Persist data
|
|
210
|
+
this.dbService.updateGovLockedInfos(queue).catch(console.warn);
|
|
211
|
+
}, 300, 900);
|
|
212
|
+
}
|
|
213
|
+
async resetGovLockedInfo() {
|
|
214
|
+
this.govLockedInfoPersistQueue = [];
|
|
215
|
+
await this.dbService.stores.govLockedInfo.clear();
|
|
216
|
+
}
|
|
217
|
+
async getGovLockedInfoFromDB() {
|
|
218
|
+
await this.eventService.waitChainReady;
|
|
219
|
+
await this.eventService.waitKeyringReady;
|
|
220
|
+
const addresses = this.state.keyringService.context.getDecodedAddresses();
|
|
221
|
+
const existedInfos = await this.dbService.getGovLockedInfos(addresses, this.state.activeChainSlugs);
|
|
222
|
+
const govInfo = this.govLockedInfoSubject.getValue();
|
|
223
|
+
existedInfos.forEach(item => {
|
|
224
|
+
govInfo[`${item.chain}---${item.address}`] = item;
|
|
225
|
+
});
|
|
226
|
+
this.govLockedInfoSubject.next(govInfo);
|
|
227
|
+
this.govLockedInfoListSubject.next(Object.values(govInfo));
|
|
228
|
+
}
|
|
229
|
+
subscribeGovLockedInfoSubject() {
|
|
230
|
+
return this.govLockedInfoListSubject;
|
|
231
|
+
}
|
|
232
|
+
async getGovLockedInfoInfo() {
|
|
233
|
+
await this.eventService.waitEarningReady;
|
|
234
|
+
return Promise.resolve(this.govLockedInfoListSubject.getValue());
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* --------- Start/Stop ---------- */
|
|
238
|
+
async start() {
|
|
239
|
+
if (this.status === ServiceStatus.STARTING || this.status === ServiceStatus.STARTED) {
|
|
240
|
+
return this.waitForStarted();
|
|
241
|
+
}
|
|
242
|
+
this.status = ServiceStatus.STARTING;
|
|
243
|
+
this.startPromiseHandler.resolve();
|
|
244
|
+
this.stopPromiseHandler = createPromiseHandler();
|
|
245
|
+
this.status = ServiceStatus.STARTED;
|
|
246
|
+
}
|
|
247
|
+
async stop() {
|
|
248
|
+
if (this.status === ServiceStatus.STOPPING || this.status === ServiceStatus.STOPPED) {
|
|
249
|
+
return this.waitForStopped();
|
|
250
|
+
}
|
|
251
|
+
this.status = ServiceStatus.STOPPING;
|
|
252
|
+
this.runUnsubscribeGovLockedInfo();
|
|
253
|
+
this.stopPromiseHandler.resolve();
|
|
254
|
+
this.startPromiseHandler = createPromiseHandler();
|
|
255
|
+
this.status = ServiceStatus.STOPPED;
|
|
256
|
+
}
|
|
257
|
+
waitForStarted() {
|
|
258
|
+
return this.startPromiseHandler.promise;
|
|
259
|
+
}
|
|
260
|
+
waitForStopped() {
|
|
261
|
+
return this.stopPromiseHandler.promise;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Gov Locked Info */
|
|
265
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
export declare enum GovVoteType {
|
|
2
|
+
AYE = "aye",
|
|
3
|
+
NAY = "nay",
|
|
4
|
+
SPLIT = "split",
|
|
5
|
+
ABSTAIN = "abstain"
|
|
6
|
+
}
|
|
7
|
+
interface BaseVoteRequest {
|
|
8
|
+
chain: string;
|
|
9
|
+
address: string;
|
|
10
|
+
referendumIndex: string;
|
|
11
|
+
trackId: number;
|
|
12
|
+
conviction: number;
|
|
13
|
+
}
|
|
14
|
+
export interface StandardVoteRequest extends BaseVoteRequest {
|
|
15
|
+
type: GovVoteType.AYE | GovVoteType.NAY;
|
|
16
|
+
amount: string;
|
|
17
|
+
}
|
|
18
|
+
export interface SplitVoteRequest extends BaseVoteRequest {
|
|
19
|
+
type: GovVoteType.SPLIT;
|
|
20
|
+
ayeAmount: string;
|
|
21
|
+
nayAmount: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SplitAbstainVoteRequest extends BaseVoteRequest {
|
|
24
|
+
type: GovVoteType.ABSTAIN;
|
|
25
|
+
abstainAmount: string;
|
|
26
|
+
ayeAmount: string;
|
|
27
|
+
nayAmount: string;
|
|
28
|
+
}
|
|
29
|
+
export declare type GovVoteRequest = StandardVoteRequest | SplitVoteRequest | SplitAbstainVoteRequest;
|
|
30
|
+
export interface RemoveVoteRequest {
|
|
31
|
+
address: string;
|
|
32
|
+
chain: string;
|
|
33
|
+
trackId: number;
|
|
34
|
+
referendumIndex: string;
|
|
35
|
+
amount?: string;
|
|
36
|
+
ayeAmount?: string;
|
|
37
|
+
nayAmount?: string;
|
|
38
|
+
abstainAmount?: string;
|
|
39
|
+
totalAmount: string;
|
|
40
|
+
type?: GovVoteType;
|
|
41
|
+
}
|
|
42
|
+
export declare enum Conviction {
|
|
43
|
+
None = "None",
|
|
44
|
+
Locked1x = "Locked1x",
|
|
45
|
+
Locked2x = "Locked2x",
|
|
46
|
+
Locked3x = "Locked3x",
|
|
47
|
+
Locked4x = "Locked4x",
|
|
48
|
+
Locked5x = "Locked5x",
|
|
49
|
+
Locked6x = "Locked6x"
|
|
50
|
+
}
|
|
51
|
+
export interface StandardVote {
|
|
52
|
+
standard: {
|
|
53
|
+
vote: {
|
|
54
|
+
conviction: Conviction;
|
|
55
|
+
aye: boolean;
|
|
56
|
+
};
|
|
57
|
+
balance: string;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export interface SplitVote {
|
|
61
|
+
split: {
|
|
62
|
+
aye: string;
|
|
63
|
+
nay: string;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export interface SplitAbstainVote {
|
|
67
|
+
splitAbstain: {
|
|
68
|
+
aye: string;
|
|
69
|
+
nay: string;
|
|
70
|
+
abstain: string;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export declare type Vote = StandardVote | SplitVote | SplitAbstainVote;
|
|
74
|
+
export interface Casting {
|
|
75
|
+
prior: [string, string];
|
|
76
|
+
votes: [string, Vote][];
|
|
77
|
+
delegations: {
|
|
78
|
+
votes: string;
|
|
79
|
+
capital: string;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export interface Delegating {
|
|
83
|
+
prior: [string, string];
|
|
84
|
+
target: string;
|
|
85
|
+
balance: string;
|
|
86
|
+
conviction: Conviction;
|
|
87
|
+
}
|
|
88
|
+
export interface VotingFor {
|
|
89
|
+
casting?: Casting;
|
|
90
|
+
delegating?: Delegating;
|
|
91
|
+
}
|
|
92
|
+
export interface UnlockingReferendaData {
|
|
93
|
+
id?: string;
|
|
94
|
+
balance: string;
|
|
95
|
+
timestamp: number;
|
|
96
|
+
}
|
|
97
|
+
export interface GovVotingInfo {
|
|
98
|
+
chain: string;
|
|
99
|
+
address: string;
|
|
100
|
+
summary: {
|
|
101
|
+
delegated: string;
|
|
102
|
+
voted: string;
|
|
103
|
+
totalLocked: string;
|
|
104
|
+
unlocking: {
|
|
105
|
+
unlockingReferenda: UnlockingReferendaData[];
|
|
106
|
+
};
|
|
107
|
+
unlockable: {
|
|
108
|
+
balance: string;
|
|
109
|
+
trackIds: number[];
|
|
110
|
+
unlockableReferenda: string[];
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
tracks: GovTrackVoting[];
|
|
114
|
+
}
|
|
115
|
+
export interface GovTrackVoting {
|
|
116
|
+
trackId: number;
|
|
117
|
+
votes?: GovVoteDetail[];
|
|
118
|
+
delegation?: GovDelegationDetail;
|
|
119
|
+
}
|
|
120
|
+
export interface GovVoteDetail {
|
|
121
|
+
referendumIndex: string;
|
|
122
|
+
type: GovVoteType;
|
|
123
|
+
conviction: Conviction;
|
|
124
|
+
amount?: string;
|
|
125
|
+
ayeAmount?: string;
|
|
126
|
+
nayAmount?: string;
|
|
127
|
+
abstainAmount?: string;
|
|
128
|
+
}
|
|
129
|
+
export interface GovDelegationDetail {
|
|
130
|
+
balance: string;
|
|
131
|
+
target: string;
|
|
132
|
+
conviction: Conviction;
|
|
133
|
+
}
|
|
134
|
+
export interface UnlockVoteRequest {
|
|
135
|
+
address: string;
|
|
136
|
+
chain: string;
|
|
137
|
+
trackIds?: number[];
|
|
138
|
+
referendumIds?: string[];
|
|
139
|
+
amount: string;
|
|
140
|
+
}
|
|
141
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
export let GovVoteType;
|
|
5
|
+
(function (GovVoteType) {
|
|
6
|
+
GovVoteType["AYE"] = "aye";
|
|
7
|
+
GovVoteType["NAY"] = "nay";
|
|
8
|
+
GovVoteType["SPLIT"] = "split";
|
|
9
|
+
GovVoteType["ABSTAIN"] = "abstain";
|
|
10
|
+
})(GovVoteType || (GovVoteType = {}));
|
|
11
|
+
/* Lock inteface */
|
|
12
|
+
export let Conviction;
|
|
13
|
+
(function (Conviction) {
|
|
14
|
+
Conviction["None"] = "None";
|
|
15
|
+
Conviction["Locked1x"] = "Locked1x";
|
|
16
|
+
Conviction["Locked2x"] = "Locked2x";
|
|
17
|
+
Conviction["Locked3x"] = "Locked3x";
|
|
18
|
+
Conviction["Locked4x"] = "Locked4x";
|
|
19
|
+
Conviction["Locked5x"] = "Locked5x";
|
|
20
|
+
Conviction["Locked6x"] = "Locked6x";
|
|
21
|
+
})(Conviction || (Conviction = {}));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Conviction } from './interface';
|
|
2
|
+
export declare const numberToConviction: Record<number, Conviction>;
|
|
3
|
+
export declare const defaultConvictionDays: Record<Conviction, number>;
|
|
4
|
+
export declare const specialChainLockConfig: {
|
|
5
|
+
chains: string[];
|
|
6
|
+
daysMap: Record<Conviction, number>;
|
|
7
|
+
}[];
|
|
8
|
+
export declare function getConvictionDays(chain: string, conviction: Conviction): number;
|
|
9
|
+
export declare function getGovConvictionOptions(chain: string): {
|
|
10
|
+
value: number;
|
|
11
|
+
label: string;
|
|
12
|
+
description: string;
|
|
13
|
+
}[];
|
|
14
|
+
export declare const MIGRATED_CHAINS: string[];
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { Conviction } from "./interface.js";
|
|
5
|
+
export const numberToConviction = {
|
|
6
|
+
0: Conviction.None,
|
|
7
|
+
1: Conviction.Locked1x,
|
|
8
|
+
2: Conviction.Locked2x,
|
|
9
|
+
3: Conviction.Locked3x,
|
|
10
|
+
4: Conviction.Locked4x,
|
|
11
|
+
5: Conviction.Locked5x,
|
|
12
|
+
6: Conviction.Locked6x
|
|
13
|
+
};
|
|
14
|
+
export const defaultConvictionDays = {
|
|
15
|
+
[Conviction.None]: 0,
|
|
16
|
+
[Conviction.Locked1x]: 7,
|
|
17
|
+
[Conviction.Locked2x]: 14,
|
|
18
|
+
[Conviction.Locked3x]: 28,
|
|
19
|
+
[Conviction.Locked4x]: 56,
|
|
20
|
+
[Conviction.Locked5x]: 112,
|
|
21
|
+
[Conviction.Locked6x]: 224
|
|
22
|
+
};
|
|
23
|
+
export const specialChainLockConfig = [{
|
|
24
|
+
chains: ['bifrost_dot', 'bifrost'],
|
|
25
|
+
daysMap: {
|
|
26
|
+
[Conviction.None]: 0,
|
|
27
|
+
[Conviction.Locked1x]: 1,
|
|
28
|
+
[Conviction.Locked2x]: 2,
|
|
29
|
+
[Conviction.Locked3x]: 4,
|
|
30
|
+
[Conviction.Locked4x]: 8,
|
|
31
|
+
[Conviction.Locked5x]: 16,
|
|
32
|
+
[Conviction.Locked6x]: 32
|
|
33
|
+
}
|
|
34
|
+
}];
|
|
35
|
+
export function getConvictionDays(chain, conviction) {
|
|
36
|
+
var _group$daysMap, _daysMap$conviction;
|
|
37
|
+
const lowerChain = chain.toLowerCase();
|
|
38
|
+
const group = specialChainLockConfig.find(g => g.chains.includes(lowerChain));
|
|
39
|
+
const daysMap = (_group$daysMap = group === null || group === void 0 ? void 0 : group.daysMap) !== null && _group$daysMap !== void 0 ? _group$daysMap : defaultConvictionDays;
|
|
40
|
+
return (_daysMap$conviction = daysMap[conviction]) !== null && _daysMap$conviction !== void 0 ? _daysMap$conviction : 0;
|
|
41
|
+
}
|
|
42
|
+
export function getGovConvictionOptions(chain) {
|
|
43
|
+
return Object.entries(numberToConviction).map(([value, conviction]) => {
|
|
44
|
+
const days = getConvictionDays(chain, conviction);
|
|
45
|
+
return {
|
|
46
|
+
value: Number(value),
|
|
47
|
+
label: value === '0' ? '0.1x' : `${value}x`,
|
|
48
|
+
description: days === 0 ? 'No lockup' : `~${days}d`
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export const MIGRATED_CHAINS = ['statemine', 'statemint', 'paseo_assethub', 'westend_assethub'];
|
|
@@ -16,6 +16,8 @@ import { BalanceItem, ProcessTransactionData, YieldPoolInfo, YieldPoolType, Yiel
|
|
|
16
16
|
import { GetNotificationParams, RequestSwitchStatusParams } from '@subwallet/extension-base/types/notification';
|
|
17
17
|
import { Subscription } from 'dexie';
|
|
18
18
|
import { DexieExportJsonStructure } from 'dexie-export-import';
|
|
19
|
+
import { GovVotingInfo } from '../open-gov/interface';
|
|
20
|
+
import GovLockedInfoStore from './db-stores/GovLockedInfoStore';
|
|
19
21
|
export declare const DEXIE_BACKUP_TABLES: string[];
|
|
20
22
|
export default class DatabaseService {
|
|
21
23
|
private eventService;
|
|
@@ -41,6 +43,7 @@ export default class DatabaseService {
|
|
|
41
43
|
campaign: CampaignStore;
|
|
42
44
|
inappNotification: InappNotificationStore;
|
|
43
45
|
processTransactions: ProcessTransactionStore;
|
|
46
|
+
govLockedInfo: GovLockedInfoStore;
|
|
44
47
|
};
|
|
45
48
|
private logger;
|
|
46
49
|
private nftSubscription;
|
|
@@ -135,6 +138,10 @@ export default class DatabaseService {
|
|
|
135
138
|
switchReadStatus(params: RequestSwitchStatusParams): import("dexie").PromiseExtended<number>;
|
|
136
139
|
removeAccountNotifications(proxyId: string): import("dexie").PromiseExtended<number>;
|
|
137
140
|
updateNotificationProxyId(proxyIds: string[], newProxyId: string, newName: string): void;
|
|
141
|
+
getGovLockedInfos(addresses: string[], chains: string[]): Promise<GovVotingInfo[]>;
|
|
142
|
+
updateGovLockedInfos(infos: GovVotingInfo[]): Promise<unknown>;
|
|
143
|
+
removeGovLockedInfosByAddresses(addresses: string[]): import("dexie").PromiseExtended<number>;
|
|
144
|
+
removeGovLockedInfosByChains(chains: string[]): import("dexie").PromiseExtended<number>;
|
|
138
145
|
exportDB(): Promise<string>;
|
|
139
146
|
importDB(data: string): Promise<boolean>;
|
|
140
147
|
getExportJson(): Promise<DexieExportJsonStructure>;
|
|
@@ -17,6 +17,7 @@ import keyring from '@subwallet/ui-keyring';
|
|
|
17
17
|
import BigN from 'bignumber.js';
|
|
18
18
|
import { exportDB } from 'dexie-export-import';
|
|
19
19
|
import { logger as createLogger } from '@polkadot/util';
|
|
20
|
+
import GovLockedInfoStore from "./db-stores/GovLockedInfoStore.js";
|
|
20
21
|
export const DEXIE_BACKUP_TABLES = ['chain', 'asset', 'migrations', 'transactions', 'campaign'];
|
|
21
22
|
export default class DatabaseService {
|
|
22
23
|
// TODO: might remove this
|
|
@@ -54,7 +55,9 @@ export default class DatabaseService {
|
|
|
54
55
|
// inapp notification
|
|
55
56
|
inappNotification: new InappNotificationStore(this._db.inappNotification),
|
|
56
57
|
// process transaction
|
|
57
|
-
processTransactions: new ProcessTransactionStore(this._db.processTransactions)
|
|
58
|
+
processTransactions: new ProcessTransactionStore(this._db.processTransactions),
|
|
59
|
+
// gov
|
|
60
|
+
govLockedInfo: new GovLockedInfoStore(this._db.govLockedInfos)
|
|
58
61
|
};
|
|
59
62
|
}
|
|
60
63
|
async updatePriceStore(priceData) {
|
|
@@ -598,6 +601,21 @@ export default class DatabaseService {
|
|
|
598
601
|
updateNotificationProxyId(proxyIds, newProxyId, newName) {
|
|
599
602
|
return this.stores.inappNotification.updateNotificationProxyId(proxyIds, newProxyId, newName);
|
|
600
603
|
}
|
|
604
|
+
|
|
605
|
+
/* Gov */
|
|
606
|
+
|
|
607
|
+
async getGovLockedInfos(addresses, chains) {
|
|
608
|
+
return this.stores.govLockedInfo.getByAddressesAndChains(addresses, chains);
|
|
609
|
+
}
|
|
610
|
+
async updateGovLockedInfos(infos) {
|
|
611
|
+
return this.stores.govLockedInfo.upsertMany(infos);
|
|
612
|
+
}
|
|
613
|
+
removeGovLockedInfosByAddresses(addresses) {
|
|
614
|
+
return this.stores.govLockedInfo.removeByAddresses(addresses);
|
|
615
|
+
}
|
|
616
|
+
removeGovLockedInfosByChains(chains) {
|
|
617
|
+
return this.stores.govLockedInfo.removeByChains(chains);
|
|
618
|
+
}
|
|
601
619
|
async exportDB() {
|
|
602
620
|
const blob = await exportDB(this._db, {
|
|
603
621
|
filter: (table, value, key) => {
|
|
@@ -3,6 +3,7 @@ import { CampaignData, ChainStakingMetadata, CrowdloanItem, MetadataItem, Metada
|
|
|
3
3
|
import { _NotificationInfo } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
|
|
4
4
|
import { BalanceItem, ProcessTransactionData, YieldPoolInfo, YieldPositionInfo } from '@subwallet/extension-base/types';
|
|
5
5
|
import Dexie, { Table } from 'dexie';
|
|
6
|
+
import { GovVotingInfo } from '../../open-gov/interface';
|
|
6
7
|
export declare const DEFAULT_DATABASE = "SubWalletDB_v2";
|
|
7
8
|
export interface DefaultChainDoc {
|
|
8
9
|
chain: string;
|
|
@@ -66,6 +67,7 @@ export default class KoniDatabase extends Dexie {
|
|
|
66
67
|
inappNotification: Table<_NotificationInfo, object>;
|
|
67
68
|
processTransactions: Table<ProcessTransactionData, object>;
|
|
68
69
|
private schemaVersion;
|
|
70
|
+
govLockedInfos: Table<GovVotingInfo, object>;
|
|
69
71
|
constructor(name?: string, schemaVersion?: number);
|
|
70
72
|
private conditionalVersion;
|
|
71
73
|
static instance: KoniDatabase;
|
|
@@ -49,6 +49,9 @@ export default class KoniDatabase extends Dexie {
|
|
|
49
49
|
this.conditionalVersion(9, {
|
|
50
50
|
processTransactions: 'id, address'
|
|
51
51
|
});
|
|
52
|
+
this.conditionalVersion(10, {
|
|
53
|
+
govLockedInfos: '[chain+address], chain, address'
|
|
54
|
+
});
|
|
52
55
|
}
|
|
53
56
|
conditionalVersion(version, schema, upgrade) {
|
|
54
57
|
if (this.schemaVersion != null && this.schemaVersion < version) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GovVotingInfo } from '../../open-gov/interface';
|
|
2
|
+
import BaseStore from './BaseStore';
|
|
3
|
+
export default class GovLockedInfoStore extends BaseStore<GovVotingInfo> {
|
|
4
|
+
getAll(): Promise<GovVotingInfo[]>;
|
|
5
|
+
getByAddresses(addresses: string[]): Promise<GovVotingInfo[]>;
|
|
6
|
+
getByAddressesAndChains(addresses: string[], chains: string[]): Promise<GovVotingInfo[]>;
|
|
7
|
+
upsertMany(infos: GovVotingInfo[]): Promise<unknown>;
|
|
8
|
+
removeByAddresses(addresses: string[]): import("dexie").PromiseExtended<number>;
|
|
9
|
+
removeByChains(chains: string[]): import("dexie").PromiseExtended<number>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import BaseStore from "./BaseStore.js";
|
|
5
|
+
export default class GovLockedInfoStore extends BaseStore {
|
|
6
|
+
async getAll() {
|
|
7
|
+
return this.table.toArray();
|
|
8
|
+
}
|
|
9
|
+
async getByAddresses(addresses) {
|
|
10
|
+
if (addresses.length === 0) {
|
|
11
|
+
return this.getAll();
|
|
12
|
+
}
|
|
13
|
+
return this.table.where('address').anyOfIgnoreCase(addresses).toArray();
|
|
14
|
+
}
|
|
15
|
+
async getByAddressesAndChains(addresses, chains) {
|
|
16
|
+
return this.table.where('address').anyOfIgnoreCase(addresses).filter(item => chains.includes(item.chain)).toArray();
|
|
17
|
+
}
|
|
18
|
+
async upsertMany(infos) {
|
|
19
|
+
return this.table.bulkPut(infos);
|
|
20
|
+
}
|
|
21
|
+
removeByAddresses(addresses) {
|
|
22
|
+
return this.table.where('address').anyOf(addresses).delete();
|
|
23
|
+
}
|
|
24
|
+
removeByChains(chains) {
|
|
25
|
+
return this.table.where('chain').anyOf(chains).delete();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -61,6 +61,12 @@ const typeName = type => {
|
|
|
61
61
|
return 'Withdraw pool';
|
|
62
62
|
case ExtrinsicType.JOIN_YIELD_POOL:
|
|
63
63
|
return 'Start earning';
|
|
64
|
+
case ExtrinsicType.GOV_VOTE:
|
|
65
|
+
return 'Vote';
|
|
66
|
+
case ExtrinsicType.GOV_UNVOTE:
|
|
67
|
+
return 'Remove vote';
|
|
68
|
+
case ExtrinsicType.GOV_UNLOCK_VOTE:
|
|
69
|
+
return 'Unlock votes';
|
|
64
70
|
case ExtrinsicType.CHANGE_EARNING_VALIDATOR:
|
|
65
71
|
return 'Change validator';
|
|
66
72
|
case ExtrinsicType.UNKNOWN:
|