@subwallet/extension-base 1.1.15-0 → 1.1.16-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/background/KoniTypes.d.ts +1 -1
- package/background/handlers/Extension.js +2 -2
- package/background/types.d.ts +2 -2
- package/cjs/background/handlers/Extension.js +2 -2
- package/cjs/koni/api/nft/index.js +3 -0
- package/cjs/koni/api/nft/statemint_nft/index.js +143 -0
- package/cjs/koni/api/nft/transfer.js +12 -1
- package/cjs/koni/background/handlers/Extension.js +4 -4
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/constants.js +2 -1
- package/cjs/services/keyring-service/index.js +32 -0
- package/koni/api/nft/index.js +3 -0
- package/koni/api/nft/statemint_nft/index.d.ts +18 -0
- package/koni/api/nft/statemint_nft/index.js +135 -0
- package/koni/api/nft/transfer.d.ts +1 -0
- package/koni/api/nft/transfer.js +11 -1
- package/koni/background/handlers/Extension.js +4 -4
- package/package.json +11 -6
- package/packageInfo.js +1 -1
- package/services/chain-service/constants.d.ts +1 -0
- package/services/chain-service/constants.js +2 -1
- package/services/keyring-service/index.js +32 -0
|
@@ -1600,7 +1600,7 @@ export interface KoniRequestSignatures {
|
|
|
1600
1600
|
'pri(mantaPay.subscribeSyncingState)': [null, MantaPaySyncState, MantaPaySyncState];
|
|
1601
1601
|
'pri(mantaPay.initSyncMantaPay)': [string, null];
|
|
1602
1602
|
'pri(authorize.listV2)': [null, ResponseAuthorizeList];
|
|
1603
|
-
'pri(authorize.requestsV2)': [RequestAuthorizeSubscribe,
|
|
1603
|
+
'pri(authorize.requestsV2)': [RequestAuthorizeSubscribe, AuthorizeRequest[], AuthorizeRequest[]];
|
|
1604
1604
|
'pri(authorize.approveV2)': [RequestAuthorizeApproveV2, boolean];
|
|
1605
1605
|
'pri(authorize.changeSiteAll)': [RequestAuthorizationAll, boolean, AuthUrls];
|
|
1606
1606
|
'pri(authorize.changeSite)': [RequestAuthorization, boolean, AuthUrls];
|
|
@@ -264,7 +264,7 @@ export default class Extension {
|
|
|
264
264
|
unsubscribe(id);
|
|
265
265
|
subscription.unsubscribe();
|
|
266
266
|
});
|
|
267
|
-
return
|
|
267
|
+
return this.#state.metaSubject.value;
|
|
268
268
|
}
|
|
269
269
|
jsonRestore({
|
|
270
270
|
file,
|
|
@@ -444,7 +444,7 @@ export default class Extension {
|
|
|
444
444
|
unsubscribe(id);
|
|
445
445
|
subscription.unsubscribe();
|
|
446
446
|
});
|
|
447
|
-
return
|
|
447
|
+
return this.#state.signSubject.value;
|
|
448
448
|
}
|
|
449
449
|
windowOpen({
|
|
450
450
|
allowedPath: path,
|
package/background/types.d.ts
CHANGED
|
@@ -116,7 +116,7 @@ export interface RequestSignatures extends KoniRequestSignatures {
|
|
|
116
116
|
'pri(metadata.approve)': [RequestMetadataApprove, boolean];
|
|
117
117
|
'pri(metadata.get)': [string | null, MetadataDef | null];
|
|
118
118
|
'pri(metadata.reject)': [RequestMetadataReject, boolean];
|
|
119
|
-
'pri(metadata.requests)': [RequestMetadataSubscribe,
|
|
119
|
+
'pri(metadata.requests)': [RequestMetadataSubscribe, MetadataRequest[], MetadataRequest[]];
|
|
120
120
|
'pri(metadata.list)': [null, MetadataDef[]];
|
|
121
121
|
'pri(seed.create)': [RequestSeedCreate, ResponseSeedCreate];
|
|
122
122
|
'pri(seed.validate)': [RequestSeedValidate, ResponseSeedValidate];
|
|
@@ -125,7 +125,7 @@ export interface RequestSignatures extends KoniRequestSignatures {
|
|
|
125
125
|
'pri(signing.approve.signature)': [RequestSigningApproveSignature, boolean];
|
|
126
126
|
'pri(signing.cancel)': [RequestSigningCancel, boolean];
|
|
127
127
|
'pri(signing.isLocked)': [RequestSigningIsLocked, ResponseSigningIsLocked];
|
|
128
|
-
'pri(signing.requests)': [RequestSigningSubscribe,
|
|
128
|
+
'pri(signing.requests)': [RequestSigningSubscribe, SigningRequest[], SigningRequest[]];
|
|
129
129
|
'pri(window.open)': [WindowOpenParams, boolean];
|
|
130
130
|
'pub(accounts.list)': [RequestAccountList, InjectedAccount[]];
|
|
131
131
|
'pub(accounts.subscribe)': [RequestAccountSubscribe, boolean, InjectedAccount[]];
|
|
@@ -293,7 +293,7 @@ class Extension {
|
|
|
293
293
|
(0, _subscriptions.unsubscribe)(id);
|
|
294
294
|
subscription.unsubscribe();
|
|
295
295
|
});
|
|
296
|
-
return
|
|
296
|
+
return this.#state.metaSubject.value;
|
|
297
297
|
}
|
|
298
298
|
jsonRestore(_ref16) {
|
|
299
299
|
let {
|
|
@@ -481,7 +481,7 @@ class Extension {
|
|
|
481
481
|
(0, _subscriptions.unsubscribe)(id);
|
|
482
482
|
subscription.unsubscribe();
|
|
483
483
|
});
|
|
484
|
-
return
|
|
484
|
+
return this.#state.signSubject.value;
|
|
485
485
|
}
|
|
486
486
|
windowOpen(_ref24) {
|
|
487
487
|
let {
|
|
@@ -16,6 +16,7 @@ var _wasm_nft = require("@subwallet/extension-base/koni/api/nft/wasm_nft");
|
|
|
16
16
|
var _constants = require("@subwallet/extension-base/services/chain-service/constants");
|
|
17
17
|
var _utils = require("@subwallet/extension-base/services/chain-service/utils");
|
|
18
18
|
var _utils2 = require("@subwallet/extension-base/utils");
|
|
19
|
+
var _statemint_nft = _interopRequireDefault(require("./statemint_nft"));
|
|
19
20
|
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
20
21
|
// SPDX-License-Identifier: Apache-2.0
|
|
21
22
|
|
|
@@ -29,6 +30,8 @@ function createSubstrateNftApi(chain, substrateApi, addresses) {
|
|
|
29
30
|
return new _rmrk_nft.RmrkNftApi(substrateAddresses, chain);
|
|
30
31
|
} else if (_constants._NFT_CHAIN_GROUP.statemine.includes(chain)) {
|
|
31
32
|
return new _statemine_nft.default(substrateApi, substrateAddresses, chain);
|
|
33
|
+
} else if (_constants._NFT_CHAIN_GROUP.statemint.includes(chain)) {
|
|
34
|
+
return new _statemint_nft.default(substrateApi, substrateAddresses, chain);
|
|
32
35
|
} else if (_constants._NFT_CHAIN_GROUP.unique_network.includes(chain)) {
|
|
33
36
|
return new _unique_nft.default(substrateApi, substrateAddresses, chain);
|
|
34
37
|
} else if (_constants._NFT_CHAIN_GROUP.bitcountry.includes(chain)) {
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _nft = require("@subwallet/extension-base/koni/api/nft/nft");
|
|
9
|
+
var _utils = require("@subwallet/extension-base/utils");
|
|
10
|
+
var _crossFetch = _interopRequireDefault(require("cross-fetch"));
|
|
11
|
+
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
12
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
13
|
+
|
|
14
|
+
class StatemintNftApi extends _nft.BaseNftApi {
|
|
15
|
+
// eslint-disable-next-line no-useless-constructor
|
|
16
|
+
constructor(api, addresses, chain) {
|
|
17
|
+
super(chain, api, addresses);
|
|
18
|
+
}
|
|
19
|
+
getMetadata(metadataUrl) {
|
|
20
|
+
let url = metadataUrl;
|
|
21
|
+
if (!(0, _utils.isUrl)(metadataUrl)) {
|
|
22
|
+
url = this.parseUrl(metadataUrl);
|
|
23
|
+
if (!url || url.length === 0) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return (0, _crossFetch.default)(url, {
|
|
28
|
+
method: 'GET',
|
|
29
|
+
headers: {
|
|
30
|
+
'Content-Type': 'application/json'
|
|
31
|
+
}
|
|
32
|
+
}).then(res => res.json());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Retrieve id of NFTs
|
|
37
|
+
*
|
|
38
|
+
* @returns the array of NFT Ids
|
|
39
|
+
* @param addresses
|
|
40
|
+
*/
|
|
41
|
+
async getNfts(addresses) {
|
|
42
|
+
if (!this.substrateApi) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
const assetIds = [];
|
|
46
|
+
await Promise.all(addresses.map(async address => {
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
const resp = await this.substrateApi.api.query.nfts.account.keys(address);
|
|
49
|
+
if (resp) {
|
|
50
|
+
for (const key of resp) {
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
52
|
+
const data = key.toHuman();
|
|
53
|
+
assetIds.push({
|
|
54
|
+
classId: data[1],
|
|
55
|
+
tokenId: this.parseTokenId(data[2])
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}));
|
|
60
|
+
return assetIds;
|
|
61
|
+
}
|
|
62
|
+
async getTokenDetails(assetId) {
|
|
63
|
+
if (!this.substrateApi) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const {
|
|
67
|
+
classId,
|
|
68
|
+
tokenId
|
|
69
|
+
} = assetId;
|
|
70
|
+
const metadataNft = (await this.substrateApi.api.query.nfts.itemMetadataOf(this.parseTokenId(classId), this.parseTokenId(tokenId))).toHuman();
|
|
71
|
+
if (!(metadataNft !== null && metadataNft !== void 0 && metadataNft.data)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
return this.getMetadata(metadataNft === null || metadataNft === void 0 ? void 0 : metadataNft.data);
|
|
77
|
+
}
|
|
78
|
+
async getCollectionDetail(collectionId) {
|
|
79
|
+
if (!this.substrateApi) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const collectionMetadata = (await this.substrateApi.api.query.nfts.collectionMetadataOf(collectionId)).toHuman();
|
|
83
|
+
if (!(collectionMetadata !== null && collectionMetadata !== void 0 && collectionMetadata.data)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
return this.getMetadata(collectionMetadata === null || collectionMetadata === void 0 ? void 0 : collectionMetadata.data);
|
|
89
|
+
}
|
|
90
|
+
async handleNft(address, params) {
|
|
91
|
+
// const start = performance.now();
|
|
92
|
+
|
|
93
|
+
const assetIds = await this.getNfts([address]);
|
|
94
|
+
try {
|
|
95
|
+
if (!assetIds || assetIds.length === 0) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const collectionIds = [];
|
|
99
|
+
const nftIds = [];
|
|
100
|
+
await Promise.all(assetIds.map(async assetId => {
|
|
101
|
+
const parsedClassId = this.parseTokenId(assetId.classId);
|
|
102
|
+
const parsedTokenId = this.parseTokenId(assetId.tokenId);
|
|
103
|
+
if (!collectionIds.includes(parsedClassId)) {
|
|
104
|
+
collectionIds.push(parsedClassId);
|
|
105
|
+
}
|
|
106
|
+
nftIds.push(parsedTokenId);
|
|
107
|
+
const [tokenInfo, collectionMeta] = await Promise.all([this.getTokenDetails(assetId), this.getCollectionDetail(parseInt(parsedClassId))]);
|
|
108
|
+
const parsedNft = {
|
|
109
|
+
id: parsedTokenId,
|
|
110
|
+
name: tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.name,
|
|
111
|
+
description: tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.description,
|
|
112
|
+
image: tokenInfo && tokenInfo.image ? this.parseUrl(tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.image) : undefined,
|
|
113
|
+
collectionId: this.parseTokenId(parsedClassId),
|
|
114
|
+
chain: this.chain,
|
|
115
|
+
owner: address
|
|
116
|
+
};
|
|
117
|
+
params.updateItem(this.chain, parsedNft, address);
|
|
118
|
+
const parsedCollection = {
|
|
119
|
+
collectionId: parsedClassId,
|
|
120
|
+
chain: this.chain,
|
|
121
|
+
collectionName: collectionMeta === null || collectionMeta === void 0 ? void 0 : collectionMeta.name,
|
|
122
|
+
image: collectionMeta && collectionMeta.image ? this.parseUrl(collectionMeta === null || collectionMeta === void 0 ? void 0 : collectionMeta.image) : undefined
|
|
123
|
+
};
|
|
124
|
+
params.updateCollection(this.chain, parsedCollection);
|
|
125
|
+
}));
|
|
126
|
+
} catch (e) {
|
|
127
|
+
console.error(`${this.chain}`, e);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async handleNfts(params) {
|
|
131
|
+
await Promise.all(this.addresses.map(address => this.handleNft(address, params)));
|
|
132
|
+
}
|
|
133
|
+
async fetchNfts(params) {
|
|
134
|
+
try {
|
|
135
|
+
await this.connect();
|
|
136
|
+
await this.handleNfts(params);
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return 0;
|
|
139
|
+
}
|
|
140
|
+
return 1;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.default = StatemintNftApi;
|
|
@@ -9,6 +9,7 @@ exports.isRecipientSelf = isRecipientSelf;
|
|
|
9
9
|
exports.quartzGetExtrinsic = quartzGetExtrinsic;
|
|
10
10
|
exports.rmrkGetExtrinsic = rmrkGetExtrinsic;
|
|
11
11
|
exports.statemineGetExtrinsic = statemineGetExtrinsic;
|
|
12
|
+
exports.statemintGetExtrinsic = statemintGetExtrinsic;
|
|
12
13
|
exports.uniqueGetExtrinsic = uniqueGetExtrinsic;
|
|
13
14
|
var _config = require("@subwallet/extension-base/koni/api/nft/config");
|
|
14
15
|
var _utils = require("@subwallet/extension-base/utils");
|
|
@@ -75,6 +76,16 @@ function statemineGetExtrinsic(substrateApi, senderAddress, recipientAddress, pa
|
|
|
75
76
|
return null;
|
|
76
77
|
}
|
|
77
78
|
}
|
|
79
|
+
function statemintGetExtrinsic(substrateApi, senderAddress, recipientAddress, params) {
|
|
80
|
+
try {
|
|
81
|
+
const itemId = params.itemId;
|
|
82
|
+
const collectionId = params.collectionId;
|
|
83
|
+
return substrateApi.api.tx.nfts.transfer(collectionId, itemId, recipientAddress);
|
|
84
|
+
} catch (e) {
|
|
85
|
+
console.error(e);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
78
89
|
function getNftTransferExtrinsic(networkKey, substrateApi, senderAddress, recipientAddress, params) {
|
|
79
90
|
switch (networkKey) {
|
|
80
91
|
case _config.SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.acala:
|
|
@@ -92,7 +103,7 @@ function getNftTransferExtrinsic(networkKey, substrateApi, senderAddress, recipi
|
|
|
92
103
|
case _config.SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.statemine:
|
|
93
104
|
return statemineGetExtrinsic(substrateApi, senderAddress, recipientAddress, params);
|
|
94
105
|
case _config.SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.statemint:
|
|
95
|
-
return
|
|
106
|
+
return statemintGetExtrinsic(substrateApi, senderAddress, recipientAddress, params);
|
|
96
107
|
case _config.SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.bitcountry:
|
|
97
108
|
return acalaGetExtrinsic(substrateApi, senderAddress, recipientAddress, params);
|
|
98
109
|
case _config.SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.pioneer:
|
|
@@ -270,7 +270,7 @@ class KoniExtension {
|
|
|
270
270
|
this.cancelSubscription(id);
|
|
271
271
|
subscription.unsubscribe();
|
|
272
272
|
});
|
|
273
|
-
return
|
|
273
|
+
return this.#koniState.metaSubject.value;
|
|
274
274
|
}
|
|
275
275
|
jsonRestore(_ref12) {
|
|
276
276
|
let {
|
|
@@ -392,7 +392,7 @@ class KoniExtension {
|
|
|
392
392
|
this.cancelSubscription(id);
|
|
393
393
|
subscription.unsubscribe();
|
|
394
394
|
});
|
|
395
|
-
return
|
|
395
|
+
return this.#koniState.signSubject.value;
|
|
396
396
|
}
|
|
397
397
|
windowOpen(_ref18) {
|
|
398
398
|
let {
|
|
@@ -633,7 +633,7 @@ class KoniExtension {
|
|
|
633
633
|
port.onDisconnect.addListener(() => {
|
|
634
634
|
this.cancelSubscription(id);
|
|
635
635
|
});
|
|
636
|
-
return
|
|
636
|
+
return this.#koniState.authSubjectV2.value;
|
|
637
637
|
}
|
|
638
638
|
async getAuthListV2() {
|
|
639
639
|
const authList = await this._getAuthListV2();
|
|
@@ -3324,7 +3324,7 @@ class KoniExtension {
|
|
|
3324
3324
|
const wcId = request.request.id;
|
|
3325
3325
|
const params = request.request.params;
|
|
3326
3326
|
const requiredNamespaces = params.requiredNamespaces;
|
|
3327
|
-
const optionalNamespaces = params.optionalNamespaces;
|
|
3327
|
+
const optionalNamespaces = params.optionalNamespaces || {};
|
|
3328
3328
|
const availableNamespaces = {};
|
|
3329
3329
|
const namespaces = {};
|
|
3330
3330
|
const chainInfoMap = this.#koniState.getChainInfoMap();
|
package/cjs/packageInfo.js
CHANGED
|
@@ -53,7 +53,8 @@ const _NFT_CHAIN_GROUP = {
|
|
|
53
53
|
karura: ['karura'],
|
|
54
54
|
// TODO: karura and acala should be the same
|
|
55
55
|
rmrk: ['kusama'],
|
|
56
|
-
statemine: ['statemine'
|
|
56
|
+
statemine: ['statemine'],
|
|
57
|
+
statemint: ['statemint'],
|
|
57
58
|
unique_network: ['unique_network'],
|
|
58
59
|
bitcountry: ['bitcountry', 'pioneer']
|
|
59
60
|
};
|
|
@@ -117,8 +117,40 @@ class KeyringService {
|
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
119
|
}));
|
|
120
|
+
const currentAddress = this.currentAccountSubject.value.address;
|
|
121
|
+
const afterAccounts = {};
|
|
122
|
+
Object.keys(this.accounts).forEach(adr => {
|
|
123
|
+
afterAccounts[adr] = true;
|
|
124
|
+
});
|
|
125
|
+
accounts.forEach(value => {
|
|
126
|
+
afterAccounts[value.address] = true;
|
|
127
|
+
});
|
|
128
|
+
if (Object.keys(afterAccounts).length === 1) {
|
|
129
|
+
this.currentAccountSubject.next({
|
|
130
|
+
address: Object.keys(afterAccounts)[0],
|
|
131
|
+
currentGenesisHash: null
|
|
132
|
+
});
|
|
133
|
+
} else if (Object.keys(afterAccounts).indexOf(currentAddress) === -1) {
|
|
134
|
+
this.currentAccountSubject.next({
|
|
135
|
+
address: _constants.ALL_ACCOUNT_KEY,
|
|
136
|
+
currentGenesisHash: null
|
|
137
|
+
});
|
|
138
|
+
}
|
|
120
139
|
}
|
|
121
140
|
removeInjectAccounts(addresses) {
|
|
141
|
+
const currentAddress = this.currentAccountSubject.value.address;
|
|
142
|
+
const afterAccounts = Object.keys(this.accounts).filter(address => addresses.indexOf(address) < 0);
|
|
143
|
+
if (afterAccounts.length === 1) {
|
|
144
|
+
this.currentAccountSubject.next({
|
|
145
|
+
address: afterAccounts[0],
|
|
146
|
+
currentGenesisHash: null
|
|
147
|
+
});
|
|
148
|
+
} else if (addresses.indexOf(currentAddress) === -1) {
|
|
149
|
+
this.currentAccountSubject.next({
|
|
150
|
+
address: _constants.ALL_ACCOUNT_KEY,
|
|
151
|
+
currentGenesisHash: null
|
|
152
|
+
});
|
|
153
|
+
}
|
|
122
154
|
_uiKeyring.keyring.removeInjects(addresses);
|
|
123
155
|
}
|
|
124
156
|
|
package/koni/api/nft/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import { WasmNftApi } from '@subwallet/extension-base/koni/api/nft/wasm_nft';
|
|
|
12
12
|
import { _NFT_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
13
13
|
import { _isChainSupportEvmNft, _isChainSupportNativeNft, _isChainSupportWasmNft } from '@subwallet/extension-base/services/chain-service/utils';
|
|
14
14
|
import { categoryAddresses } from '@subwallet/extension-base/utils';
|
|
15
|
+
import StatemintNftApi from "./statemint_nft/index.js";
|
|
15
16
|
function createSubstrateNftApi(chain, substrateApi, addresses) {
|
|
16
17
|
const [substrateAddresses] = categoryAddresses(addresses);
|
|
17
18
|
if (_NFT_CHAIN_GROUP.acala.includes(chain)) {
|
|
@@ -22,6 +23,8 @@ function createSubstrateNftApi(chain, substrateApi, addresses) {
|
|
|
22
23
|
return new RmrkNftApi(substrateAddresses, chain);
|
|
23
24
|
} else if (_NFT_CHAIN_GROUP.statemine.includes(chain)) {
|
|
24
25
|
return new StatemineNftApi(substrateApi, substrateAddresses, chain);
|
|
26
|
+
} else if (_NFT_CHAIN_GROUP.statemint.includes(chain)) {
|
|
27
|
+
return new StatemintNftApi(substrateApi, substrateAddresses, chain);
|
|
25
28
|
} else if (_NFT_CHAIN_GROUP.unique_network.includes(chain)) {
|
|
26
29
|
return new UniqueNftApi(substrateApi, substrateAddresses, chain);
|
|
27
30
|
} else if (_NFT_CHAIN_GROUP.bitcountry.includes(chain)) {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseNftApi, HandleNftParams } from '@subwallet/extension-base/koni/api/nft/nft';
|
|
2
|
+
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
3
|
+
export default class StatemintNftApi extends BaseNftApi {
|
|
4
|
+
constructor(api: _SubstrateApi | null, addresses: string[], chain: string);
|
|
5
|
+
private getMetadata;
|
|
6
|
+
/**
|
|
7
|
+
* Retrieve id of NFTs
|
|
8
|
+
*
|
|
9
|
+
* @returns the array of NFT Ids
|
|
10
|
+
* @param addresses
|
|
11
|
+
*/
|
|
12
|
+
private getNfts;
|
|
13
|
+
private getTokenDetails;
|
|
14
|
+
private getCollectionDetail;
|
|
15
|
+
handleNft(address: string, params: HandleNftParams): Promise<void>;
|
|
16
|
+
handleNfts(params: HandleNftParams): Promise<void>;
|
|
17
|
+
fetchNfts(params: HandleNftParams): Promise<number>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { BaseNftApi } from '@subwallet/extension-base/koni/api/nft/nft';
|
|
5
|
+
import { isUrl } from '@subwallet/extension-base/utils';
|
|
6
|
+
import fetch from 'cross-fetch';
|
|
7
|
+
export default class StatemintNftApi extends BaseNftApi {
|
|
8
|
+
// eslint-disable-next-line no-useless-constructor
|
|
9
|
+
constructor(api, addresses, chain) {
|
|
10
|
+
super(chain, api, addresses);
|
|
11
|
+
}
|
|
12
|
+
getMetadata(metadataUrl) {
|
|
13
|
+
let url = metadataUrl;
|
|
14
|
+
if (!isUrl(metadataUrl)) {
|
|
15
|
+
url = this.parseUrl(metadataUrl);
|
|
16
|
+
if (!url || url.length === 0) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return fetch(url, {
|
|
21
|
+
method: 'GET',
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'application/json'
|
|
24
|
+
}
|
|
25
|
+
}).then(res => res.json());
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Retrieve id of NFTs
|
|
30
|
+
*
|
|
31
|
+
* @returns the array of NFT Ids
|
|
32
|
+
* @param addresses
|
|
33
|
+
*/
|
|
34
|
+
async getNfts(addresses) {
|
|
35
|
+
if (!this.substrateApi) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
const assetIds = [];
|
|
39
|
+
await Promise.all(addresses.map(async address => {
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
const resp = await this.substrateApi.api.query.nfts.account.keys(address);
|
|
42
|
+
if (resp) {
|
|
43
|
+
for (const key of resp) {
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
45
|
+
const data = key.toHuman();
|
|
46
|
+
assetIds.push({
|
|
47
|
+
classId: data[1],
|
|
48
|
+
tokenId: this.parseTokenId(data[2])
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}));
|
|
53
|
+
return assetIds;
|
|
54
|
+
}
|
|
55
|
+
async getTokenDetails(assetId) {
|
|
56
|
+
if (!this.substrateApi) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const {
|
|
60
|
+
classId,
|
|
61
|
+
tokenId
|
|
62
|
+
} = assetId;
|
|
63
|
+
const metadataNft = (await this.substrateApi.api.query.nfts.itemMetadataOf(this.parseTokenId(classId), this.parseTokenId(tokenId))).toHuman();
|
|
64
|
+
if (!(metadataNft !== null && metadataNft !== void 0 && metadataNft.data)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
return this.getMetadata(metadataNft === null || metadataNft === void 0 ? void 0 : metadataNft.data);
|
|
70
|
+
}
|
|
71
|
+
async getCollectionDetail(collectionId) {
|
|
72
|
+
if (!this.substrateApi) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const collectionMetadata = (await this.substrateApi.api.query.nfts.collectionMetadataOf(collectionId)).toHuman();
|
|
76
|
+
if (!(collectionMetadata !== null && collectionMetadata !== void 0 && collectionMetadata.data)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
return this.getMetadata(collectionMetadata === null || collectionMetadata === void 0 ? void 0 : collectionMetadata.data);
|
|
82
|
+
}
|
|
83
|
+
async handleNft(address, params) {
|
|
84
|
+
// const start = performance.now();
|
|
85
|
+
|
|
86
|
+
const assetIds = await this.getNfts([address]);
|
|
87
|
+
try {
|
|
88
|
+
if (!assetIds || assetIds.length === 0) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const collectionIds = [];
|
|
92
|
+
const nftIds = [];
|
|
93
|
+
await Promise.all(assetIds.map(async assetId => {
|
|
94
|
+
const parsedClassId = this.parseTokenId(assetId.classId);
|
|
95
|
+
const parsedTokenId = this.parseTokenId(assetId.tokenId);
|
|
96
|
+
if (!collectionIds.includes(parsedClassId)) {
|
|
97
|
+
collectionIds.push(parsedClassId);
|
|
98
|
+
}
|
|
99
|
+
nftIds.push(parsedTokenId);
|
|
100
|
+
const [tokenInfo, collectionMeta] = await Promise.all([this.getTokenDetails(assetId), this.getCollectionDetail(parseInt(parsedClassId))]);
|
|
101
|
+
const parsedNft = {
|
|
102
|
+
id: parsedTokenId,
|
|
103
|
+
name: tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.name,
|
|
104
|
+
description: tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.description,
|
|
105
|
+
image: tokenInfo && tokenInfo.image ? this.parseUrl(tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.image) : undefined,
|
|
106
|
+
collectionId: this.parseTokenId(parsedClassId),
|
|
107
|
+
chain: this.chain,
|
|
108
|
+
owner: address
|
|
109
|
+
};
|
|
110
|
+
params.updateItem(this.chain, parsedNft, address);
|
|
111
|
+
const parsedCollection = {
|
|
112
|
+
collectionId: parsedClassId,
|
|
113
|
+
chain: this.chain,
|
|
114
|
+
collectionName: collectionMeta === null || collectionMeta === void 0 ? void 0 : collectionMeta.name,
|
|
115
|
+
image: collectionMeta && collectionMeta.image ? this.parseUrl(collectionMeta === null || collectionMeta === void 0 ? void 0 : collectionMeta.image) : undefined
|
|
116
|
+
};
|
|
117
|
+
params.updateCollection(this.chain, parsedCollection);
|
|
118
|
+
}));
|
|
119
|
+
} catch (e) {
|
|
120
|
+
console.error(`${this.chain}`, e);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async handleNfts(params) {
|
|
124
|
+
await Promise.all(this.addresses.map(address => this.handleNft(address, params)));
|
|
125
|
+
}
|
|
126
|
+
async fetchNfts(params) {
|
|
127
|
+
try {
|
|
128
|
+
await this.connect();
|
|
129
|
+
await this.handleNfts(params);
|
|
130
|
+
} catch (e) {
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
return 1;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -5,4 +5,5 @@ export declare function rmrkGetExtrinsic(substrateApi: _SubstrateApi, senderAddr
|
|
|
5
5
|
export declare function uniqueGetExtrinsic(substrateApi: _SubstrateApi, senderAddress: string, recipientAddress: string, params: Record<string, any>): import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult> | null;
|
|
6
6
|
export declare function quartzGetExtrinsic(substrateApi: _SubstrateApi, senderAddress: string, recipientAddress: string, params: Record<string, any>): import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult> | null;
|
|
7
7
|
export declare function statemineGetExtrinsic(substrateApi: _SubstrateApi, senderAddress: string, recipientAddress: string, params: Record<string, any>): import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult> | null;
|
|
8
|
+
export declare function statemintGetExtrinsic(substrateApi: _SubstrateApi, senderAddress: string, recipientAddress: string, params: Record<string, any>): import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult> | null;
|
|
8
9
|
export declare function getNftTransferExtrinsic(networkKey: string, substrateApi: _SubstrateApi, senderAddress: string, recipientAddress: string, params: Record<string, any>): import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult> | null;
|
package/koni/api/nft/transfer.js
CHANGED
|
@@ -63,6 +63,16 @@ export function statemineGetExtrinsic(substrateApi, senderAddress, recipientAddr
|
|
|
63
63
|
return null;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
+
export function statemintGetExtrinsic(substrateApi, senderAddress, recipientAddress, params) {
|
|
67
|
+
try {
|
|
68
|
+
const itemId = params.itemId;
|
|
69
|
+
const collectionId = params.collectionId;
|
|
70
|
+
return substrateApi.api.tx.nfts.transfer(collectionId, itemId, recipientAddress);
|
|
71
|
+
} catch (e) {
|
|
72
|
+
console.error(e);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
66
76
|
export function getNftTransferExtrinsic(networkKey, substrateApi, senderAddress, recipientAddress, params) {
|
|
67
77
|
switch (networkKey) {
|
|
68
78
|
case SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.acala:
|
|
@@ -80,7 +90,7 @@ export function getNftTransferExtrinsic(networkKey, substrateApi, senderAddress,
|
|
|
80
90
|
case SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.statemine:
|
|
81
91
|
return statemineGetExtrinsic(substrateApi, senderAddress, recipientAddress, params);
|
|
82
92
|
case SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.statemint:
|
|
83
|
-
return
|
|
93
|
+
return statemintGetExtrinsic(substrateApi, senderAddress, recipientAddress, params);
|
|
84
94
|
case SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.bitcountry:
|
|
85
95
|
return acalaGetExtrinsic(substrateApi, senderAddress, recipientAddress, params);
|
|
86
96
|
case SUPPORTED_TRANSFER_SUBSTRATE_CHAIN_NAME.pioneer:
|
|
@@ -250,7 +250,7 @@ export default class KoniExtension {
|
|
|
250
250
|
this.cancelSubscription(id);
|
|
251
251
|
subscription.unsubscribe();
|
|
252
252
|
});
|
|
253
|
-
return
|
|
253
|
+
return this.#koniState.metaSubject.value;
|
|
254
254
|
}
|
|
255
255
|
jsonRestore({
|
|
256
256
|
file,
|
|
@@ -366,7 +366,7 @@ export default class KoniExtension {
|
|
|
366
366
|
this.cancelSubscription(id);
|
|
367
367
|
subscription.unsubscribe();
|
|
368
368
|
});
|
|
369
|
-
return
|
|
369
|
+
return this.#koniState.signSubject.value;
|
|
370
370
|
}
|
|
371
371
|
windowOpen({
|
|
372
372
|
allowedPath: path,
|
|
@@ -600,7 +600,7 @@ export default class KoniExtension {
|
|
|
600
600
|
port.onDisconnect.addListener(() => {
|
|
601
601
|
this.cancelSubscription(id);
|
|
602
602
|
});
|
|
603
|
-
return
|
|
603
|
+
return this.#koniState.authSubjectV2.value;
|
|
604
604
|
}
|
|
605
605
|
async getAuthListV2() {
|
|
606
606
|
const authList = await this._getAuthListV2();
|
|
@@ -3233,7 +3233,7 @@ export default class KoniExtension {
|
|
|
3233
3233
|
const wcId = request.request.id;
|
|
3234
3234
|
const params = request.request.params;
|
|
3235
3235
|
const requiredNamespaces = params.requiredNamespaces;
|
|
3236
|
-
const optionalNamespaces = params.optionalNamespaces;
|
|
3236
|
+
const optionalNamespaces = params.optionalNamespaces || {};
|
|
3237
3237
|
const availableNamespaces = {};
|
|
3238
3238
|
const namespaces = {};
|
|
3239
3239
|
const chainInfoMap = this.#koniState.getChainInfoMap();
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"./cjs/detectPackage.js"
|
|
18
18
|
],
|
|
19
19
|
"type": "module",
|
|
20
|
-
"version": "1.1.
|
|
20
|
+
"version": "1.1.16-1",
|
|
21
21
|
"main": "./cjs/index.js",
|
|
22
22
|
"module": "./index.js",
|
|
23
23
|
"types": "./index.d.ts",
|
|
@@ -249,6 +249,11 @@
|
|
|
249
249
|
"require": "./cjs/koni/api/nft/statemine_nft/index.js",
|
|
250
250
|
"default": "./koni/api/nft/statemine_nft/index.js"
|
|
251
251
|
},
|
|
252
|
+
"./koni/api/nft/statemint_nft": {
|
|
253
|
+
"types": "./koni/api/nft/statemint_nft/index.d.ts",
|
|
254
|
+
"require": "./cjs/koni/api/nft/statemint_nft/index.js",
|
|
255
|
+
"default": "./koni/api/nft/statemint_nft/index.js"
|
|
256
|
+
},
|
|
252
257
|
"./koni/api/nft/transfer": {
|
|
253
258
|
"types": "./koni/api/nft/transfer.d.ts",
|
|
254
259
|
"require": "./cjs/koni/api/nft/transfer.js",
|
|
@@ -1227,11 +1232,11 @@
|
|
|
1227
1232
|
"@reduxjs/toolkit": "^1.9.1",
|
|
1228
1233
|
"@sora-substrate/type-definitions": "^1.17.7",
|
|
1229
1234
|
"@substrate/connect": "^0.7.26",
|
|
1230
|
-
"@subwallet/chain-list": "0.2.16-beta.
|
|
1231
|
-
"@subwallet/extension-base": "^1.1.
|
|
1232
|
-
"@subwallet/extension-chains": "^1.1.
|
|
1233
|
-
"@subwallet/extension-dapp": "^1.1.
|
|
1234
|
-
"@subwallet/extension-inject": "^1.1.
|
|
1235
|
+
"@subwallet/chain-list": "0.2.16-beta.5",
|
|
1236
|
+
"@subwallet/extension-base": "^1.1.16-1",
|
|
1237
|
+
"@subwallet/extension-chains": "^1.1.16-1",
|
|
1238
|
+
"@subwallet/extension-dapp": "^1.1.16-1",
|
|
1239
|
+
"@subwallet/extension-inject": "^1.1.16-1",
|
|
1235
1240
|
"@subwallet/keyring": "^0.1.1",
|
|
1236
1241
|
"@subwallet/ui-keyring": "^0.1.1",
|
|
1237
1242
|
"@walletconnect/sign-client": "^2.8.4",
|
package/packageInfo.js
CHANGED
|
@@ -7,5 +7,5 @@ export const packageInfo = {
|
|
|
7
7
|
name: '@subwallet/extension-base',
|
|
8
8
|
path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
|
|
9
9
|
type: 'esm',
|
|
10
|
-
version: '1.1.
|
|
10
|
+
version: '1.1.16-1'
|
|
11
11
|
};
|
|
@@ -41,7 +41,8 @@ export const _NFT_CHAIN_GROUP = {
|
|
|
41
41
|
karura: ['karura'],
|
|
42
42
|
// TODO: karura and acala should be the same
|
|
43
43
|
rmrk: ['kusama'],
|
|
44
|
-
statemine: ['statemine'
|
|
44
|
+
statemine: ['statemine'],
|
|
45
|
+
statemint: ['statemint'],
|
|
45
46
|
unique_network: ['unique_network'],
|
|
46
47
|
bitcountry: ['bitcountry', 'pioneer']
|
|
47
48
|
};
|
|
@@ -110,8 +110,40 @@ export class KeyringService {
|
|
|
110
110
|
}
|
|
111
111
|
};
|
|
112
112
|
}));
|
|
113
|
+
const currentAddress = this.currentAccountSubject.value.address;
|
|
114
|
+
const afterAccounts = {};
|
|
115
|
+
Object.keys(this.accounts).forEach(adr => {
|
|
116
|
+
afterAccounts[adr] = true;
|
|
117
|
+
});
|
|
118
|
+
accounts.forEach(value => {
|
|
119
|
+
afterAccounts[value.address] = true;
|
|
120
|
+
});
|
|
121
|
+
if (Object.keys(afterAccounts).length === 1) {
|
|
122
|
+
this.currentAccountSubject.next({
|
|
123
|
+
address: Object.keys(afterAccounts)[0],
|
|
124
|
+
currentGenesisHash: null
|
|
125
|
+
});
|
|
126
|
+
} else if (Object.keys(afterAccounts).indexOf(currentAddress) === -1) {
|
|
127
|
+
this.currentAccountSubject.next({
|
|
128
|
+
address: ALL_ACCOUNT_KEY,
|
|
129
|
+
currentGenesisHash: null
|
|
130
|
+
});
|
|
131
|
+
}
|
|
113
132
|
}
|
|
114
133
|
removeInjectAccounts(addresses) {
|
|
134
|
+
const currentAddress = this.currentAccountSubject.value.address;
|
|
135
|
+
const afterAccounts = Object.keys(this.accounts).filter(address => addresses.indexOf(address) < 0);
|
|
136
|
+
if (afterAccounts.length === 1) {
|
|
137
|
+
this.currentAccountSubject.next({
|
|
138
|
+
address: afterAccounts[0],
|
|
139
|
+
currentGenesisHash: null
|
|
140
|
+
});
|
|
141
|
+
} else if (addresses.indexOf(currentAddress) === -1) {
|
|
142
|
+
this.currentAccountSubject.next({
|
|
143
|
+
address: ALL_ACCOUNT_KEY,
|
|
144
|
+
currentGenesisHash: null
|
|
145
|
+
});
|
|
146
|
+
}
|
|
115
147
|
keyring.removeInjects(addresses);
|
|
116
148
|
}
|
|
117
149
|
|