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

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 (78) hide show
  1. package/background/KoniTypes.d.ts +31 -5
  2. package/background/KoniTypes.js +2 -1
  3. package/background/errors/TransactionError.js +4 -0
  4. package/background/types.d.ts +10 -5
  5. package/cjs/background/KoniTypes.js +2 -1
  6. package/cjs/background/errors/TransactionError.js +4 -0
  7. package/cjs/koni/api/dotsama/transfer.js +6 -12
  8. package/cjs/koni/api/nft/acala_nft/index.js +7 -10
  9. package/cjs/koni/api/nft/bit.country/index.js +7 -9
  10. package/cjs/koni/api/nft/evm_nft/index.js +2 -1
  11. package/cjs/koni/api/nft/karura_nft/index.js +7 -9
  12. package/cjs/koni/api/nft/rmrk_nft/index.js +4 -1
  13. package/cjs/koni/api/nft/statemine_nft/index.js +7 -9
  14. package/cjs/koni/api/nft/unique_nft/index.js +5 -6
  15. package/cjs/koni/api/nft/wasm_nft/index.js +2 -1
  16. package/cjs/koni/api/staking/bonding/relayChain.js +3 -0
  17. package/cjs/koni/background/cron.js +53 -46
  18. package/cjs/koni/background/handlers/Extension.js +292 -159
  19. package/cjs/koni/background/handlers/State.js +24 -14
  20. package/cjs/koni/background/handlers/Tabs.js +42 -16
  21. package/cjs/packageInfo.js +1 -1
  22. package/cjs/services/chain-service/handler/light-client/index.js +0 -2
  23. package/cjs/services/chain-service/index.js +53 -38
  24. package/cjs/services/history-service/index.js +3 -3
  25. package/cjs/services/history-service/subsquid-multi-chain-history.js +1 -1
  26. package/cjs/services/keyring-service/index.js +11 -13
  27. package/cjs/services/request-service/handler/AuthRequestHandler.js +7 -5
  28. package/cjs/services/request-service/handler/EvmRequestHandler.js +8 -12
  29. package/cjs/services/request-service/index.js +14 -5
  30. package/cjs/services/storage-service/DatabaseService.js +8 -5
  31. package/cjs/services/storage-service/db-stores/Nft.js +9 -4
  32. package/cjs/services/transaction-service/index.js +3 -1
  33. package/cjs/utils/address.js +10 -1
  34. package/cjs/utils/index.js +2 -1
  35. package/koni/api/dotsama/transfer.js +6 -12
  36. package/koni/api/nft/acala_nft/index.js +7 -9
  37. package/koni/api/nft/bit.country/index.js +7 -8
  38. package/koni/api/nft/evm_nft/index.js +2 -1
  39. package/koni/api/nft/index.d.ts +1 -1
  40. package/koni/api/nft/karura_nft/index.js +7 -8
  41. package/koni/api/nft/nft.d.ts +1 -1
  42. package/koni/api/nft/rmrk_nft/index.js +4 -1
  43. package/koni/api/nft/statemine_nft/index.js +7 -8
  44. package/koni/api/nft/unique_nft/index.js +5 -5
  45. package/koni/api/nft/wasm_nft/index.js +2 -1
  46. package/koni/api/staking/bonding/relayChain.js +3 -0
  47. package/koni/background/cron.js +53 -46
  48. package/koni/background/handlers/Extension.d.ts +6 -1
  49. package/koni/background/handlers/Extension.js +203 -73
  50. package/koni/background/handlers/State.d.ts +1 -1
  51. package/koni/background/handlers/State.js +26 -14
  52. package/koni/background/handlers/Tabs.js +42 -16
  53. package/package.json +13 -13
  54. package/packageInfo.js +1 -1
  55. package/services/chain-service/handler/light-client/index.d.ts +1 -17
  56. package/services/chain-service/handler/light-client/index.js +1 -1
  57. package/services/chain-service/index.d.ts +3 -2
  58. package/services/chain-service/index.js +47 -33
  59. package/services/chain-service/types.d.ts +1 -0
  60. package/services/history-service/index.d.ts +3 -1
  61. package/services/history-service/index.js +3 -3
  62. package/services/history-service/subsquid-multi-chain-history.js +1 -1
  63. package/services/keyring-service/index.d.ts +4 -2
  64. package/services/keyring-service/index.js +11 -13
  65. package/services/request-service/handler/AuthRequestHandler.d.ts +3 -1
  66. package/services/request-service/handler/AuthRequestHandler.js +7 -5
  67. package/services/request-service/handler/EvmRequestHandler.js +8 -12
  68. package/services/request-service/index.d.ts +3 -1
  69. package/services/request-service/index.js +14 -5
  70. package/services/storage-service/DatabaseService.d.ts +1 -1
  71. package/services/storage-service/DatabaseService.js +8 -5
  72. package/services/storage-service/db-stores/Nft.d.ts +2 -1
  73. package/services/storage-service/db-stores/Nft.js +9 -4
  74. package/services/transaction-service/index.js +3 -1
  75. package/utils/address.d.ts +3 -0
  76. package/utils/address.js +8 -1
  77. package/utils/index.d.ts +1 -1
  78. package/utils/index.js +1 -1
