@subwallet/extension-base 1.0.2-1b → 1.0.2-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/background/KoniTypes.d.ts +34 -16
  2. package/background/KoniTypes.js +7 -6
  3. package/background/errors/TransactionError.js +1 -21
  4. package/cjs/background/KoniTypes.js +7 -6
  5. package/cjs/background/errors/TransactionError.js +0 -20
  6. package/cjs/constants/index.js +26 -8
  7. package/cjs/koni/api/dotsama/balance.js +224 -49
  8. package/cjs/koni/api/dotsama/transfer.js +29 -30
  9. package/cjs/koni/api/nft/acala_nft/index.js +1 -4
  10. package/cjs/koni/api/nft/bit.country/index.js +1 -4
  11. package/cjs/koni/api/nft/evm_nft/index.js +3 -7
  12. package/cjs/koni/api/nft/index.js +6 -3
  13. package/cjs/koni/api/nft/karura_nft/index.js +1 -4
  14. package/cjs/koni/api/nft/rmrk_nft/index.js +1 -8
  15. package/cjs/koni/api/nft/statemine_nft/index.js +1 -4
  16. package/cjs/koni/api/nft/unique_nft/index.js +1 -6
  17. package/cjs/koni/api/nft/wasm_nft/index.js +111 -169
  18. package/cjs/koni/api/nft/wasm_nft/utils.js +7 -11
  19. package/cjs/koni/api/staking/bonding/amplitude.js +9 -13
  20. package/cjs/koni/api/staking/bonding/astar.js +13 -15
  21. package/cjs/koni/api/staking/bonding/index.js +10 -22
  22. package/cjs/koni/api/staking/bonding/paraChain.js +2 -85
  23. package/cjs/koni/api/staking/bonding/relayChain.js +16 -119
  24. package/cjs/koni/api/staking/bonding/utils.js +8 -27
  25. package/cjs/koni/api/tokens/wasm/index.js +4 -5
  26. package/cjs/koni/api/xcm/polkadotXcm.js +1 -1
  27. package/cjs/koni/api/xcm/utils.js +13 -18
  28. package/cjs/koni/api/xcm/xTokens.js +1 -1
  29. package/cjs/koni/api/xcm/xcmPallet.js +6 -9
  30. package/cjs/koni/background/cron.js +47 -150
  31. package/cjs/koni/background/handlers/Extension.js +64 -106
  32. package/cjs/koni/background/handlers/State.js +21 -19
  33. package/cjs/koni/background/handlers/Tabs.js +1 -8
  34. package/cjs/koni/background/subscription.js +29 -32
  35. package/cjs/packageInfo.js +1 -1
  36. package/cjs/services/chain-service/handler/SubstrateChainHandler.js +8 -13
  37. package/cjs/services/chain-service/handler/light-client/index.js +0 -2
  38. package/cjs/services/chain-service/index.js +7 -6
  39. package/cjs/services/event-service/index.js +1 -5
  40. package/cjs/services/event-service/types.js +1 -11
  41. package/cjs/services/history-service/index.js +10 -16
  42. package/cjs/services/history-service/subsquid-multi-chain-history.js +9 -12
  43. package/cjs/services/price-service/coingecko.js +1 -0
  44. package/cjs/services/price-service/index.js +3 -2
  45. package/cjs/services/request-service/handler/AuthRequestHandler.js +2 -6
  46. package/cjs/services/storage-service/DatabaseService.js +33 -52
  47. package/cjs/services/storage-service/db-stores/Nft.js +17 -4
  48. package/cjs/services/transaction-service/event-parser/index.js +48 -20
  49. package/cjs/services/transaction-service/index.js +14 -23
  50. package/cjs/utils/index.js +14 -7
  51. package/constants/index.d.ts +13 -7
  52. package/constants/index.js +13 -7
  53. package/koni/api/dotsama/balance.d.ts +1 -0
  54. package/koni/api/dotsama/balance.js +197 -22
  55. package/koni/api/dotsama/transfer.js +4 -5
  56. package/koni/api/nft/acala_nft/index.js +1 -3
  57. package/koni/api/nft/bit.country/index.js +1 -3
  58. package/koni/api/nft/evm_nft/index.js +3 -6
  59. package/koni/api/nft/index.d.ts +2 -1
  60. package/koni/api/nft/index.js +6 -3
  61. package/koni/api/nft/karura_nft/index.js +1 -3
  62. package/koni/api/nft/nft.d.ts +0 -1
  63. package/koni/api/nft/rmrk_nft/index.js +1 -8
  64. package/koni/api/nft/statemine_nft/index.js +1 -3
  65. package/koni/api/nft/unique_nft/index.js +1 -5
  66. package/koni/api/nft/wasm_nft/index.d.ts +2 -0
  67. package/koni/api/nft/wasm_nft/index.js +109 -167
  68. package/koni/api/nft/wasm_nft/utils.d.ts +5 -7
  69. package/koni/api/nft/wasm_nft/utils.js +5 -7
  70. package/koni/api/staking/bonding/amplitude.d.ts +1 -0
  71. package/koni/api/staking/bonding/amplitude.js +10 -15
  72. package/koni/api/staking/bonding/astar.js +6 -8
  73. package/koni/api/staking/bonding/index.d.ts +1 -4
  74. package/koni/api/staking/bonding/index.js +13 -23
  75. package/koni/api/staking/bonding/paraChain.d.ts +0 -3
  76. package/koni/api/staking/bonding/paraChain.js +5 -86
  77. package/koni/api/staking/bonding/relayChain.d.ts +1 -5
  78. package/koni/api/staking/bonding/relayChain.js +18 -118
  79. package/koni/api/staking/bonding/utils.d.ts +2 -3
  80. package/koni/api/staking/bonding/utils.js +9 -27
  81. package/koni/api/tokens/wasm/index.js +4 -5
  82. package/koni/api/xcm/polkadotXcm.js +2 -2
  83. package/koni/api/xcm/utils.d.ts +6 -5
  84. package/koni/api/xcm/utils.js +10 -15
  85. package/koni/api/xcm/xTokens.js +2 -2
  86. package/koni/api/xcm/xcmPallet.js +9 -10
  87. package/koni/background/cron.d.ts +1 -6
  88. package/koni/background/cron.js +48 -151
  89. package/koni/background/handlers/Extension.d.ts +2 -2
  90. package/koni/background/handlers/Extension.js +67 -108
  91. package/koni/background/handlers/State.d.ts +6 -5
  92. package/koni/background/handlers/State.js +21 -19
  93. package/koni/background/handlers/Tabs.js +1 -8
  94. package/koni/background/subscription.js +30 -31
  95. package/package.json +8 -13
  96. package/packageInfo.js +1 -1
  97. package/services/chain-service/handler/SubstrateChainHandler.js +9 -14
  98. package/services/chain-service/handler/light-client/index.d.ts +1 -17
  99. package/services/chain-service/handler/light-client/index.js +1 -1
  100. package/services/chain-service/helper/psp22_abi.json +881 -1041
  101. package/services/chain-service/helper/psp34_abi.json +1808 -2964
  102. package/services/chain-service/index.js +7 -6
  103. package/services/event-service/index.js +1 -5
  104. package/services/event-service/types.d.ts +9 -5
  105. package/services/event-service/types.js +1 -4
  106. package/services/history-service/index.d.ts +1 -1
  107. package/services/history-service/index.js +10 -16
  108. package/services/history-service/subsquid-multi-chain-history.js +11 -15
  109. package/services/price-service/coingecko.js +1 -0
  110. package/services/price-service/index.js +3 -2
  111. package/services/request-service/handler/AuthRequestHandler.js +2 -6
  112. package/services/storage-service/DatabaseService.d.ts +0 -1
  113. package/services/storage-service/DatabaseService.js +33 -52
  114. package/services/storage-service/db-stores/Nft.d.ts +2 -1
  115. package/services/storage-service/db-stores/Nft.js +16 -4
  116. package/services/transaction-service/event-parser/index.js +49 -21
  117. package/services/transaction-service/index.js +14 -23
  118. package/utils/index.d.ts +1 -1
  119. package/utils/index.js +12 -6
  120. package/cjs/koni/api/tokens/wasm/utils.js +0 -63
  121. package/koni/api/tokens/wasm/utils.d.ts +0 -6
  122. package/koni/api/tokens/wasm/utils.js +0 -54
