@subwallet/extension-base 1.2.26-0 → 1.2.28-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/background/KoniTypes.d.ts +7 -8
  2. package/cjs/constants/index.js +6 -3
  3. package/cjs/core/logic-validation/request.js +160 -23
  4. package/cjs/core/substrate/assets-pallet.js +34 -18
  5. package/cjs/core/substrate/foreign-asset-pallet.js +2 -9
  6. package/cjs/core/substrate/xcm-parser.js +2 -1
  7. package/cjs/koni/api/staking/bonding/utils.js +1 -0
  8. package/cjs/koni/background/handlers/State.js +35 -66
  9. package/cjs/koni/background/handlers/Tabs.js +96 -23
  10. package/cjs/packageInfo.js +1 -1
  11. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +21 -1
  12. package/cjs/services/chain-service/index.js +1 -1
  13. package/cjs/services/earning-service/constants/chains.js +1 -3
  14. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +31 -25
  15. package/cjs/services/earning-service/handlers/nomination-pool/index.js +1 -2
  16. package/cjs/services/mkt-campaign-service/index.js +30 -6
  17. package/cjs/services/request-service/handler/EvmRequestHandler.js +0 -1
  18. package/cjs/services/wallet-connect-service/index.js +25 -1
  19. package/constants/index.d.ts +1 -0
  20. package/constants/index.js +1 -0
  21. package/core/logic-validation/request.d.ts +22 -1
  22. package/core/logic-validation/request.js +154 -23
  23. package/core/substrate/assets-pallet.d.ts +7 -3
  24. package/core/substrate/assets-pallet.js +29 -17
  25. package/core/substrate/foreign-asset-pallet.d.ts +3 -3
  26. package/core/substrate/foreign-asset-pallet.js +2 -9
  27. package/core/substrate/types.d.ts +5 -1
  28. package/core/substrate/xcm-parser.js +2 -1
  29. package/koni/api/staking/bonding/utils.js +1 -0
  30. package/koni/background/handlers/State.d.ts +0 -1
  31. package/koni/background/handlers/State.js +19 -49
  32. package/koni/background/handlers/Tabs.d.ts +1 -0
  33. package/koni/background/handlers/Tabs.js +77 -6
  34. package/package.json +13 -11
  35. package/packageInfo.js +1 -1
  36. package/services/balance-service/helpers/subscribe/substrate/index.js +22 -2
  37. package/services/chain-service/index.js +1 -1
  38. package/services/earning-service/constants/chains.d.ts +0 -1
  39. package/services/earning-service/constants/chains.js +0 -1
  40. package/services/earning-service/handlers/native-staking/relay-chain.js +32 -26
  41. package/services/earning-service/handlers/nomination-pool/index.js +1 -2
  42. package/services/mkt-campaign-service/index.js +30 -6
  43. package/services/mkt-campaign-service/types.d.ts +2 -0
  44. package/services/request-service/handler/EvmRequestHandler.js +0 -1
  45. package/services/wallet-connect-service/index.js +24 -1
  46. package/types/yield/info/chain/target.d.ts +4 -0
@@ -8,7 +8,7 @@ import { createSubscription, unsubscribe } from '@subwallet/extension-base/backg
8
8
  import { EvmProviderErrorType } from '@subwallet/extension-base/background/KoniTypes';
9
9
  import RequestBytesSign from '@subwallet/extension-base/background/RequestBytesSign';
10
10
  import RequestExtrinsicSign from '@subwallet/extension-base/background/RequestExtrinsicSign';
11
- import { ALL_ACCOUNT_KEY, CRON_GET_API_MAP_STATUS } from '@subwallet/extension-base/constants';
11
+ import { ALL_ACCOUNT_KEY, CRON_GET_API_MAP_STATUS, PERMISSIONS_TO_REVOKE } from '@subwallet/extension-base/constants';
12
12
  import { generateValidationProcess, validationAuthMiddleware } from '@subwallet/extension-base/core/logic-validation';
13
13
  import { PHISHING_PAGE_REDIRECT } from '@subwallet/extension-base/defaults';
14
14
  import { _CHAIN_VALIDATION_ERROR } from '@subwallet/extension-base/services/chain-service/handler/types';
@@ -17,7 +17,8 @@ import { DEFAULT_CHAIN_PATROL_ENABLE } from '@subwallet/extension-base/services/
17
17
  import { canDerive, getEVMChainInfo, stripUrl } from '@subwallet/extension-base/utils';
18
18
  import Web3 from 'web3';
19
19
  import { checkIfDenied } from '@polkadot/phishing';
