@subwallet/extension-base 1.0.5-3 → 1.0.6-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 +7 -0
- package/cjs/constants/index.js +1 -1
- package/cjs/koni/api/nft/rmrk_nft/index.js +0 -3
- package/cjs/koni/api/staking/index.js +6 -3
- package/cjs/koni/api/staking/relayChain.js +16 -14
- package/cjs/koni/background/handlers/Extension.js +59 -46
- package/cjs/koni/background/handlers/State.js +16 -0
- package/cjs/koni/background/handlers/Tabs.js +23 -5
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/constants.js +1 -1
- package/cjs/services/request-service/index.js +3 -0
- package/cjs/services/setting-service/SettingService.js +14 -0
- package/cjs/services/storage-service/DatabaseService.js +1 -1
- package/cjs/services/storage-service/db-stores/Nft.js +3 -3
- package/cjs/services/transaction-service/index.js +1 -1
- package/cjs/stores/PassPhishingStore.js +18 -0
- package/constants/index.d.ts +1 -1
- package/constants/index.js +1 -1
- package/koni/api/nft/rmrk_nft/index.js +1 -4
- package/koni/api/staking/index.js +6 -4
- package/koni/api/staking/relayChain.js +16 -14
- package/koni/background/handlers/Extension.d.ts +1 -0
- package/koni/background/handlers/Extension.js +59 -47
- package/koni/background/handlers/State.d.ts +1 -0
- package/koni/background/handlers/State.js +16 -0
- package/koni/background/handlers/Tabs.d.ts +2 -0
- package/koni/background/handlers/Tabs.js +23 -5
- package/package.json +10 -5
- package/packageInfo.js +1 -1
- package/services/chain-service/constants.js +1 -1
- package/services/request-service/handler/AuthRequestHandler.d.ts +1 -1
- package/services/request-service/index.d.ts +1 -0
- package/services/request-service/index.js +3 -0
- package/services/setting-service/SettingService.d.ts +5 -1
- package/services/setting-service/SettingService.js +14 -0
- package/services/storage-service/DatabaseService.js +1 -1
- package/services/storage-service/db-stores/Nft.d.ts +1 -1
- package/services/storage-service/db-stores/Nft.js +3 -3
- package/services/transaction-service/index.js +1 -1
- package/stores/PassPhishingStore.d.ts +5 -0
- package/stores/PassPhishingStore.js +10 -0
|
@@ -1383,6 +1383,12 @@ export interface AllLogoMap {
|
|
|
1383
1383
|
chainLogoMap: Record<string, string>;
|
|
1384
1384
|
assetLogoMap: Record<string, string>;
|
|
1385
1385
|
}
|
|
1386
|
+
export interface PassPhishing {
|
|
1387
|
+
pass: boolean;
|
|
1388
|
+
}
|
|
1389
|
+
export interface RequestPassPhishingPage {
|
|
1390
|
+
url: string;
|
|
1391
|
+
}
|
|
1386
1392
|
export interface KoniRequestSignatures {
|
|
1387
1393
|
'pri(staking.submitTuringCancelCompound)': [RequestTuringCancelStakeCompound, SWTransactionResponse];
|
|
1388
1394
|
'pri(staking.submitTuringCompound)': [RequestTuringStakeCompound, SWTransactionResponse];
|
|
@@ -1436,6 +1442,7 @@ export interface KoniRequestSignatures {
|
|
|
1436
1442
|
'pri(balance.getSubscription)': [RequestSubscribeBalance, BalanceJson, BalanceJson];
|
|
1437
1443
|
'pri(crowdloan.getCrowdloan)': [RequestCrowdloan, CrowdloanJson];
|
|
1438
1444
|
'pri(crowdloan.getSubscription)': [RequestSubscribeCrowdloan, CrowdloanJson, CrowdloanJson];
|
|
1445
|
+
'pri(phishing.pass)': [RequestPassPhishingPage, boolean];
|
|
1439
1446
|
'pri(authorize.listV2)': [null, ResponseAuthorizeList];
|
|
1440
1447
|
'pri(authorize.requestsV2)': [RequestAuthorizeSubscribe, boolean, AuthorizeRequest[]];
|
|
1441
1448
|
'pri(authorize.approveV2)': [RequestAuthorizeApproveV2, boolean];
|
package/cjs/constants/index.js
CHANGED
|
@@ -56,7 +56,7 @@ const CRON_REFRESH_NFT_INTERVAL = 7200000;
|
|
|
56
56
|
exports.CRON_REFRESH_NFT_INTERVAL = CRON_REFRESH_NFT_INTERVAL;
|
|
57
57
|
const CRON_REFRESH_STAKING_REWARD_INTERVAL = 900000;
|
|
58
58
|
exports.CRON_REFRESH_STAKING_REWARD_INTERVAL = CRON_REFRESH_STAKING_REWARD_INTERVAL;
|
|
59
|
-
const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL =
|
|
59
|
+
const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = 45000;
|
|
60
60
|
exports.CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL;
|
|
61
61
|
const CRON_REFRESH_HISTORY_INTERVAL = 900000;
|
|
62
62
|
exports.CRON_REFRESH_HISTORY_INTERVAL = CRON_REFRESH_HISTORY_INTERVAL;
|
|
@@ -50,9 +50,6 @@ class RmrkNftApi extends _nft.BaseNftApi {
|
|
|
50
50
|
}
|
|
51
51
|
async getAllByAccount(account) {
|
|
52
52
|
const fetchUrls = [{
|
|
53
|
-
url: _config.SINGULAR_V1_ENDPOINT + account,
|
|
54
|
-
source: RMRK_SOURCE.SINGULAR_V1
|
|
55
|
-
}, {
|
|
56
53
|
url: _config.SINGULAR_V2_ENDPOINT + account,
|
|
57
54
|
source: RMRK_SOURCE.SINGULAR_V2
|
|
58
55
|
}];
|
|
@@ -67,11 +67,14 @@ async function getNominationStakingRewardData(addresses, chainInfoMap) {
|
|
|
67
67
|
}
|
|
68
68
|
async function getPoolingStakingRewardData(addresses, networkMap, dotSamaApiMap) {
|
|
69
69
|
const activeNetworks = [];
|
|
70
|
-
Object.
|
|
71
|
-
|
|
70
|
+
Object.entries(networkMap).forEach(_ref3 => {
|
|
71
|
+
let [key, chainInfo] = _ref3;
|
|
72
|
+
if ((0, _utils._isChainSupportSubstrateStaking)(chainInfo) && (0, _utils._isSubstrateRelayChain)(chainInfo)) {
|
|
73
|
+
activeNetworks.push(key);
|
|
74
|
+
}
|
|
72
75
|
});
|
|
73
76
|
if (activeNetworks.length === 0) {
|
|
74
77
|
return [];
|
|
75
78
|
}
|
|
76
|
-
return
|
|
79
|
+
return (0, _relayChain.getNominationPoolReward)(addresses, networkMap, dotSamaApiMap);
|
|
77
80
|
}
|
|
@@ -148,20 +148,22 @@ async function getNominationPoolReward(addresses, chainInfoMap, substrateApiMap)
|
|
|
148
148
|
try {
|
|
149
149
|
await Promise.all(targetNetworks.map(async networkKey => {
|
|
150
150
|
const substrateApi = await substrateApiMap[networkKey].isReady;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
151
|
+
if (substrateApi.api.call.nominationPoolsApi) {
|
|
152
|
+
await Promise.all(validAddresses.map(async address => {
|
|
153
|
+
var _substrateApi$api$cal, _substrateApi$api$cal2;
|
|
154
|
+
const _unclaimedReward = await ((_substrateApi$api$cal = substrateApi.api.call) === null || _substrateApi$api$cal === void 0 ? void 0 : (_substrateApi$api$cal2 = _substrateApi$api$cal.nominationPoolsApi) === null || _substrateApi$api$cal2 === void 0 ? void 0 : _substrateApi$api$cal2.pendingRewards(address));
|
|
155
|
+
if (_unclaimedReward) {
|
|
156
|
+
rewardList.push({
|
|
157
|
+
address: address,
|
|
158
|
+
chain: networkKey,
|
|
159
|
+
unclaimedReward: _unclaimedReward.toString(),
|
|
160
|
+
name: chainInfoMap[networkKey].name,
|
|
161
|
+
state: _KoniTypes.APIItemState.READY,
|
|
162
|
+
type: _KoniTypes.StakingType.POOLED
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
165
167
|
}));
|
|
166
168
|
} catch (e) {
|
|
167
169
|
return rewardList;
|
|
@@ -1641,61 +1641,60 @@ class KoniExtension {
|
|
|
1641
1641
|
const substrateApi = this.#koniState.chainService.getSubstrateApi(networkKey);
|
|
1642
1642
|
let estimatedFee;
|
|
1643
1643
|
let maxTransferable = new _util.BN(freeBalance.value);
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
const mockTx = await (0, _xcm.createXcmExtrinsic)({
|
|
1652
|
-
chainInfoMap,
|
|
1653
|
-
destinationTokenInfo,
|
|
1654
|
-
originTokenInfo: tokenInfo,
|
|
1655
|
-
recipient: address,
|
|
1656
|
-
sendingValue: '0',
|
|
1657
|
-
substrateApi
|
|
1658
|
-
});
|
|
1659
|
-
try {
|
|
1644
|
+
try {
|
|
1645
|
+
if (isXcmTransfer) {
|
|
1646
|
+
const chainInfoMap = this.#koniState.chainService.getChainInfoMap();
|
|
1647
|
+
const destinationTokenInfo = this.#koniState.getXcmEqualAssetByChain(destChain, tokenInfo.slug);
|
|
1648
|
+
if (!destinationTokenInfo) {
|
|
1649
|
+
estimatedFee = '0';
|
|
1650
|
+
} else {
|
|
1660
1651
|
var _paymentInfo$partialF;
|
|
1652
|
+
maxTransferable = maxTransferable.sub(new _util.BN(tokenInfo.minAmount || '0'));
|
|
1653
|
+
const desChainInfo = chainInfoMap[destChain];
|
|
1654
|
+
const orgChainInfo = chainInfoMap[networkKey];
|
|
1655
|
+
const recipient = !(0, _utilCrypto.isEthereumAddress)(address) && (0, _utils._isChainEvmCompatible)(desChainInfo) && !(0, _utils._isChainEvmCompatible)(orgChainInfo) ? (0, _util.u8aToHex)((0, _utilCrypto.addressToEvm)(address)) : address;
|
|
1656
|
+
const mockTx = await (0, _xcm.createXcmExtrinsic)({
|
|
1657
|
+
chainInfoMap,
|
|
1658
|
+
destinationTokenInfo,
|
|
1659
|
+
originTokenInfo: tokenInfo,
|
|
1660
|
+
recipient: recipient,
|
|
1661
|
+
sendingValue: '0',
|
|
1662
|
+
substrateApi
|
|
1663
|
+
});
|
|
1661
1664
|
const paymentInfo = await mockTx.paymentInfo(address);
|
|
1662
1665
|
estimatedFee = (paymentInfo === null || paymentInfo === void 0 ? void 0 : (_paymentInfo$partialF = paymentInfo.partialFee) === null || _paymentInfo$partialF === void 0 ? void 0 : _paymentInfo$partialF.toString()) || '0';
|
|
1663
|
-
} catch (e) {
|
|
1664
|
-
estimatedFee = '0';
|
|
1665
|
-
console.warn(e);
|
|
1666
1666
|
}
|
|
1667
|
-
}
|
|
1668
|
-
} else {
|
|
1669
|
-
const chainInfo = this.#koniState.chainService.getChainInfoByKey(networkKey);
|
|
1670
|
-
if ((0, _utils._isChainEvmCompatible)(chainInfo)) {
|
|
1671
|
-
const web3 = this.#koniState.chainService.getEvmApi(networkKey);
|
|
1672
|
-
const transaction = {
|
|
1673
|
-
value: 1,
|
|
1674
|
-
to: address,
|
|
1675
|
-
from: address
|
|
1676
|
-
};
|
|
1677
|
-
const gasPrice = await web3.api.eth.getGasPrice();
|
|
1678
|
-
const gasLimit = await web3.api.eth.estimateGas(transaction);
|
|
1679
|
-
estimatedFee = (gasLimit * parseInt(gasPrice)).toString();
|
|
1680
1667
|
} else {
|
|
1681
|
-
const
|
|
1682
|
-
|
|
1683
|
-
networkKey
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1668
|
+
const chainInfo = this.#koniState.chainService.getChainInfoByKey(networkKey);
|
|
1669
|
+
if ((0, _utils._isChainEvmCompatible)(chainInfo)) {
|
|
1670
|
+
const web3 = this.#koniState.chainService.getEvmApi(networkKey);
|
|
1671
|
+
const transaction = {
|
|
1672
|
+
value: 0,
|
|
1673
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
1674
|
+
// null address
|
|
1675
|
+
from: address
|
|
1676
|
+
};
|
|
1677
|
+
const gasPrice = await web3.api.eth.getGasPrice();
|
|
1678
|
+
const gasLimit = await web3.api.eth.estimateGas(transaction);
|
|
1679
|
+
estimatedFee = (gasLimit * parseInt(gasPrice)).toString();
|
|
1680
|
+
} else {
|
|
1691
1681
|
var _paymentInfo$partialF2;
|
|
1682
|
+
const [mockTx] = await (0, _transfer.createTransferExtrinsic)({
|
|
1683
|
+
from: address,
|
|
1684
|
+
networkKey,
|
|
1685
|
+
substrateApi,
|
|
1686
|
+
to: address,
|
|
1687
|
+
tokenInfo,
|
|
1688
|
+
transferAll: true,
|
|
1689
|
+
value: '0'
|
|
1690
|
+
});
|
|
1692
1691
|
const paymentInfo = await (mockTx === null || mockTx === void 0 ? void 0 : mockTx.paymentInfo(address));
|
|
1693
1692
|
estimatedFee = (paymentInfo === null || paymentInfo === void 0 ? void 0 : (_paymentInfo$partialF2 = paymentInfo.partialFee) === null || _paymentInfo$partialF2 === void 0 ? void 0 : _paymentInfo$partialF2.toString()) || '0';
|
|
1694
|
-
} catch (e) {
|
|
1695
|
-
estimatedFee = '0';
|
|
1696
|
-
console.warn('Error estimating fee', e);
|
|
1697
1693
|
}
|
|
1698
1694
|
}
|
|
1695
|
+
} catch (e) {
|
|
1696
|
+
estimatedFee = '0';
|
|
1697
|
+
console.warn('Error estimating fee', e);
|
|
1699
1698
|
}
|
|
1700
1699
|
maxTransferable = maxTransferable.sub(new _util.BN(estimatedFee));
|
|
1701
1700
|
return {
|
|
@@ -2388,7 +2387,8 @@ class KoniExtension {
|
|
|
2388
2387
|
transaction: extrinsic,
|
|
2389
2388
|
data: inputData,
|
|
2390
2389
|
extrinsicType: _KoniTypes.ExtrinsicType.STAKING_JOIN_POOL,
|
|
2391
|
-
chainType: _KoniTypes.ChainType.SUBSTRATE
|
|
2390
|
+
chainType: _KoniTypes.ChainType.SUBSTRATE,
|
|
2391
|
+
transferNativeAmount: amount
|
|
2392
2392
|
});
|
|
2393
2393
|
}
|
|
2394
2394
|
async submitPoolingUnbonding(inputData) {
|
|
@@ -2966,6 +2966,15 @@ class KoniExtension {
|
|
|
2966
2966
|
};
|
|
2967
2967
|
}
|
|
2968
2968
|
|
|
2969
|
+
// Phishing detect
|
|
2970
|
+
|
|
2971
|
+
async passPhishingPage(_ref72) {
|
|
2972
|
+
let {
|
|
2973
|
+
url
|
|
2974
|
+
} = _ref72;
|
|
2975
|
+
return await this.#koniState.approvePassPhishingPage(url);
|
|
2976
|
+
}
|
|
2977
|
+
|
|
2969
2978
|
// --------------------------------------------------------------
|
|
2970
2979
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
2971
2980
|
async handle(id, type, request, port) {
|
|
@@ -3291,6 +3300,10 @@ class KoniExtension {
|
|
|
3291
3300
|
case 'pri(authorize.subscribe)':
|
|
3292
3301
|
return await this.subscribeAuthUrls(id, port);
|
|
3293
3302
|
|
|
3303
|
+
// Phishing page
|
|
3304
|
+
case 'pri(phishing.pass)':
|
|
3305
|
+
return await this.passPhishingPage(request);
|
|
3306
|
+
|
|
3294
3307
|
/// Keyring state
|
|
3295
3308
|
case 'pri(keyring.subscribe)':
|
|
3296
3309
|
return this.keyringStateSubscribe(id, port);
|
|
@@ -1469,6 +1469,22 @@ class KoniState {
|
|
|
1469
1469
|
async reloadStaking() {
|
|
1470
1470
|
return await this.cron.reloadStaking();
|
|
1471
1471
|
}
|
|
1472
|
+
async approvePassPhishingPage(_url) {
|
|
1473
|
+
return new Promise(resolve => {
|
|
1474
|
+
this.settingService.getPassPhishingList(value => {
|
|
1475
|
+
const result = {
|
|
1476
|
+
...value
|
|
1477
|
+
};
|
|
1478
|
+
const url = this.requestService.stripUrl(_url);
|
|
1479
|
+
result[url] = {
|
|
1480
|
+
pass: true
|
|
1481
|
+
};
|
|
1482
|
+
this.settingService.setPassPhishing(result, () => {
|
|
1483
|
+
resolve(true);
|
|
1484
|
+
});
|
|
1485
|
+
});
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1472
1488
|
async resetWallet(resetAll) {
|
|
1473
1489
|
this.keyringService.resetWallet(resetAll);
|
|
1474
1490
|
this.requestService.resetWallet();
|
|
@@ -116,6 +116,7 @@ class KoniTabs {
|
|
|
116
116
|
#koniState;
|
|
117
117
|
evmEventEmitterMap = {};
|
|
118
118
|
#chainPatrolService = _constants2.DEFAULT_CHAIN_PATROL_ENABLE;
|
|
119
|
+
#passPhishing = {};
|
|
119
120
|
constructor(koniState) {
|
|
120
121
|
this.#koniState = koniState;
|
|
121
122
|
const updateChainPatrolService = rs => {
|
|
@@ -125,6 +126,13 @@ class KoniTabs {
|
|
|
125
126
|
this.#koniState.settingService.getSubject().subscribe({
|
|
126
127
|
next: updateChainPatrolService
|
|
127
128
|
});
|
|
129
|
+
const updatePassPhishing = rs => {
|
|
130
|
+
this.#passPhishing = rs;
|
|
131
|
+
};
|
|
132
|
+
this.#koniState.settingService.getPassPhishingList(updatePassPhishing);
|
|
133
|
+
this.#koniState.settingService.passPhishingSubject().subscribe({
|
|
134
|
+
next: updatePassPhishing
|
|
135
|
+
});
|
|
128
136
|
}
|
|
129
137
|
|
|
130
138
|
/// Clone from Polkadot.js
|
|
@@ -217,21 +225,31 @@ class KoniTabs {
|
|
|
217
225
|
})));
|
|
218
226
|
});
|
|
219
227
|
}
|
|
220
|
-
|
|
228
|
+
checkPassList(_url) {
|
|
229
|
+
const url = stripUrl(_url);
|
|
230
|
+
const result = this.#passPhishing[url];
|
|
231
|
+
return result ? !result.pass : true;
|
|
232
|
+
}
|
|
233
|
+
async checkPhishing(url) {
|
|
221
234
|
const isInDenyList = await (0, _phishing.checkIfDenied)(url);
|
|
222
235
|
if (isInDenyList) {
|
|
223
|
-
this.
|
|
224
|
-
return true;
|
|
236
|
+
return this.checkPassList(url);
|
|
225
237
|
}
|
|
226
238
|
if (this.#chainPatrolService) {
|
|
227
239
|
const isInChainPatrolDenyList = await chainPatrolCheckUrl(url);
|
|
228
240
|
if (isInChainPatrolDenyList) {
|
|
229
|
-
this.
|
|
230
|
-
return true;
|
|
241
|
+
return this.checkPassList(url);
|
|
231
242
|
}
|
|
232
243
|
}
|
|
233
244
|
return false;
|
|
234
245
|
}
|
|
246
|
+
async redirectIfPhishing(url) {
|
|
247
|
+
const result = await this.checkPhishing(url);
|
|
248
|
+
if (result) {
|
|
249
|
+
this.redirectPhishingLanding(url);
|
|
250
|
+
}
|
|
251
|
+
return result;
|
|
252
|
+
}
|
|
235
253
|
|
|
236
254
|
///
|
|
237
255
|
|
package/cjs/packageInfo.js
CHANGED
|
@@ -66,7 +66,7 @@ const _STAKING_CHAIN_GROUP = {
|
|
|
66
66
|
kilt: ['kilt', 'kilt_peregrine'],
|
|
67
67
|
nominationPool: ['polkadot', 'kusama', 'westend', 'alephTest', 'aleph'],
|
|
68
68
|
bifrost: ['bifrost', 'bifrost_testnet'],
|
|
69
|
-
aleph: ['aleph, alephTest'] // A0 has distinct tokenomics
|
|
69
|
+
aleph: ['aleph', 'alephTest'] // A0 has distinct tokenomics
|
|
70
70
|
};
|
|
71
71
|
exports._STAKING_CHAIN_GROUP = _STAKING_CHAIN_GROUP;
|
|
72
72
|
const _STAKING_ERA_LENGTH_MAP = {
|
|
@@ -42,6 +42,9 @@ class RequestService {
|
|
|
42
42
|
updateIconV2(shouldClose) {
|
|
43
43
|
this.#popupHandler.updateIconV2(shouldClose);
|
|
44
44
|
}
|
|
45
|
+
stripUrl(url) {
|
|
46
|
+
return this.#authRequestHandler.stripUrl(url);
|
|
47
|
+
}
|
|
45
48
|
getAddressList() {
|
|
46
49
|
let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
47
50
|
const addressList = Object.keys(this.keyringService.accounts);
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.default = void 0;
|
|
8
|
+
var _PassPhishingStore = _interopRequireDefault(require("@subwallet/extension-base/stores/PassPhishingStore"));
|
|
8
9
|
var _Settings = _interopRequireDefault(require("@subwallet/extension-base/stores/Settings"));
|
|
9
10
|
var _constants = require("./constants");
|
|
10
11
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
@@ -12,6 +13,7 @@ var _constants = require("./constants");
|
|
|
12
13
|
|
|
13
14
|
class SettingService {
|
|
14
15
|
settingsStore = new _Settings.default();
|
|
16
|
+
passPhishingStore = new _PassPhishingStore.default();
|
|
15
17
|
getSubject() {
|
|
16
18
|
return this.settingsStore.getSubject();
|
|
17
19
|
}
|
|
@@ -27,8 +29,20 @@ class SettingService {
|
|
|
27
29
|
setSettings(data, callback) {
|
|
28
30
|
this.settingsStore.set('Settings', data, callback);
|
|
29
31
|
}
|
|
32
|
+
passPhishingSubject() {
|
|
33
|
+
return this.passPhishingStore.getSubject();
|
|
34
|
+
}
|
|
35
|
+
getPassPhishingList(update) {
|
|
36
|
+
this.passPhishingStore.get('PassPhishing', value => {
|
|
37
|
+
update(value || {});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
setPassPhishing(data, callback) {
|
|
41
|
+
this.passPhishingStore.set('PassPhishing', data, callback);
|
|
42
|
+
}
|
|
30
43
|
resetWallet() {
|
|
31
44
|
this.settingsStore.set('Settings', _constants.DEFAULT_SETTING);
|
|
45
|
+
this.passPhishingStore.set('PassPhishing', {});
|
|
32
46
|
}
|
|
33
47
|
}
|
|
34
48
|
exports.default = SettingService;
|
|
@@ -152,7 +152,7 @@ class DatabaseService {
|
|
|
152
152
|
}
|
|
153
153
|
async cleanUpNft(chain, owner, collectionIds, nftIds, ownNothing) {
|
|
154
154
|
if (ownNothing) {
|
|
155
|
-
return this.stores.nft.deleteNftsByChainAndOwner(chain, (0, _utils.reformatAddress)(owner, 42));
|
|
155
|
+
return this.stores.nft.deleteNftsByChainAndOwner(chain, (0, _utils.reformatAddress)(owner, 42), collectionIds);
|
|
156
156
|
}
|
|
157
157
|
return this.stores.nft.cleanUpNfts(chain, (0, _utils.reformatAddress)(owner, 42), collectionIds, nftIds);
|
|
158
158
|
}
|
|
@@ -28,13 +28,13 @@ class NftStore extends _BaseStoreWithAddressAndChain.default {
|
|
|
28
28
|
return this.table.where({
|
|
29
29
|
address,
|
|
30
30
|
chain
|
|
31
|
-
}).and(nft =>
|
|
31
|
+
}).and(nft => collectionIds.includes(nft.collectionId) && !nftIds.includes(nft.id)).delete();
|
|
32
32
|
}
|
|
33
|
-
deleteNftsByChainAndOwner(chain, address) {
|
|
33
|
+
deleteNftsByChainAndOwner(chain, address, collectionIds) {
|
|
34
34
|
return this.table.where({
|
|
35
35
|
address,
|
|
36
36
|
chain
|
|
37
|
-
}).delete();
|
|
37
|
+
}).and(nft => collectionIds.includes(nft.collectionId)).delete();
|
|
38
38
|
}
|
|
39
39
|
deleteNftByAddress(addresses) {
|
|
40
40
|
return this.table.where('address').anyOfIgnoreCase(addresses).delete();
|
|
@@ -129,7 +129,7 @@ class TransactionService {
|
|
|
129
129
|
} else {
|
|
130
130
|
var _pair$meta;
|
|
131
131
|
if ((_pair$meta = pair.meta) !== null && _pair$meta !== void 0 && _pair$meta.isReadOnly) {
|
|
132
|
-
validationResponse.errors.push(new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.INTERNAL_ERROR, 'This is
|
|
132
|
+
validationResponse.errors.push(new _TransactionError.TransactionError(_KoniTypes.BasicTxErrorType.INTERNAL_ERROR, 'This is watch-only account'));
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _defaults = require("@subwallet/extension-base/defaults");
|
|
9
|
+
var _SubscribableStore = _interopRequireDefault(require("@subwallet/extension-base/stores/SubscribableStore"));
|
|
10
|
+
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
11
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
12
|
+
|
|
13
|
+
class PassPhishingStore extends _SubscribableStore.default {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(_defaults.EXTENSION_PREFIX ? `${_defaults.EXTENSION_PREFIX}subwallet-pass-phishing-list` : null);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.default = PassPhishingStore;
|
package/constants/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare const ASTAR_REFRESH_BALANCE_INTERVAL = 60000;
|
|
|
6
6
|
export declare const SUB_TOKEN_REFRESH_BALANCE_INTERVAL = 60000;
|
|
7
7
|
export declare const CRON_REFRESH_NFT_INTERVAL = 7200000;
|
|
8
8
|
export declare const CRON_REFRESH_STAKING_REWARD_INTERVAL = 900000;
|
|
9
|
-
export declare const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL =
|
|
9
|
+
export declare const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = 45000;
|
|
10
10
|
export declare const CRON_REFRESH_HISTORY_INTERVAL = 900000;
|
|
11
11
|
export declare const CRON_GET_API_MAP_STATUS = 10000;
|
|
12
12
|
export declare const CRON_REFRESH_CHAIN_STAKING_METADATA = 900000;
|
package/constants/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export const ASTAR_REFRESH_BALANCE_INTERVAL = 60000;
|
|
|
9
9
|
export const SUB_TOKEN_REFRESH_BALANCE_INTERVAL = 60000;
|
|
10
10
|
export const CRON_REFRESH_NFT_INTERVAL = 7200000;
|
|
11
11
|
export const CRON_REFRESH_STAKING_REWARD_INTERVAL = 900000;
|
|
12
|
-
export const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL =
|
|
12
|
+
export const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = 45000;
|
|
13
13
|
export const CRON_REFRESH_HISTORY_INTERVAL = 900000;
|
|
14
14
|
export const CRON_GET_API_MAP_STATUS = 10000;
|
|
15
15
|
export const CRON_REFRESH_CHAIN_STAKING_METADATA = 900000;
|
|
@@ -5,7 +5,7 @@ import { RMRK_VER } from '@subwallet/extension-base/background/KoniTypes';
|
|
|
5
5
|
import { BaseNftApi } from '@subwallet/extension-base/koni/api/nft/nft';
|
|
6
6
|
import { isUrl, reformatAddress } from '@subwallet/extension-base/utils';
|
|
7
7
|
import fetch from 'cross-fetch';
|
|
8
|
-
import { getRandomIpfsGateway, SINGULAR_V1_COLLECTION_ENDPOINT,
|
|
8
|
+
import { getRandomIpfsGateway, SINGULAR_V1_COLLECTION_ENDPOINT, SINGULAR_V2_COLLECTION_ENDPOINT, SINGULAR_V2_ENDPOINT } from "../config.js";
|
|
9
9
|
var RMRK_SOURCE;
|
|
10
10
|
(function (RMRK_SOURCE) {
|
|
11
11
|
RMRK_SOURCE["BIRD_KANARIA"] = "bird_kanaria";
|
|
@@ -44,9 +44,6 @@ export class RmrkNftApi extends BaseNftApi {
|
|
|
44
44
|
}
|
|
45
45
|
async getAllByAccount(account) {
|
|
46
46
|
const fetchUrls = [{
|
|
47
|
-
url: SINGULAR_V1_ENDPOINT + account,
|
|
48
|
-
source: RMRK_SOURCE.SINGULAR_V1
|
|
49
|
-
}, {
|
|
50
47
|
url: SINGULAR_V2_ENDPOINT + account,
|
|
51
48
|
source: RMRK_SOURCE.SINGULAR_V2
|
|
52
49
|
}];
|
|
@@ -5,7 +5,7 @@ import { getAmplitudeStakingOnChain, getAstarStakingOnChain, getParaStakingOnCha
|
|
|
5
5
|
import { getNominationPoolReward, getRelayPoolingOnChain, getRelayStakingOnChain } from '@subwallet/extension-base/koni/api/staking/relayChain';
|
|
6
6
|
import { getAllSubsquidStaking } from '@subwallet/extension-base/koni/api/staking/subsquidStaking';
|
|
7
7
|
import { _PURE_EVM_CHAINS, _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
8
|
-
import { _isChainEvmCompatible, _isChainSupportSubstrateStaking } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
|
+
import { _isChainEvmCompatible, _isChainSupportSubstrateStaking, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
|
|
9
9
|
import { categoryAddresses } from '@subwallet/extension-base/utils';
|
|
10
10
|
export function stakingOnChainApi(addresses, substrateApiMap, callback, chainInfoMap) {
|
|
11
11
|
const filteredApiMap = [];
|
|
@@ -57,11 +57,13 @@ export async function getNominationStakingRewardData(addresses, chainInfoMap) {
|
|
|
57
57
|
}
|
|
58
58
|
export async function getPoolingStakingRewardData(addresses, networkMap, dotSamaApiMap) {
|
|
59
59
|
const activeNetworks = [];
|
|
60
|
-
Object.
|
|
61
|
-
|
|
60
|
+
Object.entries(networkMap).forEach(([key, chainInfo]) => {
|
|
61
|
+
if (_isChainSupportSubstrateStaking(chainInfo) && _isSubstrateRelayChain(chainInfo)) {
|
|
62
|
+
activeNetworks.push(key);
|
|
63
|
+
}
|
|
62
64
|
});
|
|
63
65
|
if (activeNetworks.length === 0) {
|
|
64
66
|
return [];
|
|
65
67
|
}
|
|
66
|
-
return
|
|
68
|
+
return getNominationPoolReward(addresses, networkMap, dotSamaApiMap);
|
|
67
69
|
}
|
|
@@ -138,20 +138,22 @@ export async function getNominationPoolReward(addresses, chainInfoMap, substrate
|
|
|
138
138
|
try {
|
|
139
139
|
await Promise.all(targetNetworks.map(async networkKey => {
|
|
140
140
|
const substrateApi = await substrateApiMap[networkKey].isReady;
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
141
|
+
if (substrateApi.api.call.nominationPoolsApi) {
|
|
142
|
+
await Promise.all(validAddresses.map(async address => {
|
|
143
|
+
var _substrateApi$api$cal, _substrateApi$api$cal2;
|
|
144
|
+
const _unclaimedReward = await ((_substrateApi$api$cal = substrateApi.api.call) === null || _substrateApi$api$cal === void 0 ? void 0 : (_substrateApi$api$cal2 = _substrateApi$api$cal.nominationPoolsApi) === null || _substrateApi$api$cal2 === void 0 ? void 0 : _substrateApi$api$cal2.pendingRewards(address));
|
|
145
|
+
if (_unclaimedReward) {
|
|
146
|
+
rewardList.push({
|
|
147
|
+
address: address,
|
|
148
|
+
chain: networkKey,
|
|
149
|
+
unclaimedReward: _unclaimedReward.toString(),
|
|
150
|
+
name: chainInfoMap[networkKey].name,
|
|
151
|
+
state: APIItemState.READY,
|
|
152
|
+
type: StakingType.POOLED
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}));
|
|
156
|
+
}
|
|
155
157
|
}));
|
|
156
158
|
} catch (e) {
|
|
157
159
|
return rewardList;
|
|
@@ -188,5 +188,6 @@ export default class KoniExtension {
|
|
|
188
188
|
private subscribeNotifications;
|
|
189
189
|
private reloadCron;
|
|
190
190
|
private getLogoMap;
|
|
191
|
+
private passPhishingPage;
|
|
191
192
|
handle<TMessageType extends MessageTypes>(id: string, type: TMessageType, request: RequestTypes[TMessageType], port: chrome.runtime.Port): Promise<ResponseType<TMessageType>>;
|
|
192
193
|
}
|
|
@@ -31,7 +31,7 @@ import BigN from 'bignumber.js';
|
|
|
31
31
|
import { Transaction } from 'ethereumjs-tx';
|
|
32
32
|
import { TypeRegistry } from '@polkadot/types';
|
|
33
33
|
import { assert, BN, BN_ZERO, hexStripPrefix, hexToU8a, isAscii, isHex, u8aToHex, u8aToString } from '@polkadot/util';
|
|
34
|
-
import { base64Decode, decodeAddress, isAddress, isEthereumAddress, jsonDecrypt, keyExtractSuri, mnemonicGenerate, mnemonicValidate } from '@polkadot/util-crypto';
|
|
34
|
+
import { addressToEvm, base64Decode, decodeAddress, isAddress, isEthereumAddress, jsonDecrypt, keyExtractSuri, mnemonicGenerate, mnemonicValidate } from '@polkadot/util-crypto';
|
|
35
35
|
const ETH_DERIVE_DEFAULT = '/m/44\'/60\'/0\'/0/0';
|
|
36
36
|
function getSuri(seed, type) {
|
|
37
37
|
return type === 'ethereum' ? `${seed}${ETH_DERIVE_DEFAULT}` : seed;
|
|
@@ -1590,61 +1590,60 @@ export default class KoniExtension {
|
|
|
1590
1590
|
const substrateApi = this.#koniState.chainService.getSubstrateApi(networkKey);
|
|
1591
1591
|
let estimatedFee;
|
|
1592
1592
|
let maxTransferable = new BN(freeBalance.value);
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
const mockTx = await createXcmExtrinsic({
|
|
1601
|
-
chainInfoMap,
|
|
1602
|
-
destinationTokenInfo,
|
|
1603
|
-
originTokenInfo: tokenInfo,
|
|
1604
|
-
recipient: address,
|
|
1605
|
-
sendingValue: '0',
|
|
1606
|
-
substrateApi
|
|
1607
|
-
});
|
|
1608
|
-
try {
|
|
1593
|
+
try {
|
|
1594
|
+
if (isXcmTransfer) {
|
|
1595
|
+
const chainInfoMap = this.#koniState.chainService.getChainInfoMap();
|
|
1596
|
+
const destinationTokenInfo = this.#koniState.getXcmEqualAssetByChain(destChain, tokenInfo.slug);
|
|
1597
|
+
if (!destinationTokenInfo) {
|
|
1598
|
+
estimatedFee = '0';
|
|
1599
|
+
} else {
|
|
1609
1600
|
var _paymentInfo$partialF;
|
|
1601
|
+
maxTransferable = maxTransferable.sub(new BN(tokenInfo.minAmount || '0'));
|
|
1602
|
+
const desChainInfo = chainInfoMap[destChain];
|
|
1603
|
+
const orgChainInfo = chainInfoMap[networkKey];
|
|
1604
|
+
const recipient = !isEthereumAddress(address) && _isChainEvmCompatible(desChainInfo) && !_isChainEvmCompatible(orgChainInfo) ? u8aToHex(addressToEvm(address)) : address;
|
|
1605
|
+
const mockTx = await createXcmExtrinsic({
|
|
1606
|
+
chainInfoMap,
|
|
1607
|
+
destinationTokenInfo,
|
|
1608
|
+
originTokenInfo: tokenInfo,
|
|
1609
|
+
recipient: recipient,
|
|
1610
|
+
sendingValue: '0',
|
|
1611
|
+
substrateApi
|
|
1612
|
+
});
|
|
1610
1613
|
const paymentInfo = await mockTx.paymentInfo(address);
|
|
1611
1614
|
estimatedFee = (paymentInfo === null || paymentInfo === void 0 ? void 0 : (_paymentInfo$partialF = paymentInfo.partialFee) === null || _paymentInfo$partialF === void 0 ? void 0 : _paymentInfo$partialF.toString()) || '0';
|
|
1612
|
-
} catch (e) {
|
|
1613
|
-
estimatedFee = '0';
|
|
1614
|
-
console.warn(e);
|
|
1615
1615
|
}
|
|
1616
|
-
}
|
|
1617
|
-
} else {
|
|
1618
|
-
const chainInfo = this.#koniState.chainService.getChainInfoByKey(networkKey);
|
|
1619
|
-
if (_isChainEvmCompatible(chainInfo)) {
|
|
1620
|
-
const web3 = this.#koniState.chainService.getEvmApi(networkKey);
|
|
1621
|
-
const transaction = {
|
|
1622
|
-
value: 1,
|
|
1623
|
-
to: address,
|
|
1624
|
-
from: address
|
|
1625
|
-
};
|
|
1626
|
-
const gasPrice = await web3.api.eth.getGasPrice();
|
|
1627
|
-
const gasLimit = await web3.api.eth.estimateGas(transaction);
|
|
1628
|
-
estimatedFee = (gasLimit * parseInt(gasPrice)).toString();
|
|
1629
1616
|
} else {
|
|
1630
|
-
const
|
|
1631
|
-
|
|
1632
|
-
networkKey
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1617
|
+
const chainInfo = this.#koniState.chainService.getChainInfoByKey(networkKey);
|
|
1618
|
+
if (_isChainEvmCompatible(chainInfo)) {
|
|
1619
|
+
const web3 = this.#koniState.chainService.getEvmApi(networkKey);
|
|
1620
|
+
const transaction = {
|
|
1621
|
+
value: 0,
|
|
1622
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
1623
|
+
// null address
|
|
1624
|
+
from: address
|
|
1625
|
+
};
|
|
1626
|
+
const gasPrice = await web3.api.eth.getGasPrice();
|
|
1627
|
+
const gasLimit = await web3.api.eth.estimateGas(transaction);
|
|
1628
|
+
estimatedFee = (gasLimit * parseInt(gasPrice)).toString();
|
|
1629
|
+
} else {
|
|
1640
1630
|
var _paymentInfo$partialF2;
|
|
1631
|
+
const [mockTx] = await createTransferExtrinsic({
|
|
1632
|
+
from: address,
|
|
1633
|
+
networkKey,
|
|
1634
|
+
substrateApi,
|
|
1635
|
+
to: address,
|
|
1636
|
+
tokenInfo,
|
|
1637
|
+
transferAll: true,
|
|
1638
|
+
value: '0'
|
|
1639
|
+
});
|
|
1641
1640
|
const paymentInfo = await (mockTx === null || mockTx === void 0 ? void 0 : mockTx.paymentInfo(address));
|
|
1642
1641
|
estimatedFee = (paymentInfo === null || paymentInfo === void 0 ? void 0 : (_paymentInfo$partialF2 = paymentInfo.partialFee) === null || _paymentInfo$partialF2 === void 0 ? void 0 : _paymentInfo$partialF2.toString()) || '0';
|
|
1643
|
-
} catch (e) {
|
|
1644
|
-
estimatedFee = '0';
|
|
1645
|
-
console.warn('Error estimating fee', e);
|
|
1646
1642
|
}
|
|
1647
1643
|
}
|
|
1644
|
+
} catch (e) {
|
|
1645
|
+
estimatedFee = '0';
|
|
1646
|
+
console.warn('Error estimating fee', e);
|
|
1648
1647
|
}
|
|
1649
1648
|
maxTransferable = maxTransferable.sub(new BN(estimatedFee));
|
|
1650
1649
|
return {
|
|
@@ -2322,7 +2321,8 @@ export default class KoniExtension {
|
|
|
2322
2321
|
transaction: extrinsic,
|
|
2323
2322
|
data: inputData,
|
|
2324
2323
|
extrinsicType: ExtrinsicType.STAKING_JOIN_POOL,
|
|
2325
|
-
chainType: ChainType.SUBSTRATE
|
|
2324
|
+
chainType: ChainType.SUBSTRATE,
|
|
2325
|
+
transferNativeAmount: amount
|
|
2326
2326
|
});
|
|
2327
2327
|
}
|
|
2328
2328
|
async submitPoolingUnbonding(inputData) {
|
|
@@ -2885,6 +2885,14 @@ export default class KoniExtension {
|
|
|
2885
2885
|
};
|
|
2886
2886
|
}
|
|
2887
2887
|
|
|
2888
|
+
// Phishing detect
|
|
2889
|
+
|
|
2890
|
+
async passPhishingPage({
|
|
2891
|
+
url
|
|
2892
|
+
}) {
|
|
2893
|
+
return await this.#koniState.approvePassPhishingPage(url);
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2888
2896
|
// --------------------------------------------------------------
|
|
2889
2897
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
2890
2898
|
async handle(id, type, request, port) {
|
|
@@ -3210,6 +3218,10 @@ export default class KoniExtension {
|
|
|
3210
3218
|
case 'pri(authorize.subscribe)':
|
|
3211
3219
|
return await this.subscribeAuthUrls(id, port);
|
|
3212
3220
|
|
|
3221
|
+
// Phishing page
|
|
3222
|
+
case 'pri(phishing.pass)':
|
|
3223
|
+
return await this.passPhishingPage(request);
|
|
3224
|
+
|
|
3213
3225
|
/// Keyring state
|
|
3214
3226
|
case 'pri(keyring.subscribe)':
|
|
3215
3227
|
return this.keyringStateSubscribe(id, port);
|
|
@@ -223,6 +223,7 @@ export default class KoniState {
|
|
|
223
223
|
onAccountRemove(): void;
|
|
224
224
|
reloadNft(): Promise<boolean>;
|
|
225
225
|
reloadStaking(): Promise<boolean>;
|
|
226
|
+
approvePassPhishingPage(_url: string): Promise<boolean>;
|
|
226
227
|
resetWallet(resetAll: boolean): Promise<void>;
|
|
227
228
|
}
|
|
228
229
|
export {};
|
|
@@ -1441,6 +1441,22 @@ export default class KoniState {
|
|
|
1441
1441
|
async reloadStaking() {
|
|
1442
1442
|
return await this.cron.reloadStaking();
|
|
1443
1443
|
}
|
|
1444
|
+
async approvePassPhishingPage(_url) {
|
|
1445
|
+
return new Promise(resolve => {
|
|
1446
|
+
this.settingService.getPassPhishingList(value => {
|
|
1447
|
+
const result = {
|
|
1448
|
+
...value
|
|
1449
|
+
};
|
|
1450
|
+
const url = this.requestService.stripUrl(_url);
|
|
1451
|
+
result[url] = {
|
|
1452
|
+
pass: true
|
|
1453
|
+
};
|
|
1454
|
+
this.settingService.setPassPhishing(result, () => {
|
|
1455
|
+
resolve(true);
|
|
1456
|
+
});
|
|
1457
|
+
});
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1444
1460
|
async resetWallet(resetAll) {
|
|
1445
1461
|
this.keyringService.resetWallet(resetAll);
|
|
1446
1462
|
this.requestService.resetWallet();
|
|
@@ -20,6 +20,8 @@ export default class KoniTabs {
|
|
|
20
20
|
private rpcSubscribeConnected;
|
|
21
21
|
private rpcUnsubscribe;
|
|
22
22
|
private redirectPhishingLanding;
|
|
23
|
+
private checkPassList;
|
|
24
|
+
protected checkPhishing(url: string): Promise<boolean>;
|
|
23
25
|
protected redirectIfPhishing(url: string): Promise<boolean>;
|
|
24
26
|
private cancelSubscription;
|
|
25
27
|
private createUnsubscriptionHandle;
|
|
@@ -84,6 +84,7 @@ export default class KoniTabs {
|
|
|
84
84
|
#koniState;
|
|
85
85
|
evmEventEmitterMap = {};
|
|
86
86
|
#chainPatrolService = DEFAULT_CHAIN_PATROL_ENABLE;
|
|
87
|
+
#passPhishing = {};
|
|
87
88
|
constructor(koniState) {
|
|
88
89
|
this.#koniState = koniState;
|
|
89
90
|
const updateChainPatrolService = rs => {
|
|
@@ -93,6 +94,13 @@ export default class KoniTabs {
|
|
|
93
94
|
this.#koniState.settingService.getSubject().subscribe({
|
|
94
95
|
next: updateChainPatrolService
|
|
95
96
|
});
|
|
97
|
+
const updatePassPhishing = rs => {
|
|
98
|
+
this.#passPhishing = rs;
|
|
99
|
+
};
|
|
100
|
+
this.#koniState.settingService.getPassPhishingList(updatePassPhishing);
|
|
101
|
+
this.#koniState.settingService.passPhishingSubject().subscribe({
|
|
102
|
+
next: updatePassPhishing
|
|
103
|
+
});
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
/// Clone from Polkadot.js
|
|
@@ -179,21 +187,31 @@ export default class KoniTabs {
|
|
|
179
187
|
})));
|
|
180
188
|
});
|
|
181
189
|
}
|
|
182
|
-
|
|
190
|
+
checkPassList(_url) {
|
|
191
|
+
const url = stripUrl(_url);
|
|
192
|
+
const result = this.#passPhishing[url];
|
|
193
|
+
return result ? !result.pass : true;
|
|
194
|
+
}
|
|
195
|
+
async checkPhishing(url) {
|
|
183
196
|
const isInDenyList = await checkIfDenied(url);
|
|
184
197
|
if (isInDenyList) {
|
|
185
|
-
this.
|
|
186
|
-
return true;
|
|
198
|
+
return this.checkPassList(url);
|
|
187
199
|
}
|
|
188
200
|
if (this.#chainPatrolService) {
|
|
189
201
|
const isInChainPatrolDenyList = await chainPatrolCheckUrl(url);
|
|
190
202
|
if (isInChainPatrolDenyList) {
|
|
191
|
-
this.
|
|
192
|
-
return true;
|
|
203
|
+
return this.checkPassList(url);
|
|
193
204
|
}
|
|
194
205
|
}
|
|
195
206
|
return false;
|
|
196
207
|
}
|
|
208
|
+
async redirectIfPhishing(url) {
|
|
209
|
+
const result = await this.checkPhishing(url);
|
|
210
|
+
if (result) {
|
|
211
|
+
this.redirectPhishingLanding(url);
|
|
212
|
+
}
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
197
215
|
|
|
198
216
|
///
|
|
199
217
|
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"./cjs/detectPackage.js"
|
|
18
18
|
],
|
|
19
19
|
"type": "module",
|
|
20
|
-
"version": "1.0.
|
|
20
|
+
"version": "1.0.6-1",
|
|
21
21
|
"main": "./cjs/index.js",
|
|
22
22
|
"module": "./index.js",
|
|
23
23
|
"types": "./index.d.ts",
|
|
@@ -1555,6 +1555,11 @@
|
|
|
1555
1555
|
"require": "./cjs/stores/Metadata.js",
|
|
1556
1556
|
"default": "./stores/Metadata.js"
|
|
1557
1557
|
},
|
|
1558
|
+
"./stores/PassPhishingStore": {
|
|
1559
|
+
"types": "./stores/PassPhishingStore.d.ts",
|
|
1560
|
+
"require": "./cjs/stores/PassPhishingStore.js",
|
|
1561
|
+
"default": "./stores/PassPhishingStore.js"
|
|
1562
|
+
},
|
|
1558
1563
|
"./stores/Settings": {
|
|
1559
1564
|
"types": "./stores/Settings.d.ts",
|
|
1560
1565
|
"require": "./cjs/stores/Settings.js",
|
|
@@ -1693,10 +1698,10 @@
|
|
|
1693
1698
|
"@subsocial/types": "^0.6.8",
|
|
1694
1699
|
"@substrate/connect": "^0.7.26",
|
|
1695
1700
|
"@subwallet/chain-list": "^0.1.7",
|
|
1696
|
-
"@subwallet/extension-base": "^1.0.
|
|
1697
|
-
"@subwallet/extension-chains": "^1.0.
|
|
1698
|
-
"@subwallet/extension-dapp": "^1.0.
|
|
1699
|
-
"@subwallet/extension-inject": "^1.0.
|
|
1701
|
+
"@subwallet/extension-base": "^1.0.6-1",
|
|
1702
|
+
"@subwallet/extension-chains": "^1.0.6-1",
|
|
1703
|
+
"@subwallet/extension-dapp": "^1.0.6-1",
|
|
1704
|
+
"@subwallet/extension-inject": "^1.0.6-1",
|
|
1700
1705
|
"@subwallet/keyring": "^0.0.9",
|
|
1701
1706
|
"@subwallet/ui-keyring": "^0.0.9",
|
|
1702
1707
|
"@unique-nft/types": "^0.6.0-4",
|
package/packageInfo.js
CHANGED
|
@@ -7,5 +7,5 @@ export const packageInfo = {
|
|
|
7
7
|
name: '@subwallet/extension-base',
|
|
8
8
|
path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
|
|
9
9
|
type: 'esm',
|
|
10
|
-
version: '1.0.
|
|
10
|
+
version: '1.0.6-1'
|
|
11
11
|
};
|
|
@@ -55,7 +55,7 @@ export const _STAKING_CHAIN_GROUP = {
|
|
|
55
55
|
kilt: ['kilt', 'kilt_peregrine'],
|
|
56
56
|
nominationPool: ['polkadot', 'kusama', 'westend', 'alephTest', 'aleph'],
|
|
57
57
|
bifrost: ['bifrost', 'bifrost_testnet'],
|
|
58
|
-
aleph: ['aleph, alephTest'] // A0 has distinct tokenomics
|
|
58
|
+
aleph: ['aleph', 'alephTest'] // A0 has distinct tokenomics
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
export const _STAKING_ERA_LENGTH_MAP = {
|
|
@@ -15,7 +15,7 @@ export default class AuthRequestHandler {
|
|
|
15
15
|
private readonly evmChainSubject;
|
|
16
16
|
readonly authSubjectV2: BehaviorSubject<AuthorizeRequest[]>;
|
|
17
17
|
constructor(requestService: RequestService, chainService: ChainService, keyringService: KeyringService);
|
|
18
|
-
|
|
18
|
+
stripUrl(url: string): string;
|
|
19
19
|
private getAddressList;
|
|
20
20
|
get numAuthRequestsV2(): number;
|
|
21
21
|
private get allAuthRequestsV2();
|
|
@@ -14,6 +14,7 @@ export default class RequestService {
|
|
|
14
14
|
constructor(chainService: ChainService, settingService: SettingService, keyringService: KeyringService);
|
|
15
15
|
get numAllRequests(): number;
|
|
16
16
|
updateIconV2(shouldClose?: boolean): void;
|
|
17
|
+
stripUrl(url: string): string;
|
|
17
18
|
getAddressList(value?: boolean): Record<string, boolean>;
|
|
18
19
|
get popup(): number[];
|
|
19
20
|
popupClose(): void;
|
|
@@ -35,6 +35,9 @@ export default class RequestService {
|
|
|
35
35
|
updateIconV2(shouldClose) {
|
|
36
36
|
this.#popupHandler.updateIconV2(shouldClose);
|
|
37
37
|
}
|
|
38
|
+
stripUrl(url) {
|
|
39
|
+
return this.#authRequestHandler.stripUrl(url);
|
|
40
|
+
}
|
|
38
41
|
getAddressList(value = false) {
|
|
39
42
|
const addressList = Object.keys(this.keyringService.accounts);
|
|
40
43
|
return addressList.reduce((addressList, v) => ({
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { RequestSettingsType } from '@subwallet/extension-base/background/KoniTypes';
|
|
1
|
+
import { PassPhishing, RequestSettingsType } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
2
|
import { Subject } from 'rxjs';
|
|
3
3
|
export default class SettingService {
|
|
4
4
|
private readonly settingsStore;
|
|
5
|
+
private readonly passPhishingStore;
|
|
5
6
|
getSubject(): Subject<RequestSettingsType>;
|
|
6
7
|
getSettings(update: (value: RequestSettingsType) => void): void;
|
|
7
8
|
setSettings(data: RequestSettingsType, callback?: () => void): void;
|
|
9
|
+
passPhishingSubject(): Subject<Record<string, PassPhishing>>;
|
|
10
|
+
getPassPhishingList(update: (value: Record<string, PassPhishing>) => void): void;
|
|
11
|
+
setPassPhishing(data: Record<string, PassPhishing>, callback?: () => void): void;
|
|
8
12
|
resetWallet(): void;
|
|
9
13
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import PassPhishingStore from '@subwallet/extension-base/stores/PassPhishingStore';
|
|
4
5
|
import SettingsStore from '@subwallet/extension-base/stores/Settings';
|
|
5
6
|
import { DEFAULT_SETTING } from "./constants.js";
|
|
6
7
|
export default class SettingService {
|
|
7
8
|
settingsStore = new SettingsStore();
|
|
9
|
+
passPhishingStore = new PassPhishingStore();
|
|
8
10
|
getSubject() {
|
|
9
11
|
return this.settingsStore.getSubject();
|
|
10
12
|
}
|
|
@@ -20,7 +22,19 @@ export default class SettingService {
|
|
|
20
22
|
setSettings(data, callback) {
|
|
21
23
|
this.settingsStore.set('Settings', data, callback);
|
|
22
24
|
}
|
|
25
|
+
passPhishingSubject() {
|
|
26
|
+
return this.passPhishingStore.getSubject();
|
|
27
|
+
}
|
|
28
|
+
getPassPhishingList(update) {
|
|
29
|
+
this.passPhishingStore.get('PassPhishing', value => {
|
|
30
|
+
update(value || {});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
setPassPhishing(data, callback) {
|
|
34
|
+
this.passPhishingStore.set('PassPhishing', data, callback);
|
|
35
|
+
}
|
|
23
36
|
resetWallet() {
|
|
24
37
|
this.settingsStore.set('Settings', DEFAULT_SETTING);
|
|
38
|
+
this.passPhishingStore.set('PassPhishing', {});
|
|
25
39
|
}
|
|
26
40
|
}
|
|
@@ -145,7 +145,7 @@ export default class DatabaseService {
|
|
|
145
145
|
}
|
|
146
146
|
async cleanUpNft(chain, owner, collectionIds, nftIds, ownNothing) {
|
|
147
147
|
if (ownNothing) {
|
|
148
|
-
return this.stores.nft.deleteNftsByChainAndOwner(chain, reformatAddress(owner, 42));
|
|
148
|
+
return this.stores.nft.deleteNftsByChainAndOwner(chain, reformatAddress(owner, 42), collectionIds);
|
|
149
149
|
}
|
|
150
150
|
return this.stores.nft.cleanUpNfts(chain, reformatAddress(owner, 42), collectionIds, nftIds);
|
|
151
151
|
}
|
|
@@ -5,7 +5,7 @@ export default class NftStore extends BaseStoreWithAddressAndChain<INft> {
|
|
|
5
5
|
getNft(addresses: string[], chainList?: string[]): import("dexie").PromiseExtended<INft[]>;
|
|
6
6
|
subscribeNft(addresses: string[], chainList?: string[]): import("dexie").Observable<INft[]>;
|
|
7
7
|
cleanUpNfts(chain: string, address: string, collectionIds: string[], nftIds: string[]): import("dexie").PromiseExtended<number>;
|
|
8
|
-
deleteNftsByChainAndOwner(chain: string, address: string): import("dexie").PromiseExtended<number>;
|
|
8
|
+
deleteNftsByChainAndOwner(chain: string, address: string, collectionIds: string[]): import("dexie").PromiseExtended<number>;
|
|
9
9
|
deleteNftByAddress(addresses: string[]): import("dexie").PromiseExtended<number>;
|
|
10
10
|
deleteNftItem(chain: string, addresses: string[], nftItem: NftItem): import("dexie").PromiseExtended<number>;
|
|
11
11
|
deleteNftsByCollection(chain: string, collectionId: string): import("dexie").PromiseExtended<number>;
|
|
@@ -19,13 +19,13 @@ export default class NftStore extends BaseStoreWithAddressAndChain {
|
|
|
19
19
|
return this.table.where({
|
|
20
20
|
address,
|
|
21
21
|
chain
|
|
22
|
-
}).and(nft =>
|
|
22
|
+
}).and(nft => collectionIds.includes(nft.collectionId) && !nftIds.includes(nft.id)).delete();
|
|
23
23
|
}
|
|
24
|
-
deleteNftsByChainAndOwner(chain, address) {
|
|
24
|
+
deleteNftsByChainAndOwner(chain, address, collectionIds) {
|
|
25
25
|
return this.table.where({
|
|
26
26
|
address,
|
|
27
27
|
chain
|
|
28
|
-
}).delete();
|
|
28
|
+
}).and(nft => collectionIds.includes(nft.collectionId)).delete();
|
|
29
29
|
}
|
|
30
30
|
deleteNftByAddress(addresses) {
|
|
31
31
|
return this.table.where('address').anyOfIgnoreCase(addresses).delete();
|
|
@@ -122,7 +122,7 @@ export default class TransactionService {
|
|
|
122
122
|
} else {
|
|
123
123
|
var _pair$meta;
|
|
124
124
|
if ((_pair$meta = pair.meta) !== null && _pair$meta !== void 0 && _pair$meta.isReadOnly) {
|
|
125
|
-
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'This is
|
|
125
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'This is watch-only account'));
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PassPhishing } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
|
+
import SubscribableStore from '@subwallet/extension-base/stores/SubscribableStore';
|
|
3
|
+
export default class PassPhishingStore extends SubscribableStore<Record<string, PassPhishing>> {
|
|
4
|
+
constructor();
|
|
5
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { EXTENSION_PREFIX } from '@subwallet/extension-base/defaults';
|
|
5
|
+
import SubscribableStore from '@subwallet/extension-base/stores/SubscribableStore';
|
|
6
|
+
export default class PassPhishingStore extends SubscribableStore {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(EXTENSION_PREFIX ? `${EXTENSION_PREFIX}subwallet-pass-phishing-list` : null);
|
|
9
|
+
}
|
|
10
|
+
}
|