@subwallet/extension-base 1.3.73-0 → 1.3.74-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/background/KoniTypes.d.ts +42 -5
- package/background/KoniTypes.js +14 -1
- package/cjs/background/KoniTypes.js +16 -2
- package/cjs/core/logic-validation/transfer.js +35 -57
- package/cjs/koni/background/handlers/Extension.js +599 -144
- package/cjs/koni/background/handlers/State.js +5 -2
- package/cjs/koni/background/handlers/Tabs.js +3 -2
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +0 -2
- package/cjs/services/chain-service/handler/SubstrateApi.js +6 -1
- package/cjs/services/chain-service/index.js +1 -0
- package/cjs/services/chain-service/utils/index.js +4 -0
- package/cjs/services/event-service/index.js +1 -0
- package/cjs/services/fee-service/utils/index.js +4 -4
- package/cjs/services/inapp-notification-service/consts.js +4 -2
- package/cjs/services/inapp-notification-service/index.js +51 -6
- package/cjs/services/inapp-notification-service/interfaces.js +2 -0
- package/cjs/services/inapp-notification-service/utils/common.js +4 -0
- package/cjs/services/keyring-service/context/account-context.js +44 -0
- package/cjs/services/keyring-service/context/handlers/Multisig.js +186 -0
- package/cjs/services/keyring-service/context/state.js +12 -0
- package/cjs/services/multisig-service/index.js +627 -0
- package/cjs/services/multisig-service/utils.js +242 -0
- package/cjs/services/request-service/handler/SubstrateRequestHandler.js +25 -0
- package/cjs/services/request-service/index.js +5 -1
- package/cjs/services/storage-service/DatabaseService.js +5 -2
- package/cjs/services/storage-service/db-stores/InappNotification.js +20 -2
- package/cjs/services/substrate-proxy-service/index.js +22 -7
- package/cjs/services/transaction-service/helpers/index.js +8 -0
- package/cjs/services/transaction-service/index.js +348 -147
- package/cjs/services/transaction-service/types.js +18 -1
- package/cjs/types/account/info/keyring.js +5 -0
- package/cjs/types/account/info/proxy.js +1 -0
- package/cjs/types/multisig/index.js +14 -0
- package/cjs/types/transaction/error.js +9 -2
- package/cjs/utils/account/transform.js +28 -4
- package/cjs/utils/logger/Logger.js +294 -0
- package/cjs/utils/logger/index.js +42 -0
- package/cjs/utils/logger/types.js +1 -0
- package/core/logic-validation/transfer.d.ts +2 -2
- package/core/logic-validation/transfer.js +10 -32
- package/koni/background/handlers/Extension.d.ts +7 -0
- package/koni/background/handlers/Extension.js +498 -43
- package/koni/background/handlers/State.d.ts +2 -0
- package/koni/background/handlers/State.js +5 -2
- package/koni/background/handlers/Tabs.js +3 -2
- package/package.json +42 -6
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/subscribe/substrate/index.js +0 -2
- package/services/chain-service/handler/SubstrateApi.js +7 -2
- package/services/chain-service/index.js +1 -0
- package/services/chain-service/types.d.ts +1 -1
- package/services/chain-service/utils/index.js +4 -0
- 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/fee-service/utils/index.js +4 -4
- package/services/inapp-notification-service/consts.d.ts +3 -1
- package/services/inapp-notification-service/consts.js +5 -3
- package/services/inapp-notification-service/index.d.ts +3 -2
- package/services/inapp-notification-service/index.js +51 -6
- package/services/inapp-notification-service/interfaces.d.ts +18 -2
- package/services/inapp-notification-service/interfaces.js +2 -0
- package/services/inapp-notification-service/utils/common.d.ts +1 -0
- package/services/inapp-notification-service/utils/common.js +3 -0
- package/services/keyring-service/context/account-context.d.ts +9 -1
- package/services/keyring-service/context/account-context.js +44 -0
- package/services/keyring-service/context/handlers/Multisig.d.ts +18 -0
- package/services/keyring-service/context/handlers/Multisig.js +180 -0
- package/services/keyring-service/context/state.d.ts +2 -0
- package/services/keyring-service/context/state.js +12 -0
- package/services/multisig-service/index.d.ts +245 -0
- package/services/multisig-service/index.js +620 -0
- package/services/multisig-service/utils.d.ts +95 -0
- package/services/multisig-service/utils.js +227 -0
- package/services/request-service/handler/SubstrateRequestHandler.d.ts +1 -0
- package/services/request-service/handler/SubstrateRequestHandler.js +25 -0
- package/services/request-service/index.d.ts +2 -1
- package/services/request-service/index.js +5 -1
- package/services/storage-service/DatabaseService.d.ts +3 -2
- package/services/storage-service/DatabaseService.js +5 -2
- package/services/storage-service/db-stores/InappNotification.d.ts +3 -2
- package/services/storage-service/db-stores/InappNotification.js +20 -2
- package/services/substrate-proxy-service/index.d.ts +4 -1
- package/services/substrate-proxy-service/index.js +22 -8
- package/services/transaction-service/helpers/index.js +8 -0
- package/services/transaction-service/index.d.ts +31 -0
- package/services/transaction-service/index.js +270 -69
- package/services/transaction-service/types.d.ts +28 -3
- package/services/transaction-service/types.js +12 -1
- package/types/account/info/keyring.d.ts +14 -1
- package/types/account/info/keyring.js +6 -0
- package/types/account/info/proxy.d.ts +1 -0
- package/types/account/info/proxy.js +1 -0
- package/types/multisig/index.d.ts +76 -0
- package/types/multisig/index.js +8 -0
- package/types/notification/index.d.ts +8 -0
- package/types/substrateProxyAccount/index.d.ts +26 -1
- package/types/transaction/error.d.ts +6 -1
- package/types/transaction/error.js +7 -1
- package/types/transaction/request.d.ts +0 -1
- package/utils/account/transform.js +28 -4
- package/utils/logger/Logger.d.ts +31 -0
- package/utils/logger/Logger.js +267 -0
- package/utils/logger/index.d.ts +15 -0
- package/utils/logger/index.js +29 -0
- package/utils/logger/types.d.ts +23 -0
- package/utils/logger/types.js +1 -0
|
@@ -32,6 +32,7 @@ var _keyringService = require("@subwallet/extension-base/services/keyring-servic
|
|
|
32
32
|
var _migrationService = _interopRequireDefault(require("@subwallet/extension-base/services/migration-service"));
|
|
33
33
|
var _mintCampaignService = _interopRequireDefault(require("@subwallet/extension-base/services/mint-campaign-service"));
|
|
34
34
|
var _mktCampaignService = _interopRequireDefault(require("@subwallet/extension-base/services/mkt-campaign-service"));
|
|
35
|
+
var _multisigService = require("@subwallet/extension-base/services/multisig-service");
|
|
35
36
|
var _nftService = _interopRequireDefault(require("@subwallet/extension-base/services/nft-service"));
|
|
36
37
|
var _NotificationService = _interopRequireDefault(require("@subwallet/extension-base/services/notification-service/NotificationService"));
|
|
37
38
|
var _openGov = _interopRequireDefault(require("@subwallet/extension-base/services/open-gov"));
|
|
@@ -133,6 +134,7 @@ class KoniState {
|
|
|
133
134
|
this.inappNotificationService = new _inappNotificationService.InappNotificationService(this.dbService, this.keyringService, this.eventService, this.chainService);
|
|
134
135
|
this.chainOnlineService = new _chainOnlineService.ChainOnlineService(this.chainService, this.settingService, this.eventService, this.dbService);
|
|
135
136
|
this.openGovService = new _openGov.default(this);
|
|
137
|
+
this.multisigService = new _multisigService.MultisigService(this.eventService, this.chainService, this.keyringService, this.inappNotificationService);
|
|
136
138
|
this.substrateProxyAccountService = new _substrateProxyService.default(this);
|
|
137
139
|
this.subscription = new _subscription.KoniSubscription(this, this.dbService);
|
|
138
140
|
this.cron = new _cron.KoniCron(this, this.subscription, this.dbService);
|
|
@@ -239,6 +241,7 @@ class KoniState {
|
|
|
239
241
|
await this.swapService.init();
|
|
240
242
|
await this.inappNotificationService.init();
|
|
241
243
|
await this.openGovService.init();
|
|
244
|
+
await this.multisigService.init();
|
|
242
245
|
|
|
243
246
|
// this.onReady();
|
|
244
247
|
this.onAccountAdd();
|
|
@@ -1694,7 +1697,7 @@ class KoniState {
|
|
|
1694
1697
|
this.campaignService.stop();
|
|
1695
1698
|
await Promise.all([this.cron.stop(), this.subscription.stop()]);
|
|
1696
1699
|
await this.pauseAllNetworks(undefined, 'IDLE mode');
|
|
1697
|
-
await Promise.all([this.historyService.stop(), this.priceService.stop(), this.balanceService.stop(), this.earningService.stop(), this.swapService.stop(), this.inappNotificationService.stop(), this.openGovService.stop()]);
|
|
1700
|
+
await Promise.all([this.historyService.stop(), this.priceService.stop(), this.balanceService.stop(), this.earningService.stop(), this.swapService.stop(), this.inappNotificationService.stop(), this.openGovService.stop(), this.multisigService.stop()]);
|
|
1698
1701
|
|
|
1699
1702
|
// Complete sleeping
|
|
1700
1703
|
sleeping.resolve();
|
|
@@ -1750,7 +1753,7 @@ class KoniState {
|
|
|
1750
1753
|
this.generalStatus = _types.ServiceStatus.STARTING_FULL;
|
|
1751
1754
|
const startingFull = (0, _promise.createPromiseHandler)();
|
|
1752
1755
|
this.waitStartingFull = startingFull.promise;
|
|
1753
|
-
await Promise.all([this.cron.start(), this.subscription.start(), this.historyService.start(), this.priceService.start(), this.balanceService.start(), this.earningService.start(), this.swapService.start(), this.inappNotificationService.start(), this.openGovService.start()]);
|
|
1756
|
+
await Promise.all([this.cron.start(), this.subscription.start(), this.historyService.start(), this.priceService.start(), this.balanceService.start(), this.earningService.start(), this.swapService.start(), this.inappNotificationService.start(), this.openGovService.start(), this.multisigService.start()]);
|
|
1754
1757
|
this.eventService.emit('general.start_full', true);
|
|
1755
1758
|
this.waitStartingFull = null;
|
|
1756
1759
|
this.generalStatus = _types.ServiceStatus.STARTED_FULL;
|
|
@@ -83,11 +83,12 @@ function transformAccountsV2(accounts) {
|
|
|
83
83
|
let {
|
|
84
84
|
json: {
|
|
85
85
|
meta: {
|
|
86
|
-
isHidden
|
|
86
|
+
isHidden,
|
|
87
|
+
isMultisig
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
} = _ref2;
|
|
90
|
-
return !isHidden;
|
|
91
|
+
return !isHidden && !isMultisig;
|
|
91
92
|
}).filter(authTypeFilter).filter(_ref3 => {
|
|
92
93
|
let {
|
|
93
94
|
json: {
|
package/cjs/packageInfo.js
CHANGED
|
@@ -144,8 +144,6 @@ const subscribeWithSystemAccountPallet = async _ref => {
|
|
|
144
144
|
args: addresses
|
|
145
145
|
});
|
|
146
146
|
}
|
|
147
|
-
|
|
148
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
149
147
|
const subscription = substrateApi.subscribeDataWithMulti(params, async rs => {
|
|
150
148
|
const balances = rs[systemAccountKey];
|
|
151
149
|
const poolMemberInfos = rs[poolMembersKey];
|
|
@@ -358,7 +358,12 @@ class SubstrateApi {
|
|
|
358
358
|
subscriber.next([]);
|
|
359
359
|
});
|
|
360
360
|
} else {
|
|
361
|
-
observables[key] = apiRx[section][module][method].multi(args).pipe(
|
|
361
|
+
observables[key] = apiRx[section][module][method].multi(args).pipe(
|
|
362
|
+
// tap((codecs) => console.log('raw data', key, codecs)), // this line is used to debug data before transformation
|
|
363
|
+
(0, _rxjs.map)(codecs => codecs.map(codec => codec.toPrimitive())), (0, _rxjs.catchError)((error, caught) => {
|
|
364
|
+
console.error(`RxJS pipe() error for key ${key}`, error);
|
|
365
|
+
return (0, _rxjs.of)([]);
|
|
366
|
+
}));
|
|
362
367
|
}
|
|
363
368
|
});
|
|
364
369
|
return (0, _rxjs.combineLatest)(observables).subscribe(callback);
|
|
@@ -1450,6 +1450,7 @@ class ChainService {
|
|
|
1450
1450
|
hasNativeNft: false,
|
|
1451
1451
|
supportStaking: params.chainSpec.paraId === null,
|
|
1452
1452
|
supportProxy: false,
|
|
1453
|
+
supportMultisig: false,
|
|
1453
1454
|
supportSmartContract: null
|
|
1454
1455
|
};
|
|
1455
1456
|
} else if (params.chainSpec.evmChainId !== null) {
|
|
@@ -876,6 +876,10 @@ const _isChainInfoCompatibleWithAccountInfo = (chainInfo, accountInfo) => {
|
|
|
876
876
|
type: accountType
|
|
877
877
|
} = accountInfo;
|
|
878
878
|
if (accountChainType === _types3.AccountChainType.SUBSTRATE) {
|
|
879
|
+
var _chainInfo$substrateI19;
|
|
880
|
+
if (accountSignMode === _types3.AccountSignMode.MULTISIG && !((_chainInfo$substrateI19 = chainInfo.substrateInfo) !== null && _chainInfo$substrateI19 !== void 0 && _chainInfo$substrateI19.supportMultisig)) {
|
|
881
|
+
return false;
|
|
882
|
+
}
|
|
879
883
|
return _isPureSubstrateChain(chainInfo) && _types4.AllSubstrateKeypairTypes.includes(accountType);
|
|
880
884
|
}
|
|
881
885
|
if (accountChainType === _types3.AccountChainType.ETHEREUM) {
|
|
@@ -41,6 +41,7 @@ class EventService extends _eventemitter.default {
|
|
|
41
41
|
this.waitEarningReady = this.generateWaitPromise('earning.ready');
|
|
42
42
|
this.waitLedgerReady = this.generateWaitPromise('ledger.ready');
|
|
43
43
|
this.waitOpenGovReady = this.generateWaitPromise('open-gov.ready');
|
|
44
|
+
this.waitMultisigReady = this.generateWaitPromise('multisig-service.ready');
|
|
44
45
|
}
|
|
45
46
|
generateWaitPromise(eventType) {
|
|
46
47
|
return new Promise(resolve => {
|
|
@@ -54,13 +54,13 @@ const parseInfuraFee = (info, threshold) => {
|
|
|
54
54
|
exports.parseInfuraFee = parseInfuraFee;
|
|
55
55
|
const fetchInfuraFeeData = async (chainId, infuraAuth) => {
|
|
56
56
|
const baseUrl = 'https://gas.api.infura.io/networks/{{chainId}}/suggestedGasFees';
|
|
57
|
-
const
|
|
57
|
+
const baseThresholdUrl = 'https://gas.api.infura.io/networks/{{chainId}}/busyThreshold';
|
|
58
58
|
// const baseFeeHistoryUrl = 'https://gas.api.infura.io/networks/{{chainId}}/baseFeeHistory';
|
|
59
59
|
// const baseFeePercentileUrl = 'https://gas.api.infura.io/networks/{{chainId}}/baseFeePercentile';
|
|
60
60
|
const feeUrl = baseUrl.replaceAll('{{chainId}}', chainId.toString());
|
|
61
|
-
const
|
|
61
|
+
const thresholdUrl = baseThresholdUrl.replaceAll('{{chainId}}', chainId.toString());
|
|
62
62
|
try {
|
|
63
|
-
const [feeResp,
|
|
63
|
+
const [feeResp, thresholdResp] = await Promise.all([feeUrl, thresholdUrl].map(url => {
|
|
64
64
|
return fetch(url, {
|
|
65
65
|
method: 'GET',
|
|
66
66
|
headers: {
|
|
@@ -70,7 +70,7 @@ const fetchInfuraFeeData = async (chainId, infuraAuth) => {
|
|
|
70
70
|
}));
|
|
71
71
|
|
|
72
72
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
73
|
-
const [feeInfo, thresholdInfo] = await Promise.all([feeResp.json(),
|
|
73
|
+
const [feeInfo, thresholdInfo] = await Promise.all([feeResp.json(), thresholdResp.json()]);
|
|
74
74
|
return parseInfuraFee(feeInfo, thresholdInfo);
|
|
75
75
|
} catch (e) {
|
|
76
76
|
console.warn(e);
|
|
@@ -16,7 +16,8 @@ const NotificationTitleMap = {
|
|
|
16
16
|
[_interfaces.NotificationActionType.RECEIVE]: '[{{accountName}}] RECEIVE {{tokenSymbol}}',
|
|
17
17
|
[_interfaces.NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_AVAIL]: '[{{accountName}}] CLAIM {{tokenSymbol}}',
|
|
18
18
|
[_interfaces.NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_ETHEREUM]: '[{{accountName}}] CLAIM {{tokenSymbol}}',
|
|
19
|
-
[_interfaces.NotificationActionType.CLAIM_POLYGON_BRIDGE]: '[{{accountName}}] CLAIM {{tokenSymbol}}'
|
|
19
|
+
[_interfaces.NotificationActionType.CLAIM_POLYGON_BRIDGE]: '[{{accountName}}] CLAIM {{tokenSymbol}}',
|
|
20
|
+
[_interfaces.NotificationActionType.MULTISIG_APPROVAL]: '[{{accountName}}] APPROVAL REQUIRED'
|
|
20
21
|
};
|
|
21
22
|
exports.NotificationTitleMap = NotificationTitleMap;
|
|
22
23
|
const NotificationDescriptionMap = {
|
|
@@ -26,7 +27,8 @@ const NotificationDescriptionMap = {
|
|
|
26
27
|
[_interfaces.NotificationActionType.RECEIVE]: _utils.getReceiveDescription,
|
|
27
28
|
[_interfaces.NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_AVAIL]: _utils.getAvailBridgeClaimDescription,
|
|
28
29
|
[_interfaces.NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_ETHEREUM]: _utils.getAvailBridgeClaimDescription,
|
|
29
|
-
[_interfaces.NotificationActionType.CLAIM_POLYGON_BRIDGE]: _utils.getPolygonBridgeClaimDescription
|
|
30
|
+
[_interfaces.NotificationActionType.CLAIM_POLYGON_BRIDGE]: _utils.getPolygonBridgeClaimDescription,
|
|
31
|
+
[_interfaces.NotificationActionType.MULTISIG_APPROVAL]: _utils.getMultisigApprovalDescription
|
|
30
32
|
};
|
|
31
33
|
exports.NotificationDescriptionMap = NotificationDescriptionMap;
|
|
32
34
|
const ONE_DAY_MILLISECOND = 1000 * 24 * 60 * 60;
|
|
@@ -35,8 +35,8 @@ class InappNotificationService {
|
|
|
35
35
|
await this.start();
|
|
36
36
|
this.onAccountProxyRemove();
|
|
37
37
|
}
|
|
38
|
-
async markAllRead(
|
|
39
|
-
await this.dbService.markAllRead(
|
|
38
|
+
async markAllRead(params) {
|
|
39
|
+
await this.dbService.markAllRead(params);
|
|
40
40
|
}
|
|
41
41
|
async switchReadStatus(params) {
|
|
42
42
|
await this.dbService.switchReadStatus(params);
|
|
@@ -59,6 +59,9 @@ class InappNotificationService {
|
|
|
59
59
|
let overdueTime = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _consts.ONE_DAY_MILLISECOND * 60;
|
|
60
60
|
return this.dbService.cleanUpOldNotifications(overdueTime);
|
|
61
61
|
}
|
|
62
|
+
cleanUpNotificationByIds(ids) {
|
|
63
|
+
return this.dbService.cleanUpNotificationByIds(ids);
|
|
64
|
+
}
|
|
62
65
|
passValidateNotification(candidateNotification, comparedNotifications, remindTimeConfigInHrs) {
|
|
63
66
|
// todo: simplify condition !!
|
|
64
67
|
if ([_interfaces.NotificationActionType.WITHDRAW, _interfaces.NotificationActionType.CLAIM].includes(candidateNotification.actionType)) {
|
|
@@ -94,6 +97,7 @@ class InappNotificationService {
|
|
|
94
97
|
}
|
|
95
98
|
if ([_interfaces.NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_ETHEREUM, _interfaces.NotificationActionType.CLAIM_AVAIL_BRIDGE_ON_AVAIL].includes(candidateNotification.actionType)) {
|
|
96
99
|
const {
|
|
100
|
+
actionType,
|
|
97
101
|
address,
|
|
98
102
|
metadata,
|
|
99
103
|
time
|
|
@@ -104,6 +108,9 @@ class InappNotificationService {
|
|
|
104
108
|
if (notification.address !== address) {
|
|
105
109
|
continue;
|
|
106
110
|
}
|
|
111
|
+
if (notification.actionType !== actionType) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
107
114
|
if (time - notification.time >= remindTime) {
|
|
108
115
|
continue;
|
|
109
116
|
}
|
|
@@ -116,6 +123,7 @@ class InappNotificationService {
|
|
|
116
123
|
}
|
|
117
124
|
if ([_interfaces.NotificationActionType.CLAIM_POLYGON_BRIDGE].includes(candidateNotification.actionType)) {
|
|
118
125
|
const {
|
|
126
|
+
actionType,
|
|
119
127
|
address,
|
|
120
128
|
metadata,
|
|
121
129
|
time
|
|
@@ -126,6 +134,9 @@ class InappNotificationService {
|
|
|
126
134
|
if (notification.address !== address) {
|
|
127
135
|
continue;
|
|
128
136
|
}
|
|
137
|
+
if (notification.actionType !== actionType) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
129
140
|
if (time - notification.time >= remindTime) {
|
|
130
141
|
continue;
|
|
131
142
|
}
|
|
@@ -137,9 +148,16 @@ class InappNotificationService {
|
|
|
137
148
|
}
|
|
138
149
|
}
|
|
139
150
|
if ([_interfaces.NotificationActionType.SWAP, _interfaces.NotificationActionType.EARNING].includes(candidateNotification.actionType)) {
|
|
140
|
-
const
|
|
151
|
+
const {
|
|
152
|
+
actionType,
|
|
153
|
+
metadata
|
|
154
|
+
} = candidateNotification;
|
|
155
|
+
const candidateMetadata = metadata;
|
|
141
156
|
const processId = candidateMetadata.processId;
|
|
142
157
|
for (const notification of comparedNotifications) {
|
|
158
|
+
if (notification.actionType !== actionType) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
143
161
|
const comparedMetadata = notification.metadata;
|
|
144
162
|
const _processId = comparedMetadata.processId;
|
|
145
163
|
if (processId === _processId) {
|
|
@@ -147,10 +165,33 @@ class InappNotificationService {
|
|
|
147
165
|
}
|
|
148
166
|
}
|
|
149
167
|
}
|
|
168
|
+
if ([_interfaces.NotificationActionType.MULTISIG_APPROVAL].includes(candidateNotification.actionType)) {
|
|
169
|
+
const {
|
|
170
|
+
actionType,
|
|
171
|
+
address,
|
|
172
|
+
metadata
|
|
173
|
+
} = candidateNotification;
|
|
174
|
+
const candidateMetadata = metadata;
|
|
175
|
+
|
|
176
|
+
// todo: experiment without notification reminder, remove this todo if no problems raised
|
|
177
|
+
for (const notification of comparedNotifications) {
|
|
178
|
+
if (notification.address !== address) {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (notification.actionType !== actionType) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const comparedMetadata = notification.metadata;
|
|
185
|
+
const sameNotification = candidateMetadata.multisigTxType === comparedMetadata.multisigTxType && candidateMetadata.multisigKey === comparedMetadata.multisigKey;
|
|
186
|
+
if (sameNotification) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
150
191
|
return true;
|
|
151
192
|
}
|
|
152
193
|
async validateAndWriteNotificationsToDB(notifications, address) {
|
|
153
|
-
const proxyId = this.keyringService.context.belongUnifiedAccount(address) || address;
|
|
194
|
+
const proxyId = this.keyringService.context.belongUnifiedAccount(address) || (0, _utils3.reformatAddress)(address);
|
|
154
195
|
const accountName = this.keyringService.context.getCurrentAccountProxyName(proxyId);
|
|
155
196
|
const passNotifications = [];
|
|
156
197
|
const [comparedNotifications, remindTimeConfig] = await Promise.all([this.fetchNotificationsByParams({
|
|
@@ -429,7 +470,9 @@ class InappNotificationService {
|
|
|
429
470
|
this.status = _types.ServiceStatus.STARTING;
|
|
430
471
|
await this.startCron();
|
|
431
472
|
this.status = _types.ServiceStatus.STARTED;
|
|
432
|
-
} catch (e) {
|
|
473
|
+
} catch (e) {
|
|
474
|
+
console.error('Failed to start InappNotificationService', e);
|
|
475
|
+
}
|
|
433
476
|
}
|
|
434
477
|
async startCron() {
|
|
435
478
|
this.cleanUpOldNotifications().catch(console.error);
|
|
@@ -441,7 +484,9 @@ class InappNotificationService {
|
|
|
441
484
|
this.status = _types.ServiceStatus.STOPPING;
|
|
442
485
|
await this.stopCron();
|
|
443
486
|
this.status = _types.ServiceStatus.STOPPED;
|
|
444
|
-
} catch (e) {
|
|
487
|
+
} catch (e) {
|
|
488
|
+
console.error('Failed to stop InappNotificationService', e);
|
|
489
|
+
}
|
|
445
490
|
}
|
|
446
491
|
stopCron() {
|
|
447
492
|
return Promise.resolve(undefined);
|
|
@@ -32,6 +32,7 @@ exports.NotificationActionType = NotificationActionType;
|
|
|
32
32
|
NotificationActionType["CLAIM_POLYGON_BRIDGE"] = "CLAIM_POLYGON_BRIDGE";
|
|
33
33
|
NotificationActionType["SWAP"] = "SWAP";
|
|
34
34
|
NotificationActionType["EARNING"] = "EARNING";
|
|
35
|
+
NotificationActionType["MULTISIG_APPROVAL"] = "MULTISIG_APPROVAL";
|
|
35
36
|
})(NotificationActionType || (exports.NotificationActionType = NotificationActionType = {}));
|
|
36
37
|
let NotificationTab;
|
|
37
38
|
exports.NotificationTab = NotificationTab;
|
|
@@ -39,4 +40,5 @@ exports.NotificationTab = NotificationTab;
|
|
|
39
40
|
NotificationTab["ALL"] = "ALL";
|
|
40
41
|
NotificationTab["UNREAD"] = "UNREAD";
|
|
41
42
|
NotificationTab["READ"] = "READ";
|
|
43
|
+
NotificationTab["MULTISIG"] = "MULTISIG";
|
|
42
44
|
})(NotificationTab || (exports.NotificationTab = NotificationTab = {}));
|
|
@@ -7,6 +7,7 @@ exports.createClaimNotification = createClaimNotification;
|
|
|
7
7
|
exports.createWithdrawNotifications = createWithdrawNotifications;
|
|
8
8
|
exports.getClaimDescription = getClaimDescription;
|
|
9
9
|
exports.getIsTabRead = getIsTabRead;
|
|
10
|
+
exports.getMultisigApprovalDescription = getMultisigApprovalDescription;
|
|
10
11
|
exports.getReceiveDescription = getReceiveDescription;
|
|
11
12
|
exports.getSendDescription = getSendDescription;
|
|
12
13
|
exports.getWithdrawDescription = getWithdrawDescription;
|
|
@@ -36,6 +37,9 @@ function getSendDescription(amount, symbol) {
|
|
|
36
37
|
function getReceiveDescription(amount, symbol) {
|
|
37
38
|
return `You have just received ${amount} ${symbol}`;
|
|
38
39
|
}
|
|
40
|
+
function getMultisigApprovalDescription() {
|
|
41
|
+
return 'A multisig transaction is waiting for your approval. Click to view details';
|
|
42
|
+
}
|
|
39
43
|
|
|
40
44
|
/* Description */
|
|
41
45
|
|
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.AccountContext = void 0;
|
|
7
7
|
var _Migration = require("@subwallet/extension-base/services/keyring-service/context/handlers/Migration");
|
|
8
|
+
var _Multisig = require("@subwallet/extension-base/services/keyring-service/context/handlers/Multisig");
|
|
9
|
+
var _utils = require("@subwallet/extension-base/utils");
|
|
8
10
|
var _handlers = require("./handlers");
|
|
9
11
|
var _state = require("./state");
|
|
10
12
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
@@ -23,6 +25,7 @@ class AccountContext {
|
|
|
23
25
|
this.modifyHandler = new _handlers.AccountModifyHandler(this.parentService, this.state);
|
|
24
26
|
this.secretHandler = new _handlers.AccountSecretHandler(this.parentService, this.state);
|
|
25
27
|
this.migrationHandler = new _Migration.AccountMigrationHandler(this.parentService, this.state);
|
|
28
|
+
this.multisigHandler = new _Multisig.AccountMultisigHandler(this.parentService, this.state);
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
// TODO: Merge to value
|
|
@@ -147,6 +150,15 @@ class AccountContext {
|
|
|
147
150
|
return this.secretHandler.accountsCreateExternalV2(request);
|
|
148
151
|
}
|
|
149
152
|
|
|
153
|
+
/* Multisig */
|
|
154
|
+
async accountsCreateMultisig(request) {
|
|
155
|
+
return this.multisigHandler.accountsCreateMultisig(request);
|
|
156
|
+
}
|
|
157
|
+
getSignableAccountInfos(request) {
|
|
158
|
+
const chainInfo = this.koniState.chainService.getChainInfoByKey(request.chain);
|
|
159
|
+
return this.multisigHandler.getSignableAccountInfos(request, chainInfo);
|
|
160
|
+
}
|
|
161
|
+
|
|
150
162
|
/* Import ethereum account with the private key */
|
|
151
163
|
privateKeyValidateV2(request) {
|
|
152
164
|
return this.secretHandler.privateKeyValidateV2(request);
|
|
@@ -262,6 +274,38 @@ class AccountContext {
|
|
|
262
274
|
|
|
263
275
|
/* Migration */
|
|
264
276
|
|
|
277
|
+
/* Multisig */
|
|
278
|
+
|
|
279
|
+
getMultisigAccounts() {
|
|
280
|
+
return this.state.getMultisigAccounts();
|
|
281
|
+
}
|
|
282
|
+
getMultisigAccountByAddress(address) {
|
|
283
|
+
if (!address) {
|
|
284
|
+
return undefined;
|
|
285
|
+
}
|
|
286
|
+
const allMultisigAccounts = this.getMultisigAccounts();
|
|
287
|
+
return allMultisigAccounts.find(acc => acc.accounts[0].address === (0, _utils.reformatAddress)(address));
|
|
288
|
+
}
|
|
289
|
+
getMultisigAccountInfoByAddress(address) {
|
|
290
|
+
const accountProxy = this.getMultisigAccountByAddress(address);
|
|
291
|
+
if (!accountProxy) {
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
const threshold = accountProxy.accounts[0].threshold;
|
|
295
|
+
const signers = accountProxy.accounts[0].signers;
|
|
296
|
+
const multisigAddress = accountProxy.accounts[0].address;
|
|
297
|
+
return {
|
|
298
|
+
threshold,
|
|
299
|
+
signers,
|
|
300
|
+
multisigAddress
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
getMultisigAddresses() {
|
|
304
|
+
return this.state.getMultisigAddresses();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* Multisig */
|
|
308
|
+
|
|
265
309
|
/* Others */
|
|
266
310
|
|
|
267
311
|
removeNoneHardwareGenesisHash() {
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.AccountMultisigHandler = void 0;
|
|
7
|
+
var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
|
|
8
|
+
var _Base = require("@subwallet/extension-base/services/keyring-service/context/handlers/Base");
|
|
9
|
+
var _types = require("@subwallet/extension-base/types");
|
|
10
|
+
var _utils = require("@subwallet/extension-base/utils");
|
|
11
|
+
var _keyring = require("@subwallet/keyring");
|
|
12
|
+
var _uiKeyring = require("@subwallet/ui-keyring");
|
|
13
|
+
var _i18next = require("i18next");
|
|
14
|
+
var _utilCrypto = require("@polkadot/util-crypto");
|
|
15
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
16
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @class AccountMultisigHandler
|
|
20
|
+
* @extends AccountBaseHandler
|
|
21
|
+
* @description Handler for multisig account
|
|
22
|
+
* */
|
|
23
|
+
class AccountMultisigHandler extends _Base.AccountBaseHandler {
|
|
24
|
+
validateSigners(signers, threshold) {
|
|
25
|
+
const errors = [];
|
|
26
|
+
if (!signers || signers.length === 0) {
|
|
27
|
+
errors.push({
|
|
28
|
+
code: _KoniTypes.AccountMultisigErrorCode.INVALID_FILLED_ADDRESS,
|
|
29
|
+
message: (0, _i18next.t)('bg.ACCOUNT.services.keyring.handler.Multisig.signersRequired')
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (!signers || signers.length < 2) {
|
|
33
|
+
errors.push({
|
|
34
|
+
code: _KoniTypes.AccountMultisigErrorCode.INVALID_FILLED_ADDRESS,
|
|
35
|
+
message: (0, _i18next.t)('bg.ACCOUNT.services.keyring.handler.Multisig.multipleSignersRequired')
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (!threshold || threshold < 2 || threshold > signers.length) {
|
|
39
|
+
errors.push({
|
|
40
|
+
code: _KoniTypes.AccountMultisigErrorCode.INVALID_FILLED_THRESHOLD,
|
|
41
|
+
message: (0, _i18next.t)('bg.ACCOUNT.services.keyring.handler.Multisig.invalidThreshold')
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
for (const signer of signers) {
|
|
45
|
+
if (!signer || !(0, _keyring.isSubstrateAddress)(signer)) {
|
|
46
|
+
errors.push({
|
|
47
|
+
code: _KoniTypes.AccountMultisigErrorCode.INVALID_FILLED_ADDRESS,
|
|
48
|
+
message: (0, _i18next.t)('bg.ACCOUNT.services.keyring.handler.Multisig.mustBeSubstrateAddress')
|
|
49
|
+
});
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const distinctAddress = new Set();
|
|
54
|
+
for (const signer of signers) {
|
|
55
|
+
const rAddress = (0, _utils.reformatAddress)(signer);
|
|
56
|
+
if (distinctAddress.has(rAddress)) {
|
|
57
|
+
errors.push({
|
|
58
|
+
code: _KoniTypes.AccountMultisigErrorCode.DUPLICATE_FILLED_ADDRESS,
|
|
59
|
+
message: (0, _i18next.t)('bg.ACCOUNT.services.keyring.handler.Multisig.duplicateAddressFound')
|
|
60
|
+
});
|
|
61
|
+
break;
|
|
62
|
+
} else {
|
|
63
|
+
distinctAddress.add(rAddress);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return errors;
|
|
67
|
+
}
|
|
68
|
+
async accountsCreateMultisig(request) {
|
|
69
|
+
const {
|
|
70
|
+
name,
|
|
71
|
+
signers: _signer,
|
|
72
|
+
threshold
|
|
73
|
+
} = request;
|
|
74
|
+
|
|
75
|
+
// process signers
|
|
76
|
+
const signerError = this.validateSigners(_signer, threshold);
|
|
77
|
+
if (signerError.length > 0) {
|
|
78
|
+
return signerError;
|
|
79
|
+
}
|
|
80
|
+
const signers = _signer.map(address => (0, _utils.reformatAddress)(address));
|
|
81
|
+
const multisigKey = (0, _utilCrypto.createKeyMulti)(signers, threshold);
|
|
82
|
+
const multisigAddress = (0, _keyring.encodeAddress)(multisigKey);
|
|
83
|
+
try {
|
|
84
|
+
try {
|
|
85
|
+
const exists = _uiKeyring.keyring.getPair(multisigAddress);
|
|
86
|
+
if ((exists === null || exists === void 0 ? void 0 : exists.address) === (0, _utils.reformatAddress)(multisigAddress)) {
|
|
87
|
+
var _exists$meta;
|
|
88
|
+
const existingName = ((_exists$meta = exists.meta) === null || _exists$meta === void 0 ? void 0 : _exists$meta.name) || 'Unknown';
|
|
89
|
+
return [{
|
|
90
|
+
code: _KoniTypes.AccountMultisigErrorCode.INVALID_ADDRESS,
|
|
91
|
+
message: (0, _i18next.t)('bg.ACCOUNT.services.keyring.handler.Multisig.multisigAddressExists', {
|
|
92
|
+
replace: {
|
|
93
|
+
name: existingName
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
}];
|
|
97
|
+
}
|
|
98
|
+
} catch (e) {}
|
|
99
|
+
if (this.state.checkNameExists(name)) {
|
|
100
|
+
return [{
|
|
101
|
+
code: _KoniTypes.AccountMultisigErrorCode.INVALID_NAME,
|
|
102
|
+
message: (0, _i18next.t)('bg.ACCOUNT.services.keyring.handler.Secret.accountNameAlreadyExists')
|
|
103
|
+
}];
|
|
104
|
+
}
|
|
105
|
+
const meta = {
|
|
106
|
+
name,
|
|
107
|
+
threshold,
|
|
108
|
+
signers,
|
|
109
|
+
isExternal: true,
|
|
110
|
+
isMultisig: true,
|
|
111
|
+
genesisHash: ''
|
|
112
|
+
};
|
|
113
|
+
const multisigPair = _uiKeyring.keyring.keyring.addFromAddress(multisigAddress, meta);
|
|
114
|
+
_uiKeyring.keyring.saveAccount(multisigPair);
|
|
115
|
+
const address = multisigPair.address;
|
|
116
|
+
const modifiedPairs = this.state.modifyPairs;
|
|
117
|
+
modifiedPairs[address] = {
|
|
118
|
+
migrated: true,
|
|
119
|
+
key: address
|
|
120
|
+
};
|
|
121
|
+
this.state.upsertModifyPairs(modifiedPairs);
|
|
122
|
+
await new Promise(resolve => {
|
|
123
|
+
this.state.saveCurrentAccountProxyId(address, () => {
|
|
124
|
+
this.state._addAddressToAuthList(address, true);
|
|
125
|
+
resolve();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
return [];
|
|
129
|
+
} catch (e) {
|
|
130
|
+
return [{
|
|
131
|
+
code: _KoniTypes.AccountMultisigErrorCode.KEYRING_ERROR,
|
|
132
|
+
message: e.message
|
|
133
|
+
}];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Get 1-level signatories
|
|
139
|
+
* Ignore multisig accounts that are also signatories
|
|
140
|
+
*/
|
|
141
|
+
getSignableAccountInfos(request, chainInfo) {
|
|
142
|
+
var _chainInfo$substrateI;
|
|
143
|
+
const {
|
|
144
|
+
extrinsicType,
|
|
145
|
+
multisigProxyId
|
|
146
|
+
} = request;
|
|
147
|
+
if (!((_chainInfo$substrateI = chainInfo.substrateInfo) !== null && _chainInfo$substrateI !== void 0 && _chainInfo$substrateI.supportMultisig)) {
|
|
148
|
+
return {
|
|
149
|
+
signableProxies: []
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const allMultisigAccounts = this.state.getMultisigAccounts();
|
|
153
|
+
const allAccounts = this.state.accounts;
|
|
154
|
+
const targetMultisigAccount = allMultisigAccounts.find(acc => acc.id === multisigProxyId);
|
|
155
|
+
if (!targetMultisigAccount) {
|
|
156
|
+
return {
|
|
157
|
+
signableProxies: []
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const signableAccountInfo = [];
|
|
161
|
+
const signers = targetMultisigAccount.accounts[0].signers;
|
|
162
|
+
const allMultisigAccountAddress = allMultisigAccounts.map(acc => acc.id);
|
|
163
|
+
for (const signer of signers) {
|
|
164
|
+
if (allMultisigAccountAddress.includes(signer)) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const proxyId = this.state.belongUnifiedAccount(signer) || (0, _utils.reformatAddress)(signer);
|
|
168
|
+
const accountProxy = allAccounts[proxyId];
|
|
169
|
+
const substrateAccount = accountProxy === null || accountProxy === void 0 ? void 0 : accountProxy.accounts.find(acc => acc.chainType === _types.AccountChainType.SUBSTRATE);
|
|
170
|
+
if (substrateAccount) {
|
|
171
|
+
// Check if the account can sign the extrinsic type
|
|
172
|
+
// Only support 1 level signatories
|
|
173
|
+
if (substrateAccount.transactionActions.includes(extrinsicType) && !substrateAccount.isMultisig) {
|
|
174
|
+
signableAccountInfo.push({
|
|
175
|
+
proxyId,
|
|
176
|
+
address: signer
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
signableProxies: signableAccountInfo
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.AccountMultisigHandler = AccountMultisigHandler;
|
|
@@ -537,6 +537,18 @@ class AccountState {
|
|
|
537
537
|
* Account ref
|
|
538
538
|
* */
|
|
539
539
|
|
|
540
|
+
/* Multisig */
|
|
541
|
+
|
|
542
|
+
getMultisigAccounts() {
|
|
543
|
+
return Object.values(this.accounts).filter(acc => acc.accountType === _types.AccountProxyType.MULTISIG);
|
|
544
|
+
}
|
|
545
|
+
getMultisigAddresses() {
|
|
546
|
+
const allAccounts = this.getMultisigAccounts();
|
|
547
|
+
return allAccounts.map(acc => acc.id);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/* Multisig */
|
|
551
|
+
|
|
540
552
|
/* Others */
|
|
541
553
|
|
|
542
554
|
removeNoneHardwareGenesisHash() {
|