20
- import { isNumber } from '@polkadot/util';
20
+ import { isArray, isNumber } from '@polkadot/util';
21
+ import { isEthereumAddress } from '@polkadot/util-crypto';
21
22
  function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthType) {
22
23
  const accountSelected = authInfo ? authInfo.isAllowed ? Object.keys(authInfo.isAllowedMap).filter(address => authInfo.isAllowedMap[address]) : [] : [];
23
24
  let authTypeFilter = ({
@@ -246,8 +247,6 @@ export default class KoniTabs {
246
247
  }, id, port) {
247
248
  const cb = createSubscription(id, port);
248
249
  const authInfoSubject = this.#koniState.requestService.subscribeAuthorizeUrlSubject;
249
-
250
- // Update unsubscribe from @polkadot/extension-base
251
250
  this.#accountSubs[id] = {
252
251
  subscription: authInfoSubject.subscribe(infos => {
253
252
  this.getAuthInfo(url, infos).then(authInfo => {
@@ -258,6 +257,8 @@ export default class KoniTabs {
258
257
  }),
259
258
  url
260
259
  };
260
+
261
+ // Update unsubscribe from @polkadot/extension-base
261
262
  port.onDisconnect.addListener(() => {
262
263
  this.accountsUnsubscribe(url, {
263
264
  id
@@ -380,6 +381,74 @@ export default class KoniTabs {
380
381
  date: new Date().getTime()
381
382
  }];
382
383
  }
384
+ async revokePermissions(url, id, {
385
+ params
386
+ }) {
387
+ if (!params || !isArray(params) || params.length === 0) {
388
+ throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'No list of permissions found to revoke in the parameters.');
389
+ }
390
+
391
+ // Example of a request in MetaMask wallet
392
+ // await window.ethereum.request({
393
+ // "method": "wallet_revokePermissions",
394
+ // "params": [
395
+ // {
396
+ // "eth_accounts": {}
397
+ // }
398
+ // ]
399
+ // });
400
+ // Doc: https://docs.metamask.io/wallet/reference/wallet_revokepermissions/
401
+
402
+ const permissions = new Set(Object.keys(params[0]).filter(permission => PERMISSIONS_TO_REVOKE.includes(permission)));
403
+ const permissionPromise = async permission => {
404
+ if (permission === 'eth_accounts') {
405
+ return new Promise(resolve => {
406
+ this.#koniState.getAuthorize(value => {
407
+ const urlStripped = stripUrl(url);
408
+ if (value && value[urlStripped]) {
409
+ const {
410
+ accountAuthType,
411
+ isAllowedMap
412
+ } = {
413
+ ...value[urlStripped]
414
+ };
415
+ if (!accountAuthType) {
416
+ resolve();
417
+ }
418
+ switch (accountAuthType) {
419
+ case 'substrate':
420
+ resolve();
421
+ break;
422
+ case 'evm':
423
+ delete value[urlStripped];
424
+ break;
425
+ case 'both':
426
+ {
427
+ value[urlStripped].isAllowedMap = Object.entries(isAllowedMap).reduce((allowedMap, [address, value]) => {
428
+ if (isEthereumAddress(address)) {
429
+ allowedMap[address] = false;
430
+ } else {
431
+ allowedMap[address] = value;
432
+ }
433
+ return allowedMap;
434
+ }, {});
435
+ value[urlStripped].accountAuthType = 'substrate';
436
+ break;
437
+ }
438
+ }
439
+ this.#koniState.setAuthorize(value, () => {
440
+ resolve();
441
+ });
442
+ } else {
443
+ resolve();
444
+ }
445
+ });
446
+ });
447
+ }
448
+ };
449
+ await Promise.all(Array.from(permissions).map(permissionPromise));
450
+ return null;
451
+ }
383
452
  async switchEvmChain(id, url, {
384
453
  params
385
454
  }) {
@@ -831,6 +900,8 @@ export default class KoniTabs {
831
900
  return await this.getEvmPermission(url, id);
832
901
  case 'wallet_getPermissions':
833
902
  return await this.getEvmPermission(url, id);
903
+ case 'wallet_revokePermissions':
904
+ return await this.revokePermissions(url, id, request);
834
905
  case 'wallet_addEthereumChain':
835
906
  return await this.addEvmChain(id, url, request);
836
907
  case 'wallet_switchEthereumChain':
@@ -870,7 +941,7 @@ export default class KoniTabs {
870
941
  return true;
871
942
  }
872
943
  isEvmPublicRequest(type, request) {
873
- return type === 'evm(request)' && ['eth_chainId', 'net_version'].includes(request === null || request === void 0 ? void 0 : request.method);
944
+ return type === 'evm(request)' && ['eth_chainId', 'net_version', 'wallet_requestPermissions', 'wallet_getPermissions'].includes(request === null || request === void 0 ? void 0 : request.method) || type === 'evm(events.subscribe)';
874
945
  }
875
946
  async addPspToken(id, url, {
876
947
  genesisHash,
@@ -936,7 +1007,7 @@ export default class KoniTabs {
936
1007
 
937
1008
  // Wait for account ready and chain ready
938
1009
  await Promise.all([this.#koniState.eventService.waitAccountReady, this.#koniState.eventService.waitChainReady]);
939
- if (type !== 'pub(authorize.tabV2)' && !this.isEvmPublicRequest(type, request)) {
1010
+ if (!['pub(authorize.tabV2)', 'pub(accounts.subscribeV2)'].includes(type) && !this.isEvmPublicRequest(type, request)) {
940
1011
  await this.#koniState.ensureUrlAuthorizedV2(url).catch(e => {
941
1012
  if (type.startsWith('evm')) {
942
1013
  throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, e.message);
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.2.26-0",
20
+ "version": "1.2.28-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -2046,6 +2046,7 @@
2046
2046
  "@galacticcouncil/sdk": "^2.1.0",
2047
2047
  "@gear-js/api": "^0.38.1",
2048
2048
  "@json-rpc-tools/utils": "^1.7.6",
2049
+ "@metamask/eth-sig-util": "^7.0.3",
2049
2050
  "@metamask/safe-event-emitter": "^2.0.0",
2050
2051
  "@metaverse-network-sdk/type-definitions": "^0.0.1-13",
2051
2052
  "@oak-foundation/types": "^0.0.23",
@@ -2069,17 +2070,17 @@
2069
2070
  "@reduxjs/toolkit": "^1.9.1",
2070
2071
  "@sora-substrate/type-definitions": "^1.17.7",
2071
2072
  "@substrate/connect": "^0.8.9",
2072
- "@subwallet/chain-list": "0.2.82",
2073
- "@subwallet/extension-base": "^1.2.26-0",
2074
- "@subwallet/extension-chains": "^1.2.26-0",
2075
- "@subwallet/extension-dapp": "^1.2.26-0",
2076
- "@subwallet/extension-inject": "^1.2.26-0",
2077
- "@subwallet/keyring": "^0.1.5",
2078
- "@subwallet/ui-keyring": "^0.1.5",
2073
+ "@subwallet/chain-list": "0.2.84",
2074
+ "@subwallet/extension-base": "^1.2.28-0",
2075
+ "@subwallet/extension-chains": "^1.2.28-0",
2076
+ "@subwallet/extension-dapp": "^1.2.28-0",
2077
+ "@subwallet/extension-inject": "^1.2.28-0",
2078
+ "@subwallet/keyring": "^0.1.6",
2079
+ "@subwallet/ui-keyring": "^0.1.6",
2079
2080
  "@walletconnect/keyvaluestorage": "^1.1.1",
2080
- "@walletconnect/sign-client": "^2.13.1",
2081
- "@walletconnect/types": "^2.13.1",
2082
- "@walletconnect/utils": "^2.13.1",
2081
+ "@walletconnect/sign-client": "^2.14.0",
2082
+ "@walletconnect/types": "^2.14.0",
2083
+ "@walletconnect/utils": "^2.14.0",
2083
2084
  "avail-js-sdk": "^0.2.12",
2084
2085
  "axios": "^1.6.2",
2085
2086
  "bignumber.js": "^9.1.1",
@@ -2097,6 +2098,7 @@
2097
2098
  "graphql": "^16.8.1",
2098
2099
  "i18next": "^21.9.2",
2099
2100
  "is-buffer": "^2.0.5",
2101
+ "joi": "^17.13.3",
2100
2102
  "json-rpc-engine": "^6.1.0",
2101
2103
  "manta-extension-sdk": "^1.1.0",
2102
2104
  "moment": "^2.29.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.2.26-0'
10
+ version: '1.2.28-0'
11
11
  };
@@ -4,7 +4,7 @@
4
4
  import { _AssetType } from '@subwallet/chain-list/types';
5
5
  import { APIItemState } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import { SUB_TOKEN_REFRESH_BALANCE_INTERVAL } from '@subwallet/extension-base/constants';
7
- import { _getAssetsPalletLockedBalance, _getAssetsPalletTransferable } from '@subwallet/extension-base/core/substrate/assets-pallet';
7
+ import { _getAssetsPalletLocked, _getAssetsPalletTransferable } from '@subwallet/extension-base/core/substrate/assets-pallet';
8
8
  import { _getForeignAssetPalletLockedBalance, _getForeignAssetPalletTransferable } from '@subwallet/extension-base/core/substrate/foreign-asset-pallet';
9
9
  import { _getTotalStakeInNominationPool } from '@subwallet/extension-base/core/substrate/nominationpools-pallet';
10
10
  import { _getOrmlTokensPalletLockedBalance, _getOrmlTokensPalletTransferable } from '@subwallet/extension-base/core/substrate/ormlTokens-pallet';
@@ -181,6 +181,16 @@ const subscribeForeignAssetBalance = async ({
181
181
  const balances = rs[foreignAssetsAccountKey];
182
182
  const items = balances.map((_balance, index) => {
183
183
  const balanceInfo = _balance;
184
+ if (!balanceInfo) {
185
+ // no balance info response
186
+ return {
187
+ address: addresses[index],
188
+ tokenSlug: tokenInfo.slug,
189
+ free: '0',
190
+ locked: '0',
191
+ state: APIItemState.READY
192
+ };
193
+ }
184
194
  const transferableBalance = _getForeignAssetPalletTransferable(balanceInfo, _getAssetExistentialDeposit(tokenInfo), extrinsicType);
185
195
  const totalLockedFromTransfer = _getForeignAssetPalletLockedBalance(balanceInfo);
186
196
  return {
@@ -351,8 +361,18 @@ const subscribeAssetsAccountPallet = async ({
351
361
  const balances = rs[assetsAccountKey];
352
362
  const items = balances.map((_balance, index) => {
353
363
  const balanceInfo = _balance;
364
+ if (!balanceInfo) {
365
+ // no balance info response
366
+ return {
367
+ address: addresses[index],
368
+ tokenSlug: tokenInfo.slug,
369
+ free: '0',
370
+ locked: '0',
371
+ state: APIItemState.READY
372
+ };
373
+ }
354
374
  const transferableBalance = _getAssetsPalletTransferable(balanceInfo, _getAssetExistentialDeposit(tokenInfo), extrinsicType);
355
- const totalLockedFromTransfer = _getAssetsPalletLockedBalance(balanceInfo);
375
+ const totalLockedFromTransfer = _getAssetsPalletLocked(balanceInfo);
356
376
  return {
357
377
  address: addresses[index],
358
378
  tokenSlug: tokenInfo.slug,
@@ -18,7 +18,7 @@ import { logger as createLogger } from '@polkadot/util/logger';
18
18
  const filterChainInfoMap = (data, ignoredChains) => {
19
19
  return Object.fromEntries(Object.entries(data).filter(([slug, info]) => !info.bitcoinInfo && !ignoredChains.includes(slug)));
20
20
  };
21
- const ignoredList = ['bevm', 'bevmTest', 'bevm_testnet', 'layerEdge_testnet', 'merlinEvm', 'botanixEvmTest', 'syscoin_evm', 'syscoin_evm_testnet', 'rollux_evm', 'rollux_testnet', 'boolAlpha', 'boolBeta_testnet', 'core', 'satoshivm', 'satoshivm_testnet', 'ton', 'ton_testnet'];
21
+ const ignoredList = ['bevm', 'bevmTest', 'bevm_testnet', 'layerEdge_testnet', 'merlinEvm', 'botanixEvmTest', 'syscoin_evm', 'syscoin_evm_testnet', 'rollux_evm', 'rollux_testnet', 'boolAlpha', 'boolBeta_testnet', 'core', 'satoshivm', 'satoshivm_testnet', 'ton', 'ton_testnet', 'storyPartner_testnet'];
22
22
  const filterAssetInfoMap = (chainInfo, assets) => {
23
23
  return Object.fromEntries(Object.entries(assets).filter(([, info]) => chainInfo[info.originChain]));
24
24
  };
@@ -13,7 +13,6 @@ export declare const _STAKING_CHAIN_GROUP: {
13
13
  krest_network: string[];
14
14
  manta: string[];
15
15
  };
16
- export declare const _UPDATED_RUNTIME_STAKING_GROUP: string[];
17
16
  export declare const MaxEraRewardPointsEras = 14;
18
17
  export declare const ST_LIQUID_TOKEN_ABI: Record<string, any>;
19
18
  export declare const MANTA_VALIDATOR_POINTS_PER_BLOCK = 20;
@@ -18,7 +18,6 @@ export const _STAKING_CHAIN_GROUP = {
18
18
  krest_network: ['krest_network'],
19
19
  manta: ['manta_network']
20
20
  };
21
- export const _UPDATED_RUNTIME_STAKING_GROUP = ['kusama', 'polkadot', 'westend', 'availTuringTest', 'avail_mainnet', 'dentnet'];
22
21
  export const MaxEraRewardPointsEras = 14;
23
22
 
24
23
  // eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-unsafe-assignment
@@ -6,7 +6,7 @@ import { BasicTxErrorType, ExtrinsicType, StakingTxErrorType } from '@subwallet/
6
6
  import { calculateAlephZeroValidatorReturn, calculateChainStakedReturnV2, calculateInflation, calculateTernoaValidatorReturn, calculateValidatorStakedReturn, getAvgValidatorEraReward, getCommission, getMaxValidatorErrorMessage, getMinStakeErrorMessage, getRelayBlockedValidatorList, getRelayEraRewardMap, getRelayMaxNominations, getRelayTopValidatorByPoints, getRelayValidatorPointsMap, getRelayWaitingValidatorList, getSupportedDaysByHistoryDepth } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
7
7
  import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
8
8
  import { _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
9
- import { _STAKING_CHAIN_GROUP, _UPDATED_RUNTIME_STAKING_GROUP, MaxEraRewardPointsEras } from '@subwallet/extension-base/services/earning-service/constants';
9
+ import { _STAKING_CHAIN_GROUP, MaxEraRewardPointsEras } from '@subwallet/extension-base/services/earning-service/constants';
10
10
  import { applyDecimal, parseIdentity } from '@subwallet/extension-base/services/earning-service/utils';
11
11
  import { EarningStatus, UnstakingStatus } from '@subwallet/extension-base/types';
12
12
  import { balanceFormatter, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
@@ -192,7 +192,7 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
192
192
  let nominationStatus = EarningStatus.NOT_EARNING;
193
193
  let eraStakerOtherList = [];
194
194
  let identity;
195
- if (_UPDATED_RUNTIME_STAKING_GROUP.includes(this.chain)) {
195
+ if (substrateApi.api.query.staking.erasStakersPaged) {
196
196
  // todo: review all relaychains later
197
197
  const [[_identity], _eraStaker] = await Promise.all([parseIdentity(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress)]);
198
198
  identity = _identity;
@@ -300,20 +300,19 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
300
300
  const maxEraRewardPointsEras = MaxEraRewardPointsEras;
301
301
  const endEraForPoints = parseInt(activeEra) - 1;
302
302
  const startEraForPoints = Math.max(endEraForPoints - maxEraRewardPointsEras + 1, 0);
303
- let _eraStakersPromise;
304
- if (chainApi.api.query.staking.erasStakersOverview) {
305
- // todo: review all relaychains later
306
- _eraStakersPromise = chainApi.api.query.staking.erasStakersOverview.entries(parseInt(currentEra));
307
- } else {
308
- _eraStakersPromise = chainApi.api.query.staking.erasStakers.entries(parseInt(currentEra));
309
- }
303
+ const _eraStakersPromise = chainApi.api.query.staking.erasStakersOverview // todo: review all relaychains later
304
+ ? chainApi.api.query.staking.erasStakersOverview.entries(parseInt(currentEra)) : chainApi.api.query.staking.erasStakers.entries(parseInt(currentEra));
310
305
  const [_totalEraStake, _eraStakers, _minBond, _stakingRewards, _validators, ..._eraRewardPoints] = await Promise.all([chainApi.api.query.staking.erasTotalStake(parseInt(currentEra)), _eraStakersPromise, chainApi.api.query.staking.minNominatorBond(), ((_chainApi$api$query$s = chainApi.api.query.stakingRewards) === null || _chainApi$api$query$s === void 0 ? void 0 : _chainApi$api$query$s.data) && chainApi.api.query.stakingRewards.data(), chainApi.api.query.staking.validators.entries(), chainApi.api.query.staking.erasRewardPoints.multi([...Array(maxEraRewardPointsEras).keys()].map(i => i + startEraForPoints))]);
311
306
  const eraRewardMap = getRelayEraRewardMap(_eraRewardPoints[0], startEraForPoints);
312
307
  const validatorPointsMap = getRelayValidatorPointsMap(eraRewardMap);
313
308
  const topValidatorList = getRelayTopValidatorByPoints(validatorPointsMap);
314
- const validators = _validators;
315
- const blockedValidatorList = getRelayBlockedValidatorList(validators);
316
- const waitingValidatorList = getRelayWaitingValidatorList(validators);
309
+ const allValidatorList = _validators;
310
+
311
+ // todo: optimize naming for all filtered validatorList: all, block, waiting, selected, waiting but is not selected, waiting but is not blocked, ...
312
+ const blockedValidatorList = getRelayBlockedValidatorList(allValidatorList);
313
+ const waitingValidatorList = getRelayWaitingValidatorList(allValidatorList); // all validators that are not blocked
314
+
315
+ // todo: improve handle waitingValidatorLedger
317
316
  const _waitingValidatorLedger = await chainApi.api.query.staking.ledger.multi(waitingValidatorList);
318
317
  const waitingValidatorLedger = {};
319
318
  if (_waitingValidatorLedger) {
@@ -327,7 +326,9 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
327
326
  const maxNominatorRewarded = (chainApi.api.consts.staking.maxNominatorRewardedPerValidator || 0).toString();
328
327
  const bnTotalEraStake = new BN(_totalEraStake.toString());
329
328
  const minBond = _minBond.toPrimitive();
330
- const [totalStakeMap, allValidatorAddresses, validatorInfoList] = this.parseEraStakerData(_eraStakers, blockedValidatorList, waitingValidatorLedger, topValidatorList, validatorPointsMap, minBond, maxNominatorRewarded, unlimitedNominatorRewarded);
329
+ const [totalStakeMap, allValidatorAddresses, allValidatorInfo] = this.parseEraStakerData(_eraStakers, blockedValidatorList, waitingValidatorLedger, topValidatorList, validatorPointsMap, minBond, maxNominatorRewarded, unlimitedNominatorRewarded);
330
+ const currentSelectedValidatorList = allValidatorInfo.currentSelectedValidatorList;
331
+ const allValidatorInfoList = [...currentSelectedValidatorList, ...allValidatorInfo.waitingValidatorList];
331
332
  const extraInfoMap = {};
332
333
  await Promise.all(allValidatorAddresses.map(async address => {
333
334
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
@@ -341,17 +342,19 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
341
342
  };
342
343
  }));
343
344
  const decimals = this.nativeToken.decimals || 0;
344
- const bnAvgStake = applyDecimal(bnTotalEraStake.divn(validatorInfoList.length), decimals);
345
- for (const validator of validatorInfoList) {
345
+ const bnAvgStake = applyDecimal(bnTotalEraStake.divn(currentSelectedValidatorList.length), decimals);
346
+ for (const validator of allValidatorInfoList) {
346
347
  const commissionString = extraInfoMap[validator.address].commission;
347
348
  const commission = getCommission(commissionString);
348
- validator.expectedReturn = this.getValidatorExpectedReturn(this.chain, validator, poolInfo.statistic.totalApy, commission, _stakingRewards, allValidatorAddresses, decimals, totalStakeMap, bnAvgStake);
349
+
350
+ // the waiting validator is missing info for calculating APY
351
+ validator.expectedReturn = currentSelectedValidatorList.includes(validator) ? this.getValidatorExpectedReturn(this.chain, validator, poolInfo.statistic.totalApy, commission, _stakingRewards, allValidatorAddresses, decimals, totalStakeMap, bnAvgStake) : 0;
349
352
  validator.commission = commission;
350
353
  validator.blocked = extraInfoMap[validator.address].blocked;
351
354
  validator.identity = extraInfoMap[validator.address].identity;
352
355
  validator.isVerified = extraInfoMap[validator.address].isVerified;
353
356
  }
354
- return validatorInfoList;
357
+ return allValidatorInfoList;
355
358
  }
356
359
  getValidatorExpectedReturn(chain, validator, totalApy, commission, _stakingRewards, allValidatorAddresses, decimals, totalStakeMap, bnAvgStake) {
357
360
  if (_STAKING_CHAIN_GROUP.aleph.includes(chain)) {
@@ -370,10 +373,13 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
370
373
  }
371
374
  }
372
375
  }
373
- parseEraStakerData(_eraStakers, blockedValidatorList, waitingValidatorList, topValidatorList, validatorPointsMap, minBond, maxNominatorRewarded, unlimitedNominatorRewarded) {
376
+ parseEraStakerData(_eraStakers, blockedValidatorList, waitingValidatorLedger, topValidatorList, validatorPointsMap, minBond, maxNominatorRewarded, unlimitedNominatorRewarded) {
374
377
  const totalStakeMap = {};
375
378
  const allValidatorAddresses = [];
376
- const validatorInfoList = [];
379
+ const allValidatorInfo = {
380
+ currentSelectedValidatorList: [],
381
+ waitingValidatorList: []
382
+ };
377
383
  for (const item of _eraStakers) {
378
384
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
379
385
  const rawValidatorInfo = item[0].toHuman();
@@ -391,7 +397,7 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
391
397
  const otherStake = bnTotalStake.sub(bnOwnStake);
392
398
  totalStakeMap[validatorAddress] = bnTotalStake;
393
399
  let nominatorCount = 0;
394
- if (_UPDATED_RUNTIME_STAKING_GROUP.includes(this.chain)) {
400
+ if (rawValidatorStat.nominatorCount) {
395
401
  nominatorCount = rawValidatorStat.nominatorCount;
396
402
  } else {
397
403
  if ('others' in rawValidatorStat) {
@@ -402,7 +408,7 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
402
408
  }
403
409
  }
404
410
  allValidatorAddresses.push(validatorAddress);
405
- validatorInfoList.push({
411
+ allValidatorInfo.currentSelectedValidatorList.push({
406
412
  address: validatorAddress,
407
413
  totalStake: bnTotalStake.toString(),
408
414
  ownStake: bnOwnStake.toString(),
@@ -420,13 +426,13 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
420
426
  });
421
427
  }
422
428
  }
423
- for (const waitingValidator of Object.keys(waitingValidatorList)) {
429
+ for (const waitingValidator of Object.keys(waitingValidatorLedger)) {
424
430
  if (!allValidatorAddresses.includes(waitingValidator)) {
425
431
  allValidatorAddresses.push(waitingValidator);
426
- validatorInfoList.push({
432
+ allValidatorInfo.waitingValidatorList.push({
427
433
  address: waitingValidator,
428
- totalStake: waitingValidatorList[waitingValidator],
429
- ownStake: waitingValidatorList[waitingValidator],
434
+ totalStake: waitingValidatorLedger[waitingValidator],
435
+ ownStake: waitingValidatorLedger[waitingValidator],
430
436
  otherStake: '0',
431
437
  nominatorCount: 0,
432
438
  // to be added later
@@ -441,7 +447,7 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
441
447
  });
442
448
  }
443
449
  }
444
- return [totalStakeMap, allValidatorAddresses, validatorInfoList];
450
+ return [totalStakeMap, allValidatorAddresses, allValidatorInfo];
445
451
  }
446
452
  /* Get pool targets */
447
453
 
@@ -6,7 +6,6 @@ import { APIItemState, BasicTxErrorType, ChainType, ExtrinsicType, StakingTxErro
6
6
  import { calculateChainStakedReturnV2, calculateInflation, getAvgValidatorEraReward, getExistUnstakeErrorMessage, getMinStakeErrorMessage, getSupportedDaysByHistoryDepth, parsePoolStashAddress } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
7
7
  import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
8
8
  import { _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
9
- import { _UPDATED_RUNTIME_STAKING_GROUP } from '@subwallet/extension-base/services/earning-service/constants';
10
9
  import { EarningStatus, UnstakingStatus, YieldPoolType, YieldStepType } from '@subwallet/extension-base/types';
11
10
  import { balanceFormatter, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
12
11
  import BigN from 'bignumber.js';
@@ -162,7 +161,7 @@ export default class NominationPoolHandler extends BasePoolHandler {
162
161
  const validatorList = nominations.targets;
163
162
  await Promise.all(validatorList.map(async validatorAddress => {
164
163
  let eraStakerOtherList = [];
165
- if (_UPDATED_RUNTIME_STAKING_GROUP.includes(this.chain)) {
164
+ if (substrateApi.api.query.staking.erasStakersPaged) {
166
165
  // todo: review all relaychains later
167
166
  const _eraStaker = await substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress);
168
167
  eraStakerOtherList = _eraStaker.flatMap(paged => paged[1].toPrimitive().others);
@@ -239,35 +239,59 @@ export default class MktCampaignService {
239
239
  const isValidArr = conditionBalance.map(condition => {
240
240
  return conditionMap[JSON.stringify(condition)];
241
241
  });
242
- isPassValidation.push(isValidArr.some(i => i));
242
+ if (item.comparison_operator === 'AND') {
243
+ isPassValidation.push(isValidArr.every(i => i));
244
+ } else {
245
+ isPassValidation.push(isValidArr.some(i => i));
246
+ }
243
247
  }
244
248
  if (conditionEarning && conditionEarning.length) {
245
249
  const isValidArr = conditionEarning.map(condition => {
246
250
  return conditionMap[JSON.stringify(condition)];
247
251
  });
248
- isPassValidation.push(isValidArr.some(i => i));
252
+ if (item.comparison_operator === 'AND') {
253
+ isPassValidation.push(isValidArr.every(i => i));
254
+ } else {
255
+ isPassValidation.push(isValidArr.some(i => i));
256
+ }
249
257
  }
250
258
  if (conditionNft && conditionNft.length) {
251
259
  const isValidArr = conditionNft.map(condition => {
252
260
  return conditionMap[JSON.stringify(condition)];
253
261
  });
254
- isPassValidation.push(isValidArr.some(i => i));
262
+ if (item.comparison_operator === 'AND') {
263
+ isPassValidation.push(isValidArr.every(i => i));
264
+ } else {
265
+ isPassValidation.push(isValidArr.some(i => i));
266
+ }
255
267
  }
256
268
  if (conditionCrowdloan && conditionCrowdloan.length) {
257
269
  const isValidArr = conditionCrowdloan.map(condition => {
258
270
  return conditionMap[JSON.stringify(condition)];
259
271
  });
260
- isPassValidation.push(isValidArr.some(i => i));
272
+ if (item.comparison_operator === 'AND') {
273
+ isPassValidation.push(isValidArr.every(i => i));
274
+ } else {
275
+ isPassValidation.push(isValidArr.some(i => i));
276
+ }
261
277
  }
262
278
  if (conditionHasMoney && conditionHasMoney.length) {
263
279
  const isValidArr = conditionHasMoney.map(condition => {
264
280
  return conditionMap[JSON.stringify(condition)];
265
281
  });
266
- isPassValidation.push(isValidArr.some(i => i));
282
+ if (item.comparison_operator === 'AND') {
283
+ isPassValidation.push(isValidArr.every(i => i));
284
+ } else {
285
+ isPassValidation.push(isValidArr.some(i => i));
286
+ }
267
287
  }
268
288
  }
269
289
  if (isPassValidation && isPassValidation.length) {
270
- return isPassValidation.some(_i => _i);
290
+ if (item.comparison_operator === 'AND') {
291
+ return isPassValidation.every(_i => _i);
292
+ } else {
293
+ return isPassValidation.some(_i => _i);
294
+ }
271
295
  } else {
272
296
  return true;
273
297
  }
@@ -82,6 +82,8 @@ export interface AppCommonData {
82
82
  position_params: PositionParam[];
83
83
  conditions: MktCampaignCondition;
84
84
  info?: AppBasicInfoData;
85
+ comparison_operator: 'AND' | 'OR';
86
+ locations: string[];
85
87
  }
86
88
  export interface AppPopupData extends AppCommonData {
87
89
  priority: number;
@@ -19,7 +19,6 @@ export default class EvmRequestHandler {
19
19
  confirmationsQueueSubject = new BehaviorSubject({
20
20
  addNetworkRequest: {},
21
21
  addTokenRequest: {},
22
- switchNetworkRequest: {},
23
22
  evmSignatureRequest: {},
24
23
  evmSendTransactionRequest: {},
25
24
  evmWatchTransactionRequest: {},
@@ -44,6 +44,7 @@ var _option = /*#__PURE__*/_classPrivateFieldLooseKey("option");
44
44
  var _updateSessions = /*#__PURE__*/_classPrivateFieldLooseKey("updateSessions");
45
45
  var _onSessionProposal = /*#__PURE__*/_classPrivateFieldLooseKey("onSessionProposal");
46
46
  var _onSessionRequest = /*#__PURE__*/_classPrivateFieldLooseKey("onSessionRequest");
47
+ var _onPingReply = /*#__PURE__*/_classPrivateFieldLooseKey("onPingReply");
47
48
  var _createListener = /*#__PURE__*/_classPrivateFieldLooseKey("createListener");
48
49
  var _removeListener = /*#__PURE__*/_classPrivateFieldLooseKey("removeListener");
49
50
  var _checkClient = /*#__PURE__*/_classPrivateFieldLooseKey("checkClient");
@@ -58,6 +59,9 @@ export default class WalletConnectService {
58
59
  Object.defineProperty(this, _createListener, {
59
60
  value: _createListener2
60
61
  });
62
+ Object.defineProperty(this, _onPingReply, {
63
+ value: _onPingReply2
64
+ });
61
65
  Object.defineProperty(this, _onSessionRequest, {
62
66
  value: _onSessionRequest2
63
67
  });
@@ -302,11 +306,30 @@ function _onSessionRequest2(requestEvent) {
302
306
  }).catch(console.error);
303
307
  }
304
308
  }
309
+ async function _onPingReply2({
310
+ topic
311
+ }) {
312
+ // Doc: https://specs.walletconnect.com/2.0/specs/clients/sign/session-events#session_ping
313
+
314
+ _classPrivateFieldLooseBase(this, _checkClient)[_checkClient]();
315
+ try {
316
+ var _requestSession$names, _requestSession$names2;
317
+ const requestSession = this.getSession(topic);
318
+ const sessionAccounts = (((_requestSession$names = requestSession.namespaces.eip155) === null || _requestSession$names === void 0 ? void 0 : _requestSession$names.accounts) || []).concat(((_requestSession$names2 = requestSession.namespaces.polkadot) === null || _requestSession$names2 === void 0 ? void 0 : _requestSession$names2.accounts) || []);
319
+ if (sessionAccounts.length > 0 && _classPrivateFieldLooseBase(this, _client)[_client]) {
320
+ await _classPrivateFieldLooseBase(this, _client)[_client].ping({
321
+ topic
322
+ });
323
+ }
324
+ } catch (e) {
325
+ console.error(e);
326
+ }
327
+ }
305
328
  function _createListener2() {
306
329
  var _classPrivateFieldLoo14, _classPrivateFieldLoo15, _classPrivateFieldLoo16, _classPrivateFieldLoo17, _classPrivateFieldLoo18, _classPrivateFieldLoo19;
307
330
  (_classPrivateFieldLoo14 = _classPrivateFieldLooseBase(this, _client)[_client]) === null || _classPrivateFieldLoo14 === void 0 ? void 0 : _classPrivateFieldLoo14.on('session_proposal', _classPrivateFieldLooseBase(this, _onSessionProposal)[_onSessionProposal].bind(this));
308
331
  (_classPrivateFieldLoo15 = _classPrivateFieldLooseBase(this, _client)[_client]) === null || _classPrivateFieldLoo15 === void 0 ? void 0 : _classPrivateFieldLoo15.on('session_request', _classPrivateFieldLooseBase(this, _onSessionRequest)[_onSessionRequest].bind(this));
309
- (_classPrivateFieldLoo16 = _classPrivateFieldLooseBase(this, _client)[_client]) === null || _classPrivateFieldLoo16 === void 0 ? void 0 : _classPrivateFieldLoo16.on('session_ping', data => console.log('ping', data));
332
+ (_classPrivateFieldLoo16 = _classPrivateFieldLooseBase(this, _client)[_client]) === null || _classPrivateFieldLoo16 === void 0 ? void 0 : _classPrivateFieldLoo16.on('session_ping', _classPrivateFieldLooseBase(this, _onPingReply)[_onPingReply].bind(this));
310
333
  (_classPrivateFieldLoo17 = _classPrivateFieldLooseBase(this, _client)[_client]) === null || _classPrivateFieldLoo17 === void 0 ? void 0 : _classPrivateFieldLoo17.on('session_event', data => console.log('event', data));
311
334
  (_classPrivateFieldLoo18 = _classPrivateFieldLooseBase(this, _client)[_client]) === null || _classPrivateFieldLoo18 === void 0 ? void 0 : _classPrivateFieldLoo18.on('session_update', data => console.log('update', data));
312
335
  (_classPrivateFieldLoo19 = _classPrivateFieldLooseBase(this, _client)[_client]) === null || _classPrivateFieldLoo19 === void 0 ? void 0 : _classPrivateFieldLoo19.on('session_delete', _classPrivateFieldLooseBase(this, _updateSessions)[_updateSessions].bind(this));
@@ -25,6 +25,10 @@ export interface ValidatorInfo {
25
25
  eraRewardPoint?: string;
26
26
  topQuartile?: boolean;
27
27
  }
28
+ export interface AllValidatorInfo {
29
+ currentSelectedValidatorList: ValidatorInfo[];
30
+ waitingValidatorList: ValidatorInfo[];
31
+ }
28
32
  export declare type YieldPoolTarget = NominationPoolInfo | ValidatorInfo;
29
33
  export interface RequestGetYieldPoolTargets {
30
34
  slug: string;