@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.
- package/background/KoniTypes.d.ts +31 -5
- package/background/KoniTypes.js +2 -1
- package/background/errors/TransactionError.js +4 -0
- package/background/types.d.ts +10 -5
- package/cjs/background/KoniTypes.js +2 -1
- package/cjs/background/errors/TransactionError.js +4 -0
- package/cjs/koni/api/dotsama/transfer.js +6 -12
- package/cjs/koni/api/nft/acala_nft/index.js +7 -10
- package/cjs/koni/api/nft/bit.country/index.js +7 -9
- package/cjs/koni/api/nft/evm_nft/index.js +2 -1
- package/cjs/koni/api/nft/karura_nft/index.js +7 -9
- package/cjs/koni/api/nft/rmrk_nft/index.js +4 -1
- package/cjs/koni/api/nft/statemine_nft/index.js +7 -9
- package/cjs/koni/api/nft/unique_nft/index.js +5 -6
- package/cjs/koni/api/nft/wasm_nft/index.js +2 -1
- package/cjs/koni/api/staking/bonding/relayChain.js +3 -0
- package/cjs/koni/background/cron.js +53 -46
- package/cjs/koni/background/handlers/Extension.js +292 -159
- package/cjs/koni/background/handlers/State.js +24 -14
- package/cjs/koni/background/handlers/Tabs.js +42 -16
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/handler/light-client/index.js +0 -2
- package/cjs/services/chain-service/index.js +53 -38
- package/cjs/services/history-service/index.js +3 -3
- package/cjs/services/history-service/subsquid-multi-chain-history.js +1 -1
- package/cjs/services/keyring-service/index.js +11 -13
- package/cjs/services/request-service/handler/AuthRequestHandler.js +7 -5
- package/cjs/services/request-service/handler/EvmRequestHandler.js +8 -12
- package/cjs/services/request-service/index.js +14 -5
- package/cjs/services/storage-service/DatabaseService.js +8 -5
- package/cjs/services/storage-service/db-stores/Nft.js +9 -4
- package/cjs/services/transaction-service/index.js +3 -1
- package/cjs/utils/address.js +10 -1
- package/cjs/utils/index.js +2 -1
- package/koni/api/dotsama/transfer.js +6 -12
- package/koni/api/nft/acala_nft/index.js +7 -9
- package/koni/api/nft/bit.country/index.js +7 -8
- package/koni/api/nft/evm_nft/index.js +2 -1
- package/koni/api/nft/index.d.ts +1 -1
- package/koni/api/nft/karura_nft/index.js +7 -8
- package/koni/api/nft/nft.d.ts +1 -1
- package/koni/api/nft/rmrk_nft/index.js +4 -1
- package/koni/api/nft/statemine_nft/index.js +7 -8
- package/koni/api/nft/unique_nft/index.js +5 -5
- package/koni/api/nft/wasm_nft/index.js +2 -1
- package/koni/api/staking/bonding/relayChain.js +3 -0
- package/koni/background/cron.js +53 -46
- package/koni/background/handlers/Extension.d.ts +6 -1
- package/koni/background/handlers/Extension.js +203 -73
- package/koni/background/handlers/State.d.ts +1 -1
- package/koni/background/handlers/State.js +26 -14
- package/koni/background/handlers/Tabs.js +42 -16
- package/package.json +13 -13
- package/packageInfo.js +1 -1
- package/services/chain-service/handler/light-client/index.d.ts +1 -17
- package/services/chain-service/handler/light-client/index.js +1 -1
- package/services/chain-service/index.d.ts +3 -2
- package/services/chain-service/index.js +47 -33
- package/services/chain-service/types.d.ts +1 -0
- package/services/history-service/index.d.ts +3 -1
- package/services/history-service/index.js +3 -3
- package/services/history-service/subsquid-multi-chain-history.js +1 -1
- package/services/keyring-service/index.d.ts +4 -2
- package/services/keyring-service/index.js +11 -13
- package/services/request-service/handler/AuthRequestHandler.d.ts +3 -1
- package/services/request-service/handler/AuthRequestHandler.js +7 -5
- package/services/request-service/handler/EvmRequestHandler.js +8 -12
- package/services/request-service/index.d.ts +3 -1
- package/services/request-service/index.js +14 -5
- package/services/storage-service/DatabaseService.d.ts +1 -1
- package/services/storage-service/DatabaseService.js +8 -5
- package/services/storage-service/db-stores/Nft.d.ts +2 -1
- package/services/storage-service/db-stores/Nft.js +9 -4
- package/services/transaction-service/index.js +3 -1
- package/utils/address.d.ts +3 -0
- package/utils/address.js +8 -1
- package/utils/index.d.ts +1 -1
- 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(
|
|
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
|
-
|
|
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(
|
|
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,
|
|
160
|
-
|
|
161
|
-
|
|
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,
|
|
27
|
+
cleanUpNfts(chain, address, collectionIds, nftIds) {
|
|
28
28
|
return this.table.where({
|
|
29
29
|
address,
|
|
30
|
-
chain
|
|
31
|
-
|
|
32
|
-
|
|
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) {
|
package/cjs/utils/address.js
CHANGED
|
@@ -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;
|
package/cjs/utils/index.js
CHANGED
|
@@ -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
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
86
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
83
|
-
|
|
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
|
-
|
|
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
|
}
|
package/koni/api/nft/index.d.ts
CHANGED
|
@@ -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
|
|
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 (
|
|
92
|
-
|
|
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
|
-
|
|
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
|
}
|
package/koni/api/nft/nft.d.ts
CHANGED
|
@@ -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
|
|
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 (
|
|
96
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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);
|
package/koni/background/cron.js
CHANGED
|
@@ -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
|
-
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
|
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;
|