@@ -6,15 +6,15 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
6
6
  import { isJsonPayload, SEED_DEFAULT_LENGTH, SEED_LENGTHS } from '@subwallet/extension-base/background/handlers/Extension';
7
7
  import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
8
8
  import { createSubscription } from '@subwallet/extension-base/background/handlers/subscriptions';
9
- import { AccountExternalErrorCode, BasicTxErrorType, ChainType, ExternalRequestPromiseStatus, ExtrinsicType, StakingType, TransferTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
9
+ import { AccountExternalErrorCode, BasicTxErrorType, ChainType, ExternalRequestPromiseStatus, ExtrinsicType, TransferTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
10
10
  import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH, DEFAULT_TIME_AUTO_LOCK } from '@subwallet/extension-base/constants';
11
11
  import { ALLOWED_PATH } from '@subwallet/extension-base/defaults';
12
12
  import { parseSubstrateTransaction } from '@subwallet/extension-base/koni/api/dotsama/parseTransaction';
13
13
  import { checkReferenceCount, checkSupportTransfer, createTransferExtrinsic } from '@subwallet/extension-base/koni/api/dotsama/transfer';
14
14
  import { getNftTransferExtrinsic, isRecipientSelf } from '@subwallet/extension-base/koni/api/nft/transfer';
15
- import { getBondingExtrinsic, getCancelWithdrawalExtrinsic, getClaimRewardExtrinsic, getNominationPoolsInfo, getUnbondingExtrinsic, getValidatorsInfo, getWithdrawalExtrinsic, validateBondingCondition, validateUnbondingCondition } from '@subwallet/extension-base/koni/api/staking/bonding';
15
+ import { getBondingExtrinsic, getCancelWithdrawalExtrinsic, getClaimRewardExtrinsic, getNominationPoolsInfo, getUnbondingExtrinsic, getValidatorsInfo, getWithdrawalExtrinsic } from '@subwallet/extension-base/koni/api/staking/bonding';
16
16
  import { getTuringCancelCompoundingExtrinsic, getTuringCompoundExtrinsic } from '@subwallet/extension-base/koni/api/staking/bonding/paraChain';
17
- import { getPoolingBondingExtrinsic, getPoolingUnbondingExtrinsic, validatePoolBondingCondition, validateRelayUnbondingCondition } from '@subwallet/extension-base/koni/api/staking/bonding/relayChain';
17
+ import { getPoolingBondingExtrinsic, getPoolingUnbondingExtrinsic } from '@subwallet/extension-base/koni/api/staking/bonding/relayChain';
18
18
  import { getERC20TransactionObject, getERC721Transaction, getEVMTransactionObject } from '@subwallet/extension-base/koni/api/tokens/evm/transfer';
19
19
  import { getPSP34TransferExtrinsic } from '@subwallet/extension-base/koni/api/tokens/wasm';
20
20
  import { createXcmExtrinsic } from '@subwallet/extension-base/koni/api/xcm';
@@ -401,38 +401,35 @@ export default class KoniExtension {
401
401
  }
402
402
  async accountsGetAllWithCurrentAddress(id, port) {
403
403
  const cb = createSubscription(id, port);
404
- const keyringService = this.#koniState.keyringService;
405
- await this.#koniState.eventService.waitAccountReady;
406
- const currentAccount = keyringService.currentAccount;
407
- const accountsSubject = keyring.accounts.subject;
408
- const transformedAccounts = transformAccounts(accountsSubject.value);
409
- const responseData = {
410
- accounts: transformedAccounts !== null && transformedAccounts !== void 0 && transformedAccounts.length ? [{
411
- ...ACCOUNT_ALL_JSON
412
- }, ...transformedAccounts] : [],
413
- currentAddress: currentAccount === null || currentAccount === void 0 ? void 0 : currentAccount.address,
414
- currentGenesisHash: currentAccount === null || currentAccount === void 0 ? void 0 : currentAccount.currentGenesisHash
415
- };
416
- const subscriptionAccounts = accountsSubject.subscribe(storedAccounts => {
417
- const transformedAccounts = transformAccounts(storedAccounts);
418
- responseData.accounts = transformedAccounts !== null && transformedAccounts !== void 0 && transformedAccounts.length ? [{
419
- ...ACCOUNT_ALL_JSON
420
- }, ...transformedAccounts] : [];
421
- cb(responseData);
422
- });
423
- const subscriptionCurrentAccount = keyringService.currentAccountSubject.subscribe(currentAccountData => {
424
- responseData.currentAddress = currentAccountData.address;
425
- responseData.currentGenesisHash = currentAccountData.currentGenesisHash;
426
- cb(responseData);
427
- });
428
- this.createUnsubscriptionHandle(id, () => {
429
- subscriptionAccounts.unsubscribe();
430
- subscriptionCurrentAccount.unsubscribe();
431
- });
432
- port.onDisconnect.addListener(() => {
433
- this.cancelSubscription(id);
404
+ return await new Promise(resolve => {
405
+ const subscription = accountsObservable.subject.subscribe(storedAccounts => {
406
+ const transformedAccounts = transformAccounts(storedAccounts);
407
+ const accounts = transformedAccounts && transformedAccounts.length ? [{
408
+ ...ACCOUNT_ALL_JSON
409
+ }, ...transformedAccounts] : [];
410
+ const accountsWithCurrentAddress = {
411
+ accounts
412
+ };
413
+ setTimeout(() => {
414
+ const accountInfo = this.#koniState.keyringService.currentAccount;
415
+ if (accountInfo) {
416
+ accountsWithCurrentAddress.currentAddress = accountInfo.address;
417
+ if (accountInfo.address === ALL_ACCOUNT_KEY) {
418
+ accountsWithCurrentAddress.currentGenesisHash = accountInfo.currentGenesisHash;
419
+ } else {
420
+ const acc = accounts.find(a => a.address === accountInfo.address);
421
+ accountsWithCurrentAddress.currentGenesisHash = (acc === null || acc === void 0 ? void 0 : acc.genesisHash) || ALL_GENESIS_HASH;
422
+ }
423
+ }
424
+ resolve(accountsWithCurrentAddress);
425
+ cb(accountsWithCurrentAddress);
426
+ }, 300);
427
+ });
428
+ this.createUnsubscriptionHandle(id, subscription.unsubscribe);
429
+ port.onDisconnect.addListener(() => {
430
+ this.cancelSubscription(id);
431
+ });
434
432
  });
435
- return responseData;
436
433
  }
437
434
  accountsGetAll(id, port) {
438
435
  const cb = createSubscription(id, port);
@@ -453,15 +450,11 @@ export default class KoniExtension {
453
450
  }) {
454
451
  return keyring.saveRecent(accountId);
455
452
  }
456
-
457
- // private triggerAccountsSubscription (): boolean {
458
- // const accountsSubject = accountsObservable.subject;
459
- //
460
- // accountsSubject.next(accountsSubject.getValue());
461
- //
462
- // return true;
463
- // }
464
-
453
+ triggerAccountsSubscription() {
454
+ const accountsSubject = accountsObservable.subject;
455
+ accountsSubject.next(accountsSubject.getValue());
456
+ return true;
457
+ }
465
458
  _getAuthListV2() {
466
459
  return new Promise((resolve, reject) => {
467
460
  this.#koniState.getAuthorize(rs => {
@@ -813,12 +806,8 @@ export default class KoniExtension {
813
806
  } else {
814
807
  accountInfo.address = address;
815
808
  if (address !== ALL_ACCOUNT_KEY) {
816
- try {
817
- const currentKeyPair = keyring.getPair(address);
818
- accountInfo.currentGenesisHash = (currentKeyPair === null || currentKeyPair === void 0 ? void 0 : currentKeyPair.meta.genesisHash) || ALL_GENESIS_HASH;
819
- } catch {
820
- accountInfo.currentGenesisHash = ALL_GENESIS_HASH;
821
- }
809
+ const currentKeyPair = keyring.getAccount(address);
810
+ accountInfo.currentGenesisHash = (currentKeyPair === null || currentKeyPair === void 0 ? void 0 : currentKeyPair.meta.genesisHash) || ALL_GENESIS_HASH;
822
811
  } else {
823
812
  accountInfo.currentGenesisHash = accountInfo.allGenesisHash || ALL_GENESIS_HASH;
824
813
  }
@@ -828,15 +817,18 @@ export default class KoniExtension {
828
817
  });
829
818
  }
830
819
  updateCurrentAccountAddress(address) {
831
- this._saveCurrentAccountAddress(address);
820
+ this._saveCurrentAccountAddress(address, () => {
821
+ this.triggerAccountsSubscription();
822
+ });
832
823
  return true;
833
824
  }
834
- async saveCurrentAccountAddress(data) {
835
- return new Promise(resolve => {
836
- this._saveCurrentAccountAddress(data.address, currentInfo => {
837
- resolve(currentInfo);
838
- });
825
+ saveCurrentAccountAddress(data, id, port) {
826
+ const cb = createSubscription(id, port);
827
+ this._saveCurrentAccountAddress(data.address, cb);
828
+ port.onDisconnect.addListener(() => {
829
+ this.cancelSubscription(id);
839
830
  });
831
+ return true;
840
832
  }
841
833
  async getAssetSetting() {
842
834
  return this.#koniState.chainService.getAssetSettings();
@@ -853,7 +845,6 @@ export default class KoniExtension {
853
845
  async updateAssetSetting(params) {
854
846
  try {
855
847
  await this.#koniState.chainService.updateAssetSetting(params.tokenSlug, params.assetSetting);
856
- this.#koniState.eventService.emit('asset.updateState', params.tokenSlug);
857
848
  return true;
858
849
  } catch (e) {
859
850
  console.error('Error updating asset setting', e);
@@ -1331,6 +1322,7 @@ export default class KoniExtension {
1331
1322
 
1332
1323
  // Get native token amount
1333
1324
  const freeBalance = await this.#koniState.balanceService.getTokenFreeBalance(from, networkKey, tokenSlug);
1325
+ let edAsWarning = false;
1334
1326
  if (isEthereumAddress(from) && isEthereumAddress(to)) {
1335
1327
  chainType = ChainType.EVM;
1336
1328
  const txVal = transferAll ? freeBalance.value : value || '0';
@@ -1340,6 +1332,7 @@ export default class KoniExtension {
1340
1332
  [transaction, transferAmount.value] = await getERC20TransactionObject(_getContractAddressOfToken(tokenInfo), chainInfo, from, to, txVal, !!transferAll, evmApiMap);
1341
1333
  } else {
1342
1334
  [transaction, transferAmount.value] = await getEVMTransactionObject(chainInfo, to, txVal, !!transferAll, evmApiMap);
1335
+ edAsWarning = true;
1343
1336
  }
1344
1337
  } else {
1345
1338
  const substrateApi = this.#koniState.getSubstrateApi(networkKey);
@@ -1352,6 +1345,7 @@ export default class KoniExtension {
1352
1345
  to: to,
1353
1346
  substrateApi
1354
1347
  });
1348
+ edAsWarning = true;
1355
1349
  }
1356
1350
  const transferNativeAmount = isTransferNativeToken ? transferAmount.value : '0';
1357
1351
  return this.#koniState.transactionService.handleTransaction({
@@ -1366,7 +1360,7 @@ export default class KoniExtension {
1366
1360
  extrinsicType: isTransferNativeToken ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.TRANSFER_TOKEN,
1367
1361
  ignoreWarnings: transferAll,
1368
1362
  isTransferAll: transferAll,
1369
- edAsWarning: isTransferNativeToken
1363
+ edAsWarning: edAsWarning
1370
1364
  });
1371
1365
  }
1372
1366
  validateCrossChainTransfer(destinationNetworkKey, sendingTokenSlug, sender, sendingValue) {
@@ -2044,7 +2038,6 @@ export default class KoniExtension {
2044
2038
  }
2045
2039
  async getNominationPoolOptions(chain) {
2046
2040
  const substrateApi = this.#koniState.getSubstrateApi(chain);
2047
- console.log('chain', chain);
2048
2041
  return await getNominationPoolsInfo(chain, substrateApi);
2049
2042
  }
2050
2043
  async submitBonding(inputData) {
@@ -2055,15 +2048,12 @@ export default class KoniExtension {
2055
2048
  nominatorMetadata,
2056
2049
  selectedValidators
2057
2050
  } = inputData;
2058
- const chainInfo = this.#koniState.getChainInfo(chain);
2059
- const chainStakingMetadata = await this.#koniState.getStakingMetadataByChain(chain, StakingType.NOMINATED);
2060
- if (!chainStakingMetadata) {
2061
- return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
2062
- }
2063
- const bondingValidation = validateBondingCondition(chainInfo, amount, selectedValidators, address, chainStakingMetadata, nominatorMetadata);
2064
- if (!amount || !selectedValidators || bondingValidation.length > 0) {
2065
- return this.#koniState.transactionService.generateBeforeHandleResponseErrors(bondingValidation);
2051
+ if (!amount || !selectedValidators) {
2052
+ // Todo: Check and return error here
2053
+
2054
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(BasicTxErrorType.INVALID_PARAMS)]);
2066
2055
  }
2056
+ const chainInfo = this.#koniState.getChainInfo(chain);
2067
2057
  const substrateApi = this.#koniState.getSubstrateApi(chain);
2068
2058
  const extrinsic = await getBondingExtrinsic(chainInfo, amount, selectedValidators, substrateApi, address, nominatorMetadata);
2069
2059
  console.log('Bonding extrinsic: ', chain, extrinsic.toHex());
@@ -2074,8 +2064,7 @@ export default class KoniExtension {
2074
2064
  data: inputData,
2075
2065
  extrinsicType: ExtrinsicType.STAKING_BOND,
2076
2066
  transaction: extrinsic,
2077
- url: EXTENSION_REQUEST_URL,
2078
- transferNativeAmount: amount
2067
+ url: EXTENSION_REQUEST_URL
2079
2068
  });
2080
2069
  }
2081
2070
  async submitUnbonding(inputData) {
@@ -2085,17 +2074,12 @@ export default class KoniExtension {
2085
2074
  nominatorMetadata,
2086
2075
  validatorAddress
2087
2076
  } = inputData;
2088
- const chainStakingMetadata = await this.#koniState.getStakingMetadataByChain(chain, StakingType.NOMINATED);
2089
- if (!chainStakingMetadata || !nominatorMetadata) {
2090
- return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
2091
- }
2092
- const unbondingValidation = validateUnbondingCondition(nominatorMetadata, amount, chain, chainStakingMetadata, validatorAddress);
2093
- if (!amount || unbondingValidation.length > 0) {
2094
- return this.#koniState.transactionService.generateBeforeHandleResponseErrors(unbondingValidation);
2077
+ if (!amount || !nominatorMetadata) {
2078
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(BasicTxErrorType.INVALID_PARAMS)]);
2095
2079
  }
2096
2080
  const substrateApi = this.#koniState.getSubstrateApi(chain);
2097
2081
  const extrinsic = await getUnbondingExtrinsic(nominatorMetadata, amount, chain, substrateApi, validatorAddress);
2098
- console.log('Unbonding extrinsic: ', extrinsic.toHex());
2082
+ console.log('unbonding extrinsic: ', extrinsic.toHex());
2099
2083
  return await this.#koniState.transactionService.handleTransaction({
2100
2084
  address: nominatorMetadata.address,
2101
2085
  chain: chain,
@@ -2169,7 +2153,7 @@ export default class KoniExtension {
2169
2153
  chainType: ChainType.SUBSTRATE
2170
2154
  });
2171
2155
  }
2172
- async submitPoolBonding(inputData) {
2156
+ async submitPoolingBonding(inputData) {
2173
2157
  const {
2174
2158
  address,
2175
2159
  amount,
@@ -2177,15 +2161,8 @@ export default class KoniExtension {
2177
2161
  nominatorMetadata,
2178
2162
  selectedPool
2179
2163
  } = inputData;
2180
- const chainInfo = this.#koniState.getChainInfo(chain);
2181
- const chainStakingMetadata = await this.#koniState.getStakingMetadataByChain(chain, StakingType.NOMINATED);
2182
- if (!chainStakingMetadata) {
2183
- return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
2184
- }
2185
- const bondingValidation = validatePoolBondingCondition(chainInfo, amount, selectedPool, address, chainStakingMetadata, nominatorMetadata);
2186
- if (!amount || bondingValidation.length > 0) {
2187
- return this.#koniState.transactionService.generateBeforeHandleResponseErrors(bondingValidation);
2188
- }
2164
+
2165
+ // TODO: can't stake when unstake all
2189
2166
  const substrateApi = this.#koniState.getSubstrateApi(chain);
2190
2167
  const extrinsic = await getPoolingBondingExtrinsic(substrateApi, amount, selectedPool.id, nominatorMetadata);
2191
2168
  console.log('Join nomination pool extrinsic', extrinsic.toHex());
@@ -2204,14 +2181,6 @@ export default class KoniExtension {
2204
2181
  chain,
2205
2182
  nominatorMetadata
2206
2183
  } = inputData;
2207
- const chainStakingMetadata = await this.#koniState.getStakingMetadataByChain(chain, StakingType.NOMINATED);
2208
- if (!chainStakingMetadata || !nominatorMetadata) {
2209
- return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
2210
- }
2211
- const unbondingValidation = validateRelayUnbondingCondition(amount, chainStakingMetadata, nominatorMetadata);
2212
- if (!amount || unbondingValidation.length > 0) {
2213
- return this.#koniState.transactionService.generateBeforeHandleResponseErrors(unbondingValidation);
2214
- }
2215
2184
  const substrateApi = this.#koniState.getSubstrateApi(chain);
2216
2185
  const extrinsic = await getPoolingUnbondingExtrinsic(substrateApi, amount, nominatorMetadata);
2217
2186
  console.log('Nomination pool unbond extrinsic', extrinsic.toHex());
@@ -2701,16 +2670,6 @@ export default class KoniExtension {
2701
2670
  });
2702
2671
  return notificationSubject.value;
2703
2672
  }
2704
- async reloadCron({
2705
- data
2706
- }) {
2707
- if (data === 'nft') {
2708
- return await this.#koniState.reloadNft();
2709
- } else if (data === 'staking') {
2710
- return await this.#koniState.reloadStaking();
2711
- }
2712
- return Promise.resolve(false);
2713
- }
2714
2673
 
2715
2674
  // --------------------------------------------------------------
2716
2675
  // eslint-disable-next-line @typescript-eslint/require-await
@@ -2827,8 +2786,10 @@ export default class KoniExtension {
2827
2786
  return this.accountsGetAll(id, port);
2828
2787
  case 'pri(accounts.saveRecent)':
2829
2788
  return this.saveRecentAccountId(request);
2789
+ case 'pri(accounts.triggerSubscription)':
2790
+ return this.triggerAccountsSubscription();
2830
2791
  case 'pri(currentAccount.saveAddress)':
2831
- return await this.saveCurrentAccountAddress(request);
2792
+ return this.saveCurrentAccountAddress(request, id, port);
2832
2793
  case 'pri(accounts.updateCurrentAddress)':
2833
2794
  return this.updateCurrentAccountAddress(request);
2834
2795
  case 'pri(settings.changeBalancesVisibility)':
@@ -2992,7 +2953,7 @@ export default class KoniExtension {
2992
2953
  case 'pri(staking.submitTuringCancelCompound)':
2993
2954
  return await this.submitTuringCancelStakeCompound(request);
2994
2955
  case 'pri(bonding.nominationPool.submitBonding)':
2995
- return await this.submitPoolBonding(request);
2956
+ return await this.submitPoolingBonding(request);
2996
2957
  case 'pri(bonding.nominationPool.submitUnbonding)':
2997
2958
  return await this.submitPoolingUnbonding(request);
2998
2959
 
@@ -3041,8 +3002,6 @@ export default class KoniExtension {
3041
3002
  // Notification
3042
3003
  case 'pri(notifications.subscribe)':
3043
3004
  return this.subscribeNotifications(id, port);
3044
- case 'pri(cron.reload)':
3045
- return await this.reloadCron(request);
3046
3005
 
3047
3006
  // Default
3048
3007
  default:
@@ -31,6 +31,7 @@ export default class KoniState {
31
31
  private readonly unsubscriptionMap;
32
32
  private readonly accountRefStore;
33
33
  private externalRequest;
34
+ private serviceInfoSubject;
34
35
  private balanceMap;
35
36
  private balanceSubject;
36
37
  private crowdloanMap;
@@ -108,8 +109,8 @@ export default class KoniState {
108
109
  subscribeNftCollection(): import("dexie").Observable<NftCollection[]>;
109
110
  resetNft(newAddress: string): void;
110
111
  updateNftData(network: string, nftData: NftItem, address: string, callback?: (nftData: NftItem) => void): void;
112
+ removeNfts(chain: string, address: string, collectionId: string, nftIds: string[]): import("dexie").PromiseExtended<number>;
111
113
  deleteNftCollection(chain: string, collectionId: string): Promise<void>;
112
- cleanUpNfts(chain: string, owner: string, collectionId: string, nftIds: string[]): void;
113
114
  getNft(): Promise<NftJson | undefined>;
114
115
  subscribeNft(): Subject<NftJson>;
115
116
  resetStakingReward(): void;
@@ -140,7 +141,7 @@ export default class KoniState {
140
141
  private removeInactiveChainBalances;
141
142
  getBalance(reset?: boolean): BalanceJson;
142
143
  getStoredBalance(address: string): Promise<Record<string, BalanceItem>>;
143
- handleSwitchAccount(newAddress: string): Promise<void>;
144
+ switchAccount(newAddress: string): Promise<void>;
144
145
  resetBalanceMap(newAddress: string): Promise<void>;
145
146
  resetCrowdloanMap(newAddress: string): Promise<void>;
146
147
  resetStaking(newAddress: string): void;
@@ -152,6 +153,7 @@ export default class KoniState {
152
153
  setCrowdloanItem(networkKey: string, item: CrowdloanItem): void;
153
154
  private updateCrowdloanStore;
154
155
  subscribeCrowdloan(): Subject<CrowdloanJson>;
156
+ getAllPriceIds(): string[];
155
157
  getSmartContractNfts(): _ChainAsset[];
156
158
  getChainInfoMap(): Record<string, _ChainInfo>;
157
159
  getChainStateMap(): Record<string, _ChainState>;
@@ -180,6 +182,7 @@ export default class KoniState {
180
182
  disableChain(chainSlug: string): Promise<boolean>;
181
183
  enableChain(chainSlug: string, enableTokens?: boolean): Promise<boolean>;
182
184
  resetDefaultChains(): boolean;
185
+ updateNetworkStatus(networkKey: string, status: _ChainConnectionStatus): void;
183
186
  getSubstrateApiMap(): Record<string, import("@subwallet/extension-base/services/chain-service/types")._SubstrateApi>;
184
187
  getSubstrateApi(networkKey: string): import("@subwallet/extension-base/services/chain-service/types")._SubstrateApi;
185
188
  getEvmApiMap(): Record<string, import("@subwallet/extension-base/services/chain-service/types")._EvmApi>;
@@ -187,6 +190,7 @@ export default class KoniState {
187
190
  getApiMap(): ApiMap;
188
191
  refreshSubstrateApi(key: string): boolean;
189
192
  refreshWeb3Api(key: string): void;
193
+ subscribeServiceInfo(): Subject<ServiceInfo>;
190
194
  getServiceInfo(): ServiceInfo;
191
195
  getExternalRequestMap(): Record<string, ExternalRequestPromise>;
192
196
  setExternalRequestMap(id: string, value: ExternalRequestPromise): void;
@@ -215,11 +219,8 @@ export default class KoniState {
215
219
  wakeup(): Promise<void>;
216
220
  cancelSubscription(id: string): boolean;
217
221
  createUnsubscriptionHandle(id: string, unsubscribe: () => void): void;
218
- updateChainConnectionStatus(chain: string, status: _ChainConnectionStatus): void;
219
222
  autoEnableChains(addresses: string[]): Promise<void>;
220
223
  onAccountAdd(): void;
221
224
  onAccountRemove(): void;
222
- reloadNft(): Promise<boolean>;
223
- reloadStaking(): Promise<boolean>;
224
225
  }
225
226
  export {};
@@ -59,6 +59,7 @@ export default class KoniState {
59
59
  unsubscriptionMap = {};
60
60
  accountRefStore = new AccountRefStore();
61
61
  externalRequest = {};
62
+ serviceInfoSubject = new Subject();
62
63
  balanceMap = {};
63
64
  balanceSubject = new Subject();
64
65
  crowdloanMap = generateDefaultCrowdloanMap();
@@ -295,7 +296,7 @@ export default class KoniState {
295
296
  return addresses;
296
297
  }
297
298
  async getPooledStakingRecordsByAddress(addresses) {
298
- return this.dbService.getPooledStakings(addresses, this.activeChainSlugs);
299
+ return await this.dbService.getPooledStakings(addresses, this.activeChainSlugs);
299
300
  }
300
301
 
301
302
  // TODO: delete later
@@ -353,12 +354,12 @@ export default class KoniState {
353
354
  this.dbService.addNft(address, nftData).catch(e => this.logger.warn(e));
354
355
  callback && callback(nftData);
355
356
  }
357
+ removeNfts(chain, address, collectionId, nftIds) {
358
+ return this.dbService.removeNfts(chain, address, collectionId, nftIds);
359
+ }
356
360
  deleteNftCollection(chain, collectionId) {
357
361
  return this.dbService.deleteNftCollection(chain, collectionId);
358
362
  }
359
- cleanUpNfts(chain, owner, collectionId, nftIds) {
360
- this.dbService.cleanUpNft(chain, owner, collectionId, nftIds).catch(e => this.logger.warn(e));
361
- }
362
363
  async getNft() {
363
364
  const addresses = this.getDecodedAddresses();
364
365
  if (!addresses.length) {
@@ -445,7 +446,7 @@ export default class KoniState {
445
446
  if (address === ALL_ACCOUNT_KEY) {
446
447
  const pairs = keyring.getAccounts();
447
448
  const pair = pairs[0];
448
- const pairGenesisHash = (pair === null || pair === void 0 ? void 0 : pair.meta.genesisHash) || '';
449
+ const pairGenesisHash = pair.meta.genesisHash;
449
450
  if (pairs.length > 1 || !pair) {
450
451
  result.allGenesisHash = currentGenesisHash || undefined;
451
452
  } else {
@@ -655,7 +656,7 @@ export default class KoniState {
655
656
  const items = await this.dbService.stores.balance.getBalanceMapByAddress(address);
656
657
  return items || {};
657
658
  }
658
- async handleSwitchAccount(newAddress) {
659
+ async switchAccount(newAddress) {
659
660
  await Promise.all([this.resetBalanceMap(newAddress), this.resetCrowdloanMap(newAddress)]);
660
661
  }
661
662
  async resetBalanceMap(newAddress) {
@@ -736,6 +737,9 @@ export default class KoniState {
736
737
  subscribeCrowdloan() {
737
738
  return this.crowdloanSubject;
738
739
  }
740
+ getAllPriceIds() {
741
+ return this.chainService.getAllPriceIds();
742
+ }
739
743
  getSmartContractNfts() {
740
744
  return this.chainService.getSmartContractNfts();
741
745
  }
@@ -793,9 +797,7 @@ export default class KoniState {
793
797
  await this.chainService.updateAssetSetting(tokenSlug, {
794
798
  visible: true
795
799
  });
796
- this.eventService.emit('asset.updateState', tokenSlug);
797
- } else {
798
- this.eventService.emit('asset.updateState', tokenSlug);
800
+ this.eventService.emit('asset.update', tokenSlug);
799
801
  }
800
802
  }
801
803
  deleteCustomAssets(targetTokens) {
@@ -822,7 +824,6 @@ export default class KoniState {
822
824
  await this.chainService.updateAssetSetting(newNativeTokenSlug, {
823
825
  visible: true
824
826
  });
825
- this.eventService.emit('asset.updateState', newNativeTokenSlug);
826
827
  }
827
828
  return true;
828
829
  }
@@ -865,6 +866,13 @@ export default class KoniState {
865
866
  const defaultChains = this.getDefaultNetworkKeys();
866
867
  return this.chainService.resetChainInfoMap(defaultChains);
867
868
  }
869
+ updateNetworkStatus(networkKey, status) {
870
+ const chainState = this.chainService.getChainStateByKey(networkKey);
871
+ if (chainState.connectionStatus === status) {
872
+ return;
873
+ }
874
+ this.chainService.setChainConnectionStatus(networkKey, status);
875
+ }
868
876
  getSubstrateApiMap() {
869
877
  return this.chainService.getSubstrateApiMap();
870
878
  }
@@ -890,6 +898,9 @@ export default class KoniState {
890
898
  refreshWeb3Api(key) {
891
899
  this.chainService.refreshEvmApi(key);
892
900
  }
901
+ subscribeServiceInfo() {
902
+ return this.serviceInfoSubject;
903
+ }
893
904
  getServiceInfo() {
894
905
  return {
895
906
  chainInfoMap: this.chainService.getChainInfoMap(),
@@ -1328,9 +1339,6 @@ export default class KoniState {
1328
1339
  createUnsubscriptionHandle(id, unsubscribe) {
1329
1340
  this.unsubscriptionMap[id] = unsubscribe;
1330
1341
  }
1331
- updateChainConnectionStatus(chain, status) {
1332
- this.chainService.setChainConnectionStatus(chain, status);
1333
- }
1334
1342
  async autoEnableChains(addresses) {
1335
1343
  const assetMap = this.chainService.getAssetRegistry();
1336
1344
  const promiseList = addresses.map(address => {
@@ -1401,10 +1409,4 @@ export default class KoniState {
1401
1409
  stores.staking.removeAllByAddress(address).catch(console.error);
1402
1410
  });
1403
1411
  }
1404
- async reloadNft() {
1405
- return await this.cron.reloadNft();
1406
- }
1407
- async reloadStaking() {
1408
- return await this.cron.reloadStaking();
1409
- }
1410
1412
  }
@@ -255,20 +255,13 @@ export default class KoniTabs {
255
255
  if (!web3.currentProvider.connected) {
256
256
  console.log(`[Web3] ${slug} is disconnected, trying to connect...`);
257
257
  this.#koniState.refreshWeb3Api(slug);
258
- let checkingNum = 0;
259
258
  const poll = resolve => {
260
- checkingNum += 1;
261
259
  if (web3.currentProvider.connected) {
262
260
  console.log(`Network [${slug}] is connected.`);
263
261
  resolve(true);
264
262
  } else {
265
263
  console.log(`Connecting to network [${slug}]`);
266
- if (checkingNum < 10) {
267
- setTimeout(() => poll(resolve), 900);
268
- } else {
269
- console.log(`Max retry, stop checking [${slug}]`);
270
- resolve(false);
271
- }
264
+ setTimeout(() => poll(resolve), 400);
272
265
  }
273
266
  };
274
267
  await new Promise(poll);
@@ -11,7 +11,6 @@ import { getAmplitudeUnclaimedStakingReward } from '@subwallet/extension-base/ko
11
11
  import { nftHandler } from '@subwallet/extension-base/koni/background/handlers';
12
12
  import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
13
13
  import { _isChainEnabled, _isChainEvmCompatible, _isChainSupportSubstrateStaking, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
14
- import { COMMON_RELOAD_EVENTS } from '@subwallet/extension-base/services/event-service/types';
15
14
  import { logger as createLogger } from '@polkadot/util';
16
15
  import { isEthereumAddress } from '@polkadot/util-crypto';
17
16
  export class KoniSubscription {
@@ -59,28 +58,30 @@ export class KoniSubscription {
59
58
  this.subscribeBalancesAndCrowdloans(currentAddress, this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap(), this.state.getEvmApiMap());
60
59
  this.subscribeStakingOnChain(currentAddress, this.state.getSubstrateApiMap());
61
60
  }
62
- this.eventHandler = (events, eventTypes) => {
63
- var _serviceInfo$currentA;
64
- const serviceInfo = this.state.getServiceInfo();
65
- const needReload = eventTypes.some(eventType => COMMON_RELOAD_EVENTS.includes(eventType));
66
- if (!needReload) {
67
- return;
68
- }
69
- this.logger.log('ServiceInfo updated, restarting...');
70
- const address = (_serviceInfo$currentA = serviceInfo.currentAccountInfo) === null || _serviceInfo$currentA === void 0 ? void 0 : _serviceInfo$currentA.address;
71
- if (!address) {
72
- return;
73
- }
74
- this.subscribeBalancesAndCrowdloans(address, serviceInfo.chainInfoMap, serviceInfo.chainStateMap, serviceInfo.chainApiMap.substrate, serviceInfo.chainApiMap.evm);
75
- this.subscribeStakingOnChain(address, serviceInfo.chainApiMap.substrate);
76
- };
77
- this.state.eventService.onLazy(this.eventHandler);
61
+ if (!this.eventHandler) {
62
+ const reloadEvents = ['account.add', 'account.remove', 'account.updateCurrent', 'chain.add', 'chain.update', 'chain.enable', 'asset.update', 'asset.enable', 'transaction.done', 'transaction.failed'];
63
+ this.eventHandler = (events, eventTypes) => {
64
+ var _serviceInfo$currentA;
65
+ const serviceInfo = this.state.getServiceInfo();
66
+ const needReload = eventTypes.some(eT => reloadEvents.includes(eT));
67
+ if (!needReload) {
68
+ return;
69
+ }
70
+ this.logger.log('ServiceInfo updated, restarting...');
71
+ const address = (_serviceInfo$currentA = serviceInfo.currentAccountInfo) === null || _serviceInfo$currentA === void 0 ? void 0 : _serviceInfo$currentA.address;
72
+ if (!address) {
73
+ return;
74
+ }
75
+ this.subscribeBalancesAndCrowdloans(address, serviceInfo.chainInfoMap, serviceInfo.chainStateMap, serviceInfo.chainApiMap.substrate, serviceInfo.chainApiMap.evm);
76
+ this.subscribeStakingOnChain(address, serviceInfo.chainApiMap.substrate);
77
+ };
78
+ this.state.eventService.onLazy(this.eventHandler);
79
+ }
78
80
  }
79
81
  stop() {
80
82
  this.logger.log('Stopping subscription');
81
83
  if (this.eventHandler) {
82
84
  this.state.eventService.offLazy(this.eventHandler);
83
- this.eventHandler = undefined;
84
85
  }
85
86
  this.stopAllSubscription();
86
87
  }
@@ -106,7 +107,7 @@ export class KoniSubscription {
106
107
  });
107
108
  }
108
109
  subscribeBalancesAndCrowdloans(address, chainInfoMap, chainStateMap, substrateApiMap, web3ApiMap, onlyRunOnFirstTime) {
109
- this.state.handleSwitchAccount(address).then(() => {
110
+ this.state.switchAccount(address).then(() => {
110
111
  const addresses = this.state.getDecodedAddresses(address);
111
112
  if (!addresses.length) {
112
113
  return;
@@ -177,7 +178,9 @@ export class KoniSubscription {
177
178
  nftHandler.setDotSamaApiMap(substrateApiMap);
178
179
  nftHandler.setWeb3ApiMap(evmApiMap);
179
180
  nftHandler.setAddresses(addresses);
180
- nftHandler.handleNfts(smartContractNfts, (...args) => this.state.updateNftData(...args), (...args) => this.state.setNftCollection(...args), (...args) => this.state.cleanUpNfts(...args)).catch(this.logger.log);
181
+ nftHandler.handleNfts(smartContractNfts, (...args) => this.state.updateNftData(...args), (...args) => this.state.setNftCollection(...args)).then(() => {
182
+ this.logger.log('nft state updated');
183
+ }).catch(this.logger.log);
181
184
  }
182
185
  async subscribeStakingReward(address) {
183
186
  const addresses = this.state.getDecodedAddresses(address);
@@ -194,6 +197,7 @@ export class KoniSubscription {
194
197
  });
195
198
  const result = await getNominationStakingRewardData(addresses, targetNetworkMap);
196
199
  this.state.updateStakingReward(result, 'slowInterval');
200
+ this.logger.log('Set staking reward state done', result);
197
201
  }
198
202
  async subscribeStakingRewardFastInterval(address) {
199
203
  const addresses = this.state.getDecodedAddresses(address);
@@ -222,21 +226,15 @@ export class KoniSubscription {
222
226
  const [poolingStakingRewards, amplitudeUnclaimedStakingRewards] = await Promise.all([getPoolingStakingRewardData(pooledAddresses, targetChainMap, this.state.getSubstrateApiMap()), getAmplitudeUnclaimedStakingReward(this.state.getSubstrateApiMap(), addresses, chainInfoMap, activeNetworks)]);
223
227
  const result = [...poolingStakingRewards, ...amplitudeUnclaimedStakingRewards];
224
228
  this.state.updateStakingReward(result, 'fastInterval');
229
+ this.logger.log('Set staking reward state with fast interval done', result);
225
230
  }
226
231
  async fetchChainStakingMetadata(chainInfoMap, chainStateMap, substrateApiMap) {
227
- const filteredChainInfoMap = {};
228
- Object.values(chainInfoMap).forEach(chainInfo => {
232
+ await Promise.all(Object.values(chainInfoMap).map(async chainInfo => {
229
233
  const chainState = chainStateMap[chainInfo.slug];
230
234
  if (chainState !== null && chainState !== void 0 && chainState.active && _isChainSupportSubstrateStaking(chainInfo)) {
231
- filteredChainInfoMap[chainInfo.slug] = chainInfo;
235
+ const chainStakingMetadata = await getChainStakingMetadata(chainInfo.slug, substrateApiMap[chainInfo.slug]);
236
+ this.state.updateChainStakingMetadata(chainStakingMetadata);
232
237
  }
233
- });
234
- if (Object.values(filteredChainInfoMap).length === 0) {
235
- return;
236
- }
237
- await Promise.all(Object.values(filteredChainInfoMap).map(async chainInfo => {
238
- const chainStakingMetadata = await getChainStakingMetadata(chainInfo, substrateApiMap[chainInfo.slug]);
239
- this.state.updateChainStakingMetadata(chainStakingMetadata);
240
238
  }));
241
239
  }
242
240
  async fetchNominatorMetadata(currentAddress, chainInfoMap, chainStateMap, substrateApiMap) {
@@ -251,7 +249,8 @@ export class KoniSubscription {
251
249
  if (currentAddress === ALL_ACCOUNT_KEY) {
252
250
  addresses = await this.state.getStakingOwnersByChains(Object.keys(filteredChainInfoMap));
253
251
  }
254
- await Promise.all(addresses.map(async address => {
252
+ const validAddresses = addresses.filter(address => !isEthereumAddress(address));
253
+ await Promise.all(validAddresses.map(async address => {
255
254
  const isEvmAddress = isEthereumAddress(address);
256
255
  await Promise.all(Object.values(filteredChainInfoMap).map(async chainInfo => {
257
256
  if (isEvmAddress && !_isChainEvmCompatible(chainInfo)) {