@@ -10,7 +10,6 @@ var _EvmRequestHandler = _interopRequireDefault(require("@subwallet/extension-ba
10
10
  var _MetadataRequestHandler = _interopRequireDefault(require("@subwallet/extension-base/services/request-service/handler/MetadataRequestHandler"));
11
11
  var _PopupHandler = _interopRequireDefault(require("@subwallet/extension-base/services/request-service/handler/PopupHandler"));
12
12
  var _SubstrateRequestHandler = _interopRequireDefault(require("@subwallet/extension-base/services/request-service/handler/SubstrateRequestHandler"));
13
- var _accounts = require("@subwallet/ui-keyring/observable/accounts");
14
13
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
15
14
  // SPDX-License-Identifier: Apache-2.0
16
15
 
@@ -24,12 +23,13 @@ class RequestService {
24
23
  #evmRequestHandler;
25
24
 
26
25
  // Common
27
- constructor(chainService, settingService) {
26
+ constructor(chainService, settingService, keyringService) {
27
+ this.keyringService = keyringService;
28
28
  this.#chainService = chainService;
29
29
  this.settingService = settingService;
30
30
  this.#popupHandler = new _PopupHandler.default(this);
31
31
  this.#metadataRequestHandler = new _MetadataRequestHandler.default(this);
32
- this.#authRequestHandler = new _AuthRequestHandler.default(this, this.#chainService);
32
+ this.#authRequestHandler = new _AuthRequestHandler.default(this, this.#chainService, this.keyringService);
33
33
  this.#substrateRequestHandler = new _SubstrateRequestHandler.default(this);
34
34
  this.#evmRequestHandler = new _EvmRequestHandler.default(this);
35
35
 
@@ -44,7 +44,7 @@ class RequestService {
44
44
  }
45
45
  getAddressList() {
46
46
  let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
47
- const addressList = Object.keys(_accounts.accounts.subject.value);
47
+ const addressList = Object.keys(this.keyringService.accounts);
48
48
  return addressList.reduce((addressList, v) => ({
49
49
  ...addressList,
50
50
  [v]: value
@@ -59,7 +59,16 @@ class RequestService {
59
59
  this.#popupHandler.popupClose();
60
60
  }
61
61
  popupOpen() {
62
- this.#popupHandler.popupOpen();
62
+ // Not open new popup and use existed
63
+ const popupList = this.#popupHandler.popup;
64
+ if (popupList && popupList.length > 0) {
65
+ var _chrome$windows$updat;
66
+ (_chrome$windows$updat = chrome.windows.update(popupList[0], {
67
+ focused: true
68
+ })) === null || _chrome$windows$updat === void 0 ? void 0 : _chrome$windows$updat.catch(console.error);
69
+ } else {
70
+ this.#popupHandler.popupOpen();
71
+ }
63
72
  }
64
73
 
65
74
  // Metadata
@@ -130,8 +130,8 @@ class DatabaseService {
130
130
  }
131
131
  async upsertHistory(histories) {
132
132
  // this.logger.log('Updating transaction histories');
133
-
134
- return this.stores.transaction.bulkUpsert(histories);
133
+ const cleanedHistory = histories.filter(x => x && x.address && x.chain && x.extrinsicHash);
134
+ return this.stores.transaction.bulkUpsert(cleanedHistory);
135
135
  }
136
136
 
137
137
  // NFT Collection
@@ -156,9 +156,12 @@ class DatabaseService {
156
156
  });
157
157
  return this.nftSubscription;
158
158
  }
159
- async cleanUpNft(chain, owner, collectionId, nftIds) {
160
- const result = await this.stores.nft.cleanUpNfts(chain, (0, _utils.reformatAddress)(owner, 42), collectionId, nftIds);
161
- result > 0 && console.debug(`Clean up ${result} NFTs from collection ${collectionId} on chain ${chain} for owner ${owner}`);
159
+ async cleanUpNft(chain, owner, collectionIds, nftIds, ownNothing) {
160
+ if (ownNothing) {
161
+ return this.stores.nft.deleteNftsByChainAndOwner(chain, (0, _utils.reformatAddress)(owner, 42));
162
+ }
163
+ const result = await this.stores.nft.cleanUpNfts(chain, (0, _utils.reformatAddress)(owner, 42), collectionIds, nftIds);
164
+ result > 0 && console.debug(`Cleaned up ${result} NFTs on chain ${chain} for owner ${(0, _utils.reformatAddress)(owner, 42)}`, collectionIds, nftIds);
162
165
  return result;
163
166
  }
164
167
  async getNft(addresses, chainHashes) {
@@ -24,12 +24,17 @@ class NftStore extends _BaseStoreWithAddressAndChain.default {
24
24
  let chainList = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
25
25
  return (0, _dexie.liveQuery)(() => this.getNft(addresses, chainList));
26
26
  }
27
- cleanUpNfts(chain, address, collectionId, nftIds) {
27
+ cleanUpNfts(chain, address, collectionIds, nftIds) {
28
28
  return this.table.where({
29
29
  address,
30
- chain,
31
- collectionId
32
- }).and(nft => !nftIds.includes(nft.id)).delete();
30
+ chain
31
+ }).and(nft => !collectionIds.includes(nft.collectionId) || collectionIds.includes(nft.collectionId) && !nftIds.includes(nft.id)).delete();
32
+ }
33
+ deleteNftsByChainAndOwner(chain, address) {
34
+ return this.table.where({
35
+ address,
36
+ chain
37
+ }).delete();
33
38
  }
34
39
  deleteNftByAddress(addresses) {
35
40
  return this.table.where('address').anyOfIgnoreCase(addresses).delete();
@@ -187,7 +187,6 @@ class TransactionService {
187
187
  this.transactionSubject.next({
188
188
  ...transactions
189
189
  });
190
- console.log(transaction);
191
190
 
192
191
  // Send transaction
193
192
  return await this.sendTransaction(transaction);
@@ -596,6 +595,9 @@ class TransactionService {
596
595
  payload.isToContract = isToContract;
597
596
  payload.parseData = isToContract ? payload.data ? (await (0, _parseTransaction.parseContractInput)(payload.data || '', payload.to || '', chainInfo)).result : '' : payload.data || '';
598
597
  }
598
+ if ('data' in payload && payload.data === undefined) {
599
+ delete payload.data;
600
+ }
599
601
 
600
602
  // Set unique nonce to avoid transaction errors
601
603
  if (!payload.nonce) {
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.convertSubjectInfoToAddresses = void 0;
6
7
  exports.quickFormatAddressToCompare = quickFormatAddressToCompare;
7
8
  exports.simpleAddress = void 0;
8
9
  var _index = require("@subwallet/extension-base/utils/index");
@@ -22,4 +23,12 @@ function quickFormatAddressToCompare(address) {
22
23
  return address;
23
24
  }
24
25
  return (0, _index.reformatAddress)(address, 42).toLowerCase();
25
- }
26
+ }
27
+ const convertSubjectInfoToAddresses = subjectInfo => {
28
+ return Object.values(subjectInfo).map(info => ({
29
+ address: info.json.address,
30
+ type: info.type,
31
+ ...info.json.meta
32
+ }));
33
+ };
34
+ exports.convertSubjectInfoToAddresses = convertSubjectInfoToAddresses;
@@ -52,7 +52,8 @@ exports.isEmptyArray = isEmptyArray;
52
52
  function isAccountAll(address) {
53
53
  return address === _constants.ALL_ACCOUNT_KEY;
54
54
  }
55
- function reformatAddress(address, networkPrefix) {
55
+ function reformatAddress(address) {
56
+ let networkPrefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 42;
56
57
  let isEthereum = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
57
58
  try {
58
59
  if ((0, _utilCrypto.isEthereumAddress)(address)) {
@@ -59,15 +59,17 @@ export async function checkSupportTransfer(networkKey, tokenInfo, substrateApiMa
59
59
  supportTransferAll: true
60
60
  };
61
61
  }
62
+
63
+ // TODO: need review
62
64
  if (_TRANSFER_CHAIN_GROUP.acala.includes(networkKey) && !_isNativeToken(tokenInfo) && isTxCurrenciesSupported) {
63
65
  result.supportTransfer = true;
64
- result.supportTransferAll = false;
66
+ result.supportTransferAll = true;
65
67
  } else if (_TRANSFER_CHAIN_GROUP.kintsugi.includes(networkKey) && !_isNativeToken(tokenInfo) && isTxTokensSupported) {
66
68
  result.supportTransfer = true;
67
69
  result.supportTransferAll = true;
68
70
  } else if (_TRANSFER_CHAIN_GROUP.genshiro.includes(networkKey) && !_isNativeToken(tokenInfo) && isTxEqBalancesSupported) {
69
71
  result.supportTransfer = true;
70
- result.supportTransferAll = false;
72
+ result.supportTransferAll = true;
71
73
  } else if (_TRANSFER_CHAIN_GROUP.crab.includes(networkKey) && _BALANCE_TOKEN_GROUP.crab.includes(tokenInfo.symbol)) {
72
74
  result.supportTransfer = true;
73
75
  result.supportTransferAll = true;
@@ -114,11 +116,7 @@ export const createTransferExtrinsic = async ({
114
116
  }, to, value, {});
115
117
  transferAmount = value;
116
118
  } else if (_TRANSFER_CHAIN_GROUP.acala.includes(networkKey) && !_isNativeToken(tokenInfo) && isTxCurrenciesSupported) {
117
- if (transferAll) {
118
- // currently Acala, Karura, Acala testnet do not have transfer all method for sub token
119
- } else if (value) {
120
- transfer = api.tx.currencies.transfer(to, _getTokenOnChainInfo(tokenInfo), value);
121
- }
119
+ transfer = api.tx.currencies.transfer(to, _getTokenOnChainInfo(tokenInfo), value);
122
120
  } else if (_TRANSFER_CHAIN_GROUP.kintsugi.includes(networkKey) && !_isNativeToken(tokenInfo) && isTxTokensSupported) {
123
121
  if (transferAll) {
124
122
  transfer = api.tx.tokens.transferAll(to, _getTokenOnChainInfo(tokenInfo), false);
@@ -126,11 +124,7 @@ export const createTransferExtrinsic = async ({
126
124
  transfer = api.tx.tokens.transfer(to, _getTokenOnChainInfo(tokenInfo), new BN(value));
127
125
  }
128
126
  } else if (_TRANSFER_CHAIN_GROUP.genshiro.includes(networkKey) && !_isNativeToken(tokenInfo) && isTxEqBalancesSupported) {
129
- if (transferAll) {
130
- // currently genshiro_testnet, genshiro, equilibrium_parachain do not have transfer all method for tokens
131
- } else if (value) {
132
- transfer = api.tx.eqBalances.transfer(_getTokenOnChainAssetId(tokenInfo), to, value);
133
- }
127
+ transfer = api.tx.eqBalances.transfer([_getTokenOnChainAssetId(tokenInfo)], to, value);
134
128
  } else if (!_isNativeToken(tokenInfo) && (_TRANSFER_CHAIN_GROUP.crab.includes(networkKey) || _BALANCE_TOKEN_GROUP.crab.includes(tokenInfo.symbol))) {
135
129
  if (transferAll) {
136
130
  transfer = api.tx.kton.transferAll(to, false);
@@ -72,21 +72,21 @@ export class AcalaNftApi extends BaseNftApi {
72
72
  return (await this.substrateApi.api.query.ormlNFT.tokens(assetId.classId, assetId.tokenId)).toHuman();
73
73
  }
74
74
  async handleNft(address, params) {
75
- // const start = performance.now();
76
75
  const assetIds = await this.getNfts([address]);
77
76
  try {
78
77
  if (!assetIds || assetIds.length === 0) {
78
+ params.cleanUpNfts(this.chain, address, [], [], true);
79
79
  return;
80
80
  }
81
- const collectionNftIds = {};
81
+ const collectionIds = [];
82
+ const nftIds = [];
82
83
  await Promise.all(assetIds.map(async assetId => {
83
84
  const parsedClassId = this.parseTokenId(assetId.classId);
84
85
  const parsedTokenId = this.parseTokenId(assetId.tokenId);
85
- if (collectionNftIds[parsedClassId]) {
86
- collectionNftIds[parsedClassId].push(parsedTokenId);
87
- } else {
88
- collectionNftIds[parsedClassId] = [parsedTokenId];
86
+ if (!collectionIds.includes(parsedClassId)) {
87
+ collectionIds.push(parsedClassId);
89
88
  }
89
+ nftIds.push(parsedTokenId);
90
90
  const [tokenInfo, collectionMeta] = await Promise.all([this.getTokenDetails(assetId), this.getCollectionDetails(parseInt(parsedClassId))]);
91
91
  const parsedNft = {
92
92
  id: parsedTokenId,
@@ -111,9 +111,7 @@ export class AcalaNftApi extends BaseNftApi {
111
111
  params.updateItem(this.chain, parsedNft, address);
112
112
  params.updateCollection(this.chain, parsedCollection);
113
113
  }));
114
- Object.entries(collectionNftIds).forEach(([collectionId, nftIds]) => {
115
- params.cleanUpNfts(this.chain, address, collectionId, nftIds);
116
- });
114
+ params.cleanUpNfts(this.chain, address, collectionIds, nftIds);
117
115
  } catch (e) {
118
116
  console.error('Failed to fetch acala nft', e);
119
117
  }
@@ -73,17 +73,18 @@ export class BitCountryNftApi extends BaseNftApi {
73
73
  const assetIds = await this.getNfts([address]);
74
74
  try {
75
75
  if (!assetIds || assetIds.length === 0) {
76
+ params.cleanUpNfts(this.chain, address, [], [], true);
76
77
  return;
77
78
  }
78
- const collectionNftIds = {};
79
+ const collectionIds = [];
80
+ const nftIds = [];
79
81
  await Promise.all(assetIds.map(async assetId => {
80
82
  const parsedClassId = this.parseTokenId(assetId.classId);
81
83
  const parsedTokenId = this.parseTokenId(assetId.tokenId);
82
- if (collectionNftIds[parsedClassId]) {
83
- collectionNftIds[parsedClassId].push(parsedTokenId);
84
- } else {
85
- collectionNftIds[parsedClassId] = [parsedTokenId];
84
+ if (!collectionIds.includes(parsedClassId)) {
85
+ collectionIds.push(parsedClassId);
86
86
  }
87
+ nftIds.push(parsedTokenId);
87
88
  const [tokenInfo, collectionMeta] = await Promise.all([this.getTokenDetails(assetId), this.getCollectionDetails(parsedClassId)]);
88
89
  const parsedNft = {
89
90
  id: parsedTokenId,
@@ -108,9 +109,7 @@ export class BitCountryNftApi extends BaseNftApi {
108
109
  params.updateItem(this.chain, parsedNft, address);
109
110
  params.updateCollection(this.chain, parsedCollection);
110
111
  }));
111
- Object.entries(collectionNftIds).forEach(([collectionId, nftIds]) => {
112
- params.cleanUpNfts(this.chain, address, collectionId, nftIds);
113
- });
112
+ params.cleanUpNfts(this.chain, address, collectionIds, nftIds);
114
113
  } catch (e) {
115
114
  console.error('Failed to fetch bit.country nft', e);
116
115
  }
@@ -85,6 +85,7 @@ export class EvmNftApi extends BaseNftApi {
85
85
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
86
86
  const balance = await contract.methods.balanceOf(address).call();
87
87
  if (Number(balance) === 0) {
88
+ nftParams.cleanUpNfts(this.chain, address, [smartContract], []);
88
89
  return;
89
90
  }
90
91
  const itemIndexes = [];
@@ -141,7 +142,7 @@ export class EvmNftApi extends BaseNftApi {
141
142
  };
142
143
  nftParams.updateCollection(this.chain, nftCollection);
143
144
  Object.entries(nftOwnerMap).forEach(([owner, nftIds]) => {
144
- nftParams.cleanUpNfts(this.chain, owner, smartContract, nftIds);
145
+ nftParams.cleanUpNfts(this.chain, owner, [smartContract], nftIds);
145
146
  });
146
147
  }
147
148
  }
@@ -17,5 +17,5 @@ export declare class NftHandler {
17
17
  setAddresses(addresses: string[]): void;
18
18
  private setupNftContracts;
19
19
  private setupApi;
20
- handleNfts(nftContracts: _ChainAsset[], updateItem: (chain: string, data: NftItem, owner: string) => void, updateCollection: (chain: string, data: NftCollection) => void, cleanUpNfts: (chain: string, owner: string, collectionId: string, nftIds: string[]) => void): Promise<void>;
20
+ handleNfts(nftContracts: _ChainAsset[], updateItem: (chain: string, data: NftItem, owner: string) => void, updateCollection: (chain: string, data: NftCollection) => void, cleanUpNfts: (chain: string, owner: string, collectionId: string[], nftIds: string[], ownNothing?: boolean) => void): Promise<void>;
21
21
  }
@@ -82,17 +82,18 @@ export class KaruraNftApi extends BaseNftApi {
82
82
  const assetIds = await this.getNfts([address]);
83
83
  try {
84
84
  if (!assetIds || assetIds.length === 0) {
85
+ params.cleanUpNfts(this.chain, address, [], [], true);
85
86
  return;
86
87
  }
87
- const collectionNftIds = {};
88
+ const collectionIds = [];
89
+ const nftIds = [];
88
90
  await Promise.all(assetIds.map(async assetId => {
89
91
  const parsedClassId = this.parseTokenId(assetId.classId);
90
92
  const parsedTokenId = this.parseTokenId(assetId.tokenId);
91
- if (collectionNftIds[parsedClassId]) {
92
- collectionNftIds[parsedClassId].push(parsedTokenId);
93
- } else {
94
- collectionNftIds[parsedClassId] = [parsedTokenId];
93
+ if (!collectionIds.includes(parsedClassId)) {
94
+ collectionIds.push(parsedClassId);
95
95
  }
96
+ nftIds.push(parsedTokenId);
96
97
  const [tokenInfo, collectionMeta] = await Promise.all([this.getTokenDetails(assetId), this.getCollectionDetails(parseInt(parsedClassId))]);
97
98
  const parsedNft = {
98
99
  id: parsedTokenId,
@@ -115,9 +116,7 @@ export class KaruraNftApi extends BaseNftApi {
115
116
  params.updateItem(this.chain, parsedNft, address);
116
117
  params.updateCollection(this.chain, parsedCollection);
117
118
  }));
118
- Object.entries(collectionNftIds).forEach(([collectionId, nftIds]) => {
119
- params.cleanUpNfts(this.chain, address, collectionId, nftIds);
120
- });
119
+ params.cleanUpNfts(this.chain, address, collectionIds, nftIds);
121
120
  } catch (e) {
122
121
  console.error('Failed to fetch karura nft', e);
123
122
  }
@@ -3,7 +3,7 @@ import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain
3
3
  export interface HandleNftParams {
4
4
  updateItem: (chain: string, data: NftItem, owner: string) => void;
5
5
  updateCollection: (chain: string, data: NftCollection) => void;
6
- cleanUpNfts: (chain: string, owner: string, collectionId: string, nftIds: string[]) => void;
6
+ cleanUpNfts: (chain: string, owner: string, collectionId: string[], nftIds: string[], ownNothing?: boolean) => void;
7
7
  }
8
8
  export declare abstract class BaseNftApi {
9
9
  chain: string;
@@ -132,6 +132,7 @@ export class RmrkNftApi extends BaseNftApi {
132
132
  const kusamaAddress = reformatAddress(address, 2);
133
133
  allNfts = await this.getAllByAccount(kusamaAddress);
134
134
  if (allNfts.length <= 0) {
135
+ params.cleanUpNfts(this.chain, address, [], [], true);
135
136
  return;
136
137
  }
137
138
  const collectionInfoUrl = [];
@@ -239,8 +240,10 @@ export class RmrkNftApi extends BaseNftApi {
239
240
  }
240
241
  });
241
242
  params.updateCollection(this.chain, parsedCollection);
242
- params.cleanUpNfts(this.chain, address, item.collectionId, nftIds);
243
243
  });
244
+ const allCollectionIds = allCollections.map(item => item.collectionId);
245
+ const allNftIds = allNfts.map(nft => nft === null || nft === void 0 ? void 0 : nft.id);
246
+ params.cleanUpNfts(this.chain, address, allCollectionIds, allNftIds);
244
247
  } catch (e) {
245
248
  console.error('Failed to fetch rmrk nft', e);
246
249
  }
@@ -86,17 +86,18 @@ export default class StatemineNftApi extends BaseNftApi {
86
86
  const assetIds = await this.getNfts([address]);
87
87
  try {
88
88
  if (!assetIds || assetIds.length === 0) {
89
+ params.cleanUpNfts(this.chain, address, [], [], true);
89
90
  return;
90
91
  }
91
- const collectionNftIds = {};
92
+ const collectionIds = [];
93
+ const nftIds = [];
92
94
  await Promise.all(assetIds.map(async assetId => {
93
95
  const parsedClassId = this.parseTokenId(assetId.classId);
94
96
  const parsedTokenId = this.parseTokenId(assetId.tokenId);
95
- if (collectionNftIds[parsedClassId]) {
96
- collectionNftIds[parsedClassId].push(parsedTokenId);
97
- } else {
98
- collectionNftIds[parsedClassId] = [parsedTokenId];
97
+ if (!collectionIds.includes(parsedClassId)) {
98
+ collectionIds.push(parsedClassId);
99
99
  }
100
+ nftIds.push(parsedTokenId);
100
101
  const [tokenInfo, collectionMeta] = await Promise.all([this.getTokenDetails(assetId), this.getCollectionDetail(parseInt(parsedClassId))]);
101
102
  const parsedNft = {
102
103
  id: parsedTokenId,
@@ -116,9 +117,7 @@ export default class StatemineNftApi extends BaseNftApi {
116
117
  };
117
118
  params.updateCollection(this.chain, parsedCollection);
118
119
  }));
119
- Object.entries(collectionNftIds).forEach(([collectionId, nftIds]) => {
120
- params.cleanUpNfts(this.chain, address, collectionId, nftIds);
121
- });
120
+ params.cleanUpNfts(this.chain, address, collectionIds, nftIds);
122
121
  } catch (e) {
123
122
  console.error('Failed to fetch statemine nft', e);
124
123
  }
@@ -133,7 +133,8 @@ export default class UniqueNftApi extends BaseNftApi {
133
133
  }
134
134
  }
135
135
  }));
136
- const nftCollectionMap = {};
136
+ const collectionIds = [];
137
+ let allNftIds = [];
137
138
  await Promise.all(allCollectionId.map(async collectionId => {
138
139
  const collectionIdStr = collectionId.toString();
139
140
 
@@ -141,7 +142,8 @@ export default class UniqueNftApi extends BaseNftApi {
141
142
  const collection = (await this.substrateApi.api.query.nft.collectionById(collectionId)).toJSON();
142
143
  collectionMap[collectionIdStr] = collection;
143
144
  const nftIds = Object.entries(nftMap).filter(item => item[1] === collectionId).map(item => item[0]);
144
- nftCollectionMap[collectionIdStr] = nftIds;
145
+ collectionIds.push(collectionIdStr);
146
+ allNftIds = allNftIds.concat(nftIds);
145
147
  const parsedCollection = {
146
148
  collectionId: collectionIdStr,
147
149
  chain: this.chain
@@ -171,9 +173,7 @@ export default class UniqueNftApi extends BaseNftApi {
171
173
  }
172
174
  }));
173
175
  }));
174
- Object.entries(nftCollectionMap).forEach(([collectionId, nftIds]) => {
175
- params.cleanUpNfts(this.chain, address, collectionId, nftIds);
176
- });
176
+ params.cleanUpNfts(this.chain, address, collectionIds, allNftIds);
177
177
  } catch (e) {
178
178
  console.error('Failed to fetch unique nft', e);
179
179
  }
@@ -261,6 +261,7 @@ export class WasmNftApi extends BaseNftApi {
261
261
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
262
262
  const balance = _balance.output ? balanceJson.ok || balanceJson.Ok : '0';
263
263
  if (parseInt(balance) === 0) {
264
+ nftParams.cleanUpNfts(this.chain, address, [smartContract], []);
264
265
  return;
265
266
  }
266
267
  const itemIndexes = [];
@@ -316,7 +317,7 @@ export class WasmNftApi extends BaseNftApi {
316
317
  };
317
318
  nftParams.updateCollection(this.chain, nftCollection);
318
319
  Object.entries(nftOwnerMap).forEach(([owner, nftIds]) => {
319
- nftParams.cleanUpNfts(this.chain, owner, smartContract, nftIds);
320
+ nftParams.cleanUpNfts(this.chain, owner, [smartContract], nftIds);
320
321
  });
321
322
  }
322
323
  }
@@ -28,6 +28,9 @@ export function validatePoolBondingCondition(chainInfo, amount, selectedPool, ad
28
28
  const errors = [];
29
29
  let bnTotalStake = new BN(amount);
30
30
  const bnMinStake = new BN(chainStakingMetadata.minPoolBonding || '0');
31
+ if (selectedPool.state !== 'Open') {
32
+ errors.push(new TransactionError(StakingTxErrorType.INACTIVE_NOMINATION_POOL));
33
+ }
31
34
  if (nominatorMetadata) {
32
35
  const bnCurrentActiveStake = new BN(nominatorMetadata.activeStake);
33
36
  bnTotalStake = bnTotalStake.add(bnCurrentActiveStake);
@@ -2,7 +2,6 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { CRON_AUTO_RECOVER_DOTSAMA_INTERVAL, CRON_GET_API_MAP_STATUS, CRON_REFRESH_CHAIN_NOMINATOR_METADATA, CRON_REFRESH_CHAIN_STAKING_METADATA, CRON_REFRESH_NFT_INTERVAL, CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL, CRON_REFRESH_STAKING_REWARD_INTERVAL } from '@subwallet/extension-base/constants';
5
- import { _ChainConnectionStatus } from '@subwallet/extension-base/services/chain-service/types';
6
5
  import { _isChainSupportEvmNft, _isChainSupportNativeNft, _isChainSupportSubstrateStaking, _isChainSupportWasmNft } from '@subwallet/extension-base/services/chain-service/utils';
7
6
  import { waitTimeout } from '@subwallet/extension-base/utils';
8
7
  import { Subject } from 'rxjs';
@@ -74,23 +73,7 @@ export class KoniCron {
74
73
  if (this.status === 'running') {
75
74
  return;
76
75
  }
77
- this.logger.log('Starting cron jobs');
78
76
  const currentAccountInfo = this.state.keyringService.currentAccount;
79
- if (!(currentAccountInfo !== null && currentAccountInfo !== void 0 && currentAccountInfo.address)) {
80
- return;
81
- }
82
- if (Object.keys(this.state.getSubstrateApiMap()).length !== 0 || Object.keys(this.state.getEvmApiMap()).length !== 0) {
83
- this.resetNft(currentAccountInfo.address);
84
- this.addCron('refreshNft', this.refreshNft(currentAccountInfo.address, this.state.getApiMap(), this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap()), CRON_REFRESH_NFT_INTERVAL);
85
- this.addCron('checkStatusApiMap', this.updateApiMapStatus, CRON_GET_API_MAP_STATUS);
86
- this.addCron('recoverApiMap', this.recoverApiMap, CRON_AUTO_RECOVER_DOTSAMA_INTERVAL, false);
87
- this.addCron('refreshStakingReward', this.refreshStakingReward(currentAccountInfo.address), CRON_REFRESH_STAKING_REWARD_INTERVAL);
88
- this.addCron('refreshPoolingStakingReward', this.refreshStakingRewardFastInterval(currentAccountInfo.address), CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL);
89
- this.addCron('updateChainStakingMetadata', this.updateChainStakingMetadata(this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap()), CRON_REFRESH_CHAIN_STAKING_METADATA);
90
- this.addCron('updateNominatorMetadata', this.updateNominatorMetadata(currentAccountInfo.address, this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap()), CRON_REFRESH_CHAIN_NOMINATOR_METADATA);
91
- } else {
92
- this.setStakingRewardReady();
93
- }
94
77
  const commonReloadEvents = ['account.add', 'account.remove', 'account.updateCurrent', 'chain.add', 'asset.updateState'];
95
78
  this.eventHandler = (events, eventTypes) => {
96
79
  var _serviceInfo$currentA;
@@ -136,7 +119,7 @@ export class KoniCron {
136
119
  if (this.checkNetworkAvailable(serviceInfo)) {
137
120
  // only add cron job if there's at least 1 active network
138
121
  (commonReload || needUpdateNft) && this.addCron('refreshNft', this.refreshNft(address, serviceInfo.chainApiMap, this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap()), CRON_REFRESH_NFT_INTERVAL);
139
- chainUpdated && this.addCron('checkStatusApiMap', this.updateApiMapStatus, CRON_GET_API_MAP_STATUS);
122
+ chainUpdated && this.addCron('checkStatusApiMap', this.updateApiMapStatus, CRON_GET_API_MAP_STATUS, false);
140
123
  chainUpdated && this.addCron('recoverApiMap', this.recoverApiMap, CRON_AUTO_RECOVER_DOTSAMA_INTERVAL, false);
141
124
  (commonReload || needUpdateStaking || stakingSubmitted) && this.addCron('refreshStakingReward', this.refreshStakingReward(address), CRON_REFRESH_STAKING_REWARD_INTERVAL);
142
125
  (commonReload || needUpdateStaking || stakingSubmitted) && this.addCron('refreshPoolingStakingReward', this.refreshStakingRewardFastInterval(address), CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL);
@@ -147,6 +130,22 @@ export class KoniCron {
147
130
  }
148
131
  };
149
132
  this.state.eventService.onLazy(this.eventHandler);
133
+ if (!(currentAccountInfo !== null && currentAccountInfo !== void 0 && currentAccountInfo.address)) {
134
+ return;
135
+ }
136
+ this.logger.log('Starting cron jobs');
137
+ if (Object.keys(this.state.getSubstrateApiMap()).length !== 0 || Object.keys(this.state.getEvmApiMap()).length !== 0) {
138
+ this.resetNft(currentAccountInfo.address);
139
+ this.addCron('refreshNft', this.refreshNft(currentAccountInfo.address, this.state.getApiMap(), this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap()), CRON_REFRESH_NFT_INTERVAL);
140
+ this.addCron('checkStatusApiMap', this.updateApiMapStatus, CRON_GET_API_MAP_STATUS);
141
+ this.addCron('recoverApiMap', this.recoverApiMap, CRON_AUTO_RECOVER_DOTSAMA_INTERVAL, false);
142
+ this.addCron('refreshStakingReward', this.refreshStakingReward(currentAccountInfo.address), CRON_REFRESH_STAKING_REWARD_INTERVAL);
143
+ this.addCron('refreshPoolingStakingReward', this.refreshStakingRewardFastInterval(currentAccountInfo.address), CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL);
144
+ this.addCron('updateChainStakingMetadata', this.updateChainStakingMetadata(this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap()), CRON_REFRESH_CHAIN_STAKING_METADATA);
145
+ this.addCron('updateNominatorMetadata', this.updateNominatorMetadata(currentAccountInfo.address, this.state.getChainInfoMap(), this.state.getChainStateMap(), this.state.getSubstrateApiMap()), CRON_REFRESH_CHAIN_NOMINATOR_METADATA);
146
+ } else {
147
+ this.setStakingRewardReady();
148
+ }
150
149
  this.status = 'running';
151
150
  };
152
151
  stop = () => {
@@ -168,35 +167,43 @@ export class KoniCron {
168
167
  this.status = 'stopped';
169
168
  };
170
169
  updateApiMapStatus = () => {
171
- const apiMap = this.state.getApiMap();
172
- const networkMap = this.state.getChainStateMap();
173
- for (const [key, substrateApi] of Object.entries(apiMap.substrate)) {
174
- let status = _ChainConnectionStatus.CONNECTING;
175
- if (substrateApi.isApiConnected) {
176
- status = _ChainConnectionStatus.CONNECTED;
177
- }
178
- if (!networkMap[key].connectionStatus) {
179
- this.state.updateChainConnectionStatus(key, status);
180
- } else if (networkMap[key].connectionStatus && networkMap[key].connectionStatus !== status) {
181
- this.state.updateChainConnectionStatus(key, status);
182
- }
183
- }
184
- for (const [key, evmApi] of Object.entries(apiMap.evm)) {
185
- evmApi.api.eth.net.isListening().then(() => {
186
- if (!networkMap[key].connectionStatus) {
187
- this.state.updateChainConnectionStatus(key, _ChainConnectionStatus.CONNECTED);
188
- } else if (networkMap[key].connectionStatus && networkMap[key].connectionStatus !== _ChainConnectionStatus.CONNECTED) {
189
- this.state.updateChainConnectionStatus(key, _ChainConnectionStatus.CONNECTED);
190
- }
191
- }).catch(() => {
192
- if (!networkMap[key].connectionStatus) {
193
- this.state.updateChainConnectionStatus(key, _ChainConnectionStatus.CONNECTING);
194
- } else if (networkMap[key].connectionStatus && networkMap[key].connectionStatus !== _ChainConnectionStatus.CONNECTING) {
195
- this.state.updateChainConnectionStatus(key, _ChainConnectionStatus.CONNECTING);
196
- }
197
- });
198
- }
170
+ this.state.chainService.updateApiMapStatus().catch(console.error);
171
+ // const apiMap = this.state.getApiMap();
172
+ // const networkMap = this.state.getChainStateMap();
173
+ //
174
+ // for (const [key, substrateApi] of Object.entries(apiMap.substrate)) {
175
+ // let status: _ChainConnectionStatus = _ChainConnectionStatus.CONNECTING;
176
+ //
177
+ // if (substrateApi.isApiConnected) {
178
+ // status = _ChainConnectionStatus.CONNECTED;
179
+ // }
180
+ //
181
+ // if (!networkMap[key].connectionStatus) {
182
+ // this.state.updateChainConnectionStatus(key, status);
183
+ // } else if (networkMap[key].connectionStatus && networkMap[key].connectionStatus !== status) {
184
+ // this.state.updateChainConnectionStatus(key, status);
185
+ // }
186
+ // }
187
+ //
188
+ // for (const [key, evmApi] of Object.entries(apiMap.evm)) {
189
+ // evmApi.api.eth.net.isListening()
190
+ // .then(() => {
191
+ // if (!networkMap[key].connectionStatus) {
192
+ // this.state.updateChainConnectionStatus(key, _ChainConnectionStatus.CONNECTED);
193
+ // } else if (networkMap[key].connectionStatus && networkMap[key].connectionStatus !== _ChainConnectionStatus.CONNECTED) {
194
+ // this.state.updateChainConnectionStatus(key, _ChainConnectionStatus.CONNECTED);
195
+ // }
196
+ // })
197
+ // .catch(() => {
198
+ // if (!networkMap[key].connectionStatus) {
199
+ // this.state.updateChainConnectionStatus(key, _ChainConnectionStatus.CONNECTING);
200
+ // } else if (networkMap[key].connectionStatus && networkMap[key].connectionStatus !== _ChainConnectionStatus.CONNECTING) {
201
+ // this.state.updateChainConnectionStatus(key, _ChainConnectionStatus.CONNECTING);
202
+ // }
203
+ // });
204
+ // }
199
205
  };
206
+
200
207
  recoverApiMap = () => {
201
208
  var _this$subscriptions;
202
209
  const apiMap = this.state.getApiMap();
@@ -39,7 +39,10 @@ export default class KoniExtension {
39
39
  private checkPublicAndSecretKey;
40
40
  private accountsGetAllWithCurrentAddress;
41
41
  private accountsGetAll;
42
- private saveRecentAccountId;
42
+ private subscribeAddresses;
43
+ private saveRecentAccount;
44
+ private editContactAccount;
45
+ private deleteContactAccount;
43
46
  private _getAuthListV2;
44
47
  private authorizeSubscribeV2;
45
48
  private getAuthListV2;
@@ -107,6 +110,7 @@ export default class KoniExtension {
107
110
  private getStaking;
108
111
  private subscribeStaking;
109
112
  private subscribeHistory;
113
+ private addContact;
110
114
  private validateTransfer;
111
115
  private makeTransfer;
112
116
  private validateCrossChainTransfer;
@@ -123,6 +127,7 @@ export default class KoniExtension {
123
127
  private deleteCustomAsset;
124
128
  private validateCustomAsset;
125
129
  private getAddressFreeBalance;
130
+ private transferGetMaxTransferable;
126
131
  private subscribeAddressFreeBalance;
127
132
  private transferCheckReferenceCount;
128
133
  private transferCheckSupporting;