@subwallet/extension-base 1.0.6-1 → 1.0.7-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/background/KoniTypes.d.ts +7 -0
- package/cjs/koni/api/nft/wasm_nft/index.js +119 -29
- package/cjs/koni/api/nft/wasm_nft/utils.js +74 -13
- package/cjs/koni/background/handlers/State.js +1 -0
- package/cjs/koni/background/handlers/Tabs.js +68 -19
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/index.js +5 -3
- package/cjs/services/migration-service/index.js +2 -2
- package/cjs/services/request-service/handler/EvmRequestHandler.js +23 -0
- package/cjs/services/request-service/index.js +5 -0
- package/koni/api/nft/wasm_nft/index.d.ts +2 -0
- package/koni/api/nft/wasm_nft/index.js +120 -30
- package/koni/api/nft/wasm_nft/utils.d.ts +18 -6
- package/koni/api/nft/wasm_nft/utils.js +55 -6
- package/koni/background/handlers/State.js +1 -0
- package/koni/background/handlers/Tabs.js +68 -19
- package/package.json +6 -6
- package/packageInfo.js +1 -1
- package/services/chain-service/index.js +5 -3
- package/services/chain-service/types.d.ts +3 -0
- package/services/migration-service/index.js +2 -2
- package/services/request-service/handler/EvmRequestHandler.d.ts +1 -0
- package/services/request-service/handler/EvmRequestHandler.js +21 -0
- package/services/request-service/index.d.ts +1 -0
- package/services/request-service/index.js +3 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { _AssetType } from '@subwallet/chain-list/types';
|
|
5
5
|
import { BaseNftApi } from '@subwallet/extension-base/koni/api/nft/nft';
|
|
6
|
-
import {
|
|
6
|
+
import { collectionApiFromArtZero, collectionDetailApiFromArtZero, externalUrlOnArtZero, ipfsApiFromArtZero, itemImageApiFromArtZero } from '@subwallet/extension-base/koni/api/nft/wasm_nft/utils';
|
|
7
7
|
import { getPSP34ContractPromise } from '@subwallet/extension-base/koni/api/tokens/wasm';
|
|
8
8
|
import { getDefaultWeightV2 } from '@subwallet/extension-base/koni/api/tokens/wasm/utils';
|
|
9
9
|
import { _getContractAddressOfToken } from '@subwallet/extension-base/services/chain-service/utils';
|
|
@@ -26,7 +26,7 @@ async function isArtZeroFeaturedCollection(networkKey, contractAddress) {
|
|
|
26
26
|
const urlencoded = new URLSearchParams();
|
|
27
27
|
urlencoded.append('collection_address', contractAddress);
|
|
28
28
|
const collectionInfoPromise = new Promise(function (resolve) {
|
|
29
|
-
fetch(
|
|
29
|
+
fetch(collectionApiFromArtZero(networkKey), {
|
|
30
30
|
method: 'POST',
|
|
31
31
|
headers: {
|
|
32
32
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
@@ -49,6 +49,20 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
49
49
|
setSmartContractNfts(wasmContracts) {
|
|
50
50
|
this.wasmContracts = wasmContracts;
|
|
51
51
|
}
|
|
52
|
+
async isAttributeStoredOnChain(contractPromise) {
|
|
53
|
+
var _this$substrateApi, _onChainAttributeCoun;
|
|
54
|
+
if (!contractPromise.query['psp34Traits::getAttributeCount']) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// @ts-ignore
|
|
59
|
+
const _onChainAttributeCount = await contractPromise.query['psp34Traits::getAttributeCount'](this.addresses[0], {
|
|
60
|
+
gasLimit: getDefaultWeightV2((_this$substrateApi = this.substrateApi) === null || _this$substrateApi === void 0 ? void 0 : _this$substrateApi.api)
|
|
61
|
+
});
|
|
62
|
+
const _attributeCount = _onChainAttributeCount === null || _onChainAttributeCount === void 0 ? void 0 : (_onChainAttributeCoun = _onChainAttributeCount.output) === null || _onChainAttributeCoun === void 0 ? void 0 : _onChainAttributeCoun.toJSON();
|
|
63
|
+
const onChainAttributeCount = _onChainAttributeCount.output ? (_attributeCount === null || _attributeCount === void 0 ? void 0 : _attributeCount.ok) || (_attributeCount === null || _attributeCount === void 0 ? void 0 : _attributeCount.Ok) : '0';
|
|
64
|
+
return parseInt(onChainAttributeCount) !== 0;
|
|
65
|
+
}
|
|
52
66
|
parseFeaturedTokenUri(tokenUri) {
|
|
53
67
|
if (!tokenUri || tokenUri.length === 0) {
|
|
54
68
|
return undefined;
|
|
@@ -72,7 +86,7 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
72
86
|
if (!parsedTokenUri) {
|
|
73
87
|
return undefined;
|
|
74
88
|
}
|
|
75
|
-
const nftItemImageSrc = `${this.chain
|
|
89
|
+
const nftItemImageSrc = `${itemImageApiFromArtZero(this.chain)}?input=${parsedTokenUri}&size=500`;
|
|
76
90
|
const collectionImageUrl = await axios(nftItemImageSrc, {
|
|
77
91
|
method: 'GET'
|
|
78
92
|
});
|
|
@@ -81,7 +95,7 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
81
95
|
async parseFeaturedCollectionImage(smartContract) {
|
|
82
96
|
const urlencoded = new URLSearchParams();
|
|
83
97
|
urlencoded.append('collection_address', smartContract);
|
|
84
|
-
const resp = await fetch(this.chain
|
|
98
|
+
const resp = await fetch(collectionDetailApiFromArtZero(this.chain), {
|
|
85
99
|
method: 'POST',
|
|
86
100
|
headers: {
|
|
87
101
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
@@ -100,7 +114,7 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
100
114
|
if (!parsedCollectionImage) {
|
|
101
115
|
return;
|
|
102
116
|
}
|
|
103
|
-
const collectionImageSrc = `${this.chain
|
|
117
|
+
const collectionImageSrc = `${itemImageApiFromArtZero(this.chain)}?input=${parsedCollectionImage}&size=500`;
|
|
104
118
|
const collectionImageUrl = await axios(collectionImageSrc, {
|
|
105
119
|
method: 'GET'
|
|
106
120
|
});
|
|
@@ -183,8 +197,55 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
183
197
|
// return nftItem;
|
|
184
198
|
// }
|
|
185
199
|
|
|
200
|
+
async processOnChainMetadata(tokenId, isFeatured, tokenUri) {
|
|
201
|
+
const nftItem = {
|
|
202
|
+
chain: '',
|
|
203
|
+
collectionId: '',
|
|
204
|
+
id: '',
|
|
205
|
+
owner: '',
|
|
206
|
+
name: tokenId
|
|
207
|
+
};
|
|
208
|
+
let itemDetail = false;
|
|
209
|
+
if (isFeatured) {
|
|
210
|
+
const parsedTokenUri = this.parseFeaturedTokenUri(tokenUri);
|
|
211
|
+
if (parsedTokenUri) {
|
|
212
|
+
const resp = await fetch(`${ipfsApiFromArtZero(this.chain)}?input=${parsedTokenUri}`);
|
|
213
|
+
itemDetail = resp && resp.ok && (await resp.json());
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
const parsedTokenUri = this.parseFeaturedTokenUri(tokenUri);
|
|
217
|
+
const detailUrl = this.parseUrl(parsedTokenUri);
|
|
218
|
+
if (detailUrl) {
|
|
219
|
+
const resp = await fetch(detailUrl);
|
|
220
|
+
itemDetail = resp && resp.ok && (await resp.json());
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (!itemDetail) {
|
|
224
|
+
return nftItem;
|
|
225
|
+
}
|
|
226
|
+
nftItem.name = itemDetail.name;
|
|
227
|
+
nftItem.description = itemDetail.description;
|
|
228
|
+
const rawImageSrc = itemDetail.image ? itemDetail.image : itemDetail.image_url;
|
|
229
|
+
if (isFeatured) {
|
|
230
|
+
nftItem.image = await this.parseFeaturedNftImage(rawImageSrc);
|
|
231
|
+
nftItem.externalUrl = externalUrlOnArtZero(this.chain);
|
|
232
|
+
} else {
|
|
233
|
+
nftItem.image = this.parseUrl(rawImageSrc);
|
|
234
|
+
}
|
|
235
|
+
const propertiesMap = {};
|
|
236
|
+
const traitList = itemDetail.attributes ? itemDetail.attributes : itemDetail.traits;
|
|
237
|
+
if (traitList) {
|
|
238
|
+
traitList.forEach(traitMap => {
|
|
239
|
+
propertiesMap[traitMap.trait_type] = {
|
|
240
|
+
value: traitMap.value
|
|
241
|
+
};
|
|
242
|
+
});
|
|
243
|
+
nftItem.properties = propertiesMap;
|
|
244
|
+
}
|
|
245
|
+
return nftItem;
|
|
246
|
+
}
|
|
186
247
|
async processOffChainMetadata(contractPromise, address, tokenId, isFeatured) {
|
|
187
|
-
var _this$
|
|
248
|
+
var _this$substrateApi2;
|
|
188
249
|
const nftItem = {
|
|
189
250
|
chain: '',
|
|
190
251
|
collectionId: '',
|
|
@@ -193,7 +254,7 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
193
254
|
name: tokenId
|
|
194
255
|
};
|
|
195
256
|
const _tokenUri = await contractPromise.query['psp34Traits::tokenUri'](address, {
|
|
196
|
-
gasLimit: getDefaultWeightV2((_this$
|
|
257
|
+
gasLimit: getDefaultWeightV2((_this$substrateApi2 = this.substrateApi) === null || _this$substrateApi2 === void 0 ? void 0 : _this$substrateApi2.api)
|
|
197
258
|
}, tokenId);
|
|
198
259
|
if (_tokenUri.output) {
|
|
199
260
|
let itemDetail = false;
|
|
@@ -204,7 +265,7 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
204
265
|
if (isFeatured) {
|
|
205
266
|
const parsedTokenUri = this.parseFeaturedTokenUri(tokenUri);
|
|
206
267
|
if (parsedTokenUri) {
|
|
207
|
-
const resp = await fetch(`${this.chain
|
|
268
|
+
const resp = await fetch(`${ipfsApiFromArtZero(this.chain)}?input=${parsedTokenUri}`);
|
|
208
269
|
itemDetail = resp && resp.ok && (await resp.json());
|
|
209
270
|
}
|
|
210
271
|
} else {
|
|
@@ -224,7 +285,7 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
224
285
|
const rawImageSrc = itemDetail.image ? itemDetail.image : itemDetail.image_url;
|
|
225
286
|
if (isFeatured) {
|
|
226
287
|
nftItem.image = await this.parseFeaturedNftImage(rawImageSrc);
|
|
227
|
-
nftItem.externalUrl =
|
|
288
|
+
nftItem.externalUrl = externalUrlOnArtZero(this.chain);
|
|
228
289
|
} else {
|
|
229
290
|
nftItem.image = this.parseUrl(rawImageSrc);
|
|
230
291
|
}
|
|
@@ -241,19 +302,19 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
241
302
|
}
|
|
242
303
|
return nftItem;
|
|
243
304
|
}
|
|
244
|
-
async getItemsByCollection(contractPromise, tokenInfo, collectionName, nftParams, isFeatured) {
|
|
305
|
+
async getItemsByCollection(contractPromise, tokenInfo, collectionName, nftParams, isFeatured, isAttributeOnChain) {
|
|
245
306
|
let ownItem = false;
|
|
246
307
|
let collectionImage;
|
|
247
308
|
const smartContract = _getContractAddressOfToken(tokenInfo);
|
|
248
309
|
const nftOwnerMap = {};
|
|
249
310
|
await Promise.all(this.addresses.map(async address => {
|
|
250
|
-
var _this$
|
|
311
|
+
var _this$substrateApi3, _balance$output;
|
|
251
312
|
if (isEthereumAddress(address)) {
|
|
252
313
|
return;
|
|
253
314
|
}
|
|
254
315
|
const nftIds = [];
|
|
255
316
|
const _balance = await contractPromise.query['psp34::balanceOf'](address, {
|
|
256
|
-
gasLimit: getDefaultWeightV2((_this$
|
|
317
|
+
gasLimit: getDefaultWeightV2((_this$substrateApi3 = this.substrateApi) === null || _this$substrateApi3 === void 0 ? void 0 : _this$substrateApi3.api)
|
|
257
318
|
}, address);
|
|
258
319
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
259
320
|
const balanceJson = _balance === null || _balance === void 0 ? void 0 : (_balance$output = _balance.output) === null || _balance$output === void 0 ? void 0 : _balance$output.toJSON();
|
|
@@ -269,9 +330,9 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
269
330
|
}
|
|
270
331
|
try {
|
|
271
332
|
await Promise.all(itemIndexes.map(async i => {
|
|
272
|
-
var _this$
|
|
333
|
+
var _this$substrateApi4;
|
|
273
334
|
const _tokenByIndexResp = await contractPromise.query['psp34Enumerable::ownersTokenByIndex'](address, {
|
|
274
|
-
gasLimit: getDefaultWeightV2((_this$
|
|
335
|
+
gasLimit: getDefaultWeightV2((_this$substrateApi4 = this.substrateApi) === null || _this$substrateApi4 === void 0 ? void 0 : _this$substrateApi4.api)
|
|
275
336
|
}, address, i);
|
|
276
337
|
if (_tokenByIndexResp.output) {
|
|
277
338
|
const rawTokenId = _tokenByIndexResp.output.toHuman();
|
|
@@ -279,18 +340,47 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
279
340
|
const tokenIdObj = rawTokenId.Ok.Ok || rawTokenId.ok.ok; // capital O, not normal o
|
|
280
341
|
const tokenId = Object.values(tokenIdObj)[0].replaceAll(',', '');
|
|
281
342
|
nftIds.push(tokenId);
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
343
|
+
let tokenUri;
|
|
344
|
+
try {
|
|
345
|
+
if (isAttributeOnChain) {
|
|
346
|
+
var _this$substrateApi5, _tokenUri$output;
|
|
347
|
+
const _tokenUri = await contractPromise.query['psp34Traits::getAttributes'](address, {
|
|
348
|
+
gasLimit: getDefaultWeightV2((_this$substrateApi5 = this.substrateApi) === null || _this$substrateApi5 === void 0 ? void 0 : _this$substrateApi5.api)
|
|
349
|
+
}, tokenIdObj, ['metadata']);
|
|
350
|
+
const tokenUriObj = (_tokenUri$output = _tokenUri.output) === null || _tokenUri$output === void 0 ? void 0 : _tokenUri$output.toJSON();
|
|
351
|
+
tokenUri = (tokenUriObj.ok || tokenUriObj.Ok)[0];
|
|
352
|
+
}
|
|
353
|
+
} catch (e) {
|
|
354
|
+
console.debug(e);
|
|
355
|
+
}
|
|
356
|
+
if (!tokenUri) {
|
|
357
|
+
const nftItem = await this.processOffChainMetadata(contractPromise, address, tokenId, isFeatured);
|
|
358
|
+
nftItem.collectionId = smartContract;
|
|
359
|
+
nftItem.chain = this.chain;
|
|
360
|
+
nftItem.type = _AssetType.PSP34;
|
|
361
|
+
nftItem.id = tokenId;
|
|
362
|
+
nftItem.owner = address;
|
|
363
|
+
nftItem.onChainOption = tokenIdObj;
|
|
364
|
+
nftItem.originAsset = tokenInfo.slug;
|
|
365
|
+
nftParams.updateItem(this.chain, nftItem, address);
|
|
366
|
+
ownItem = true;
|
|
367
|
+
if (!isFeatured && !collectionImage && nftItem.image) {
|
|
368
|
+
collectionImage = nftItem.image; // No default collection image
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
const nftItem = await this.processOnChainMetadata(tokenId, false, tokenUri);
|
|
372
|
+
nftItem.collectionId = smartContract;
|
|
373
|
+
nftItem.chain = this.chain;
|
|
374
|
+
nftItem.type = _AssetType.PSP34;
|
|
375
|
+
nftItem.id = tokenId;
|
|
376
|
+
nftItem.owner = address;
|
|
377
|
+
nftItem.onChainOption = tokenIdObj;
|
|
378
|
+
nftItem.originAsset = tokenInfo.slug;
|
|
379
|
+
nftParams.updateItem(this.chain, nftItem, address);
|
|
380
|
+
ownItem = true;
|
|
381
|
+
if (!isFeatured && !collectionImage && nftItem.image) {
|
|
382
|
+
collectionImage = nftItem.image; // No default collection image
|
|
383
|
+
}
|
|
294
384
|
}
|
|
295
385
|
}
|
|
296
386
|
}));
|
|
@@ -329,17 +419,17 @@ export class WasmNftApi extends BaseNftApi {
|
|
|
329
419
|
return 1;
|
|
330
420
|
}
|
|
331
421
|
async handleNfts(params) {
|
|
332
|
-
var _this$
|
|
422
|
+
var _this$substrateApi6;
|
|
333
423
|
if (!this.wasmContracts || this.wasmContracts.length === 0) {
|
|
334
424
|
return;
|
|
335
425
|
}
|
|
336
426
|
await this.connect(); // might not be necessary
|
|
337
427
|
|
|
338
|
-
const apiPromise = (_this$
|
|
428
|
+
const apiPromise = (_this$substrateApi6 = this.substrateApi) === null || _this$substrateApi6 === void 0 ? void 0 : _this$substrateApi6.api;
|
|
339
429
|
await Promise.all(this.wasmContracts.map(async tokenInfo => {
|
|
340
430
|
const contractPromise = getPSP34ContractPromise(apiPromise, _getContractAddressOfToken(tokenInfo));
|
|
341
|
-
const isCollectionFeatured = await isArtZeroFeaturedCollection(this.chain, _getContractAddressOfToken(tokenInfo));
|
|
342
|
-
return await this.getItemsByCollection(contractPromise, tokenInfo, tokenInfo.name, params, isCollectionFeatured);
|
|
431
|
+
const [isAttributeOnChain, isCollectionFeatured] = await Promise.all([this.isAttributeStoredOnChain(contractPromise), isArtZeroFeaturedCollection(this.chain, _getContractAddressOfToken(tokenInfo))]);
|
|
432
|
+
return await this.getItemsByCollection(contractPromise, tokenInfo, tokenInfo.name, params, isCollectionFeatured, isAttributeOnChain);
|
|
343
433
|
}));
|
|
344
434
|
}
|
|
345
435
|
}
|
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const A0_ART_ZERO_TESTNET_IMAGE_API = "https://a0-test-api.artzero.io/getImage";
|
|
2
|
+
export declare const ASTAR_ART_ZERO_TESTNET_IMAGE_API = "https://astar-test-api.artzero.io/getImage";
|
|
2
3
|
export declare const ART_ZERO_TESTNET_IPFS_API = "https://a0-test-api.artzero.io/getJSON";
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
4
|
+
export declare const ASTAR_ART_ZERO_TESTNET_IPFS_API = "https://astar-test-api.artzero.io/getJSON";
|
|
5
|
+
export declare const A0_ART_ZERO_TESTNET_COLLECTION_API = "https://a0-test-api.artzero.io/getCollectionByAddress";
|
|
6
|
+
export declare const ASTAR_ART_ZERO_TESTNET_COLLECTION_API = "https://astar-test-api.artzero.io/getCollectionByAddress";
|
|
7
|
+
export declare const A0_ART_ZERO_IMAGE_API = "https://a0-api.artzero.io/getImage";
|
|
8
|
+
export declare const ASTAR_ART_ZERO_IMAGE_API = "https://astar-api.artzero.io/getImage";
|
|
9
|
+
export declare const A0_ART_ZERO_IPFS_API = "https://a0-api.artzero.io/getJSON";
|
|
10
|
+
export declare const ASTAR_ART_ZERO_IPFS_API = "https://astar-api.artzero.io/getJSON";
|
|
11
|
+
export declare const A0_ART_ZERO_COLLECTION_API = "https://a0-api.artzero.io/getCollectionByAddress";
|
|
12
|
+
export declare const ASTAR_ART_ZERO_COLLECTION_API = "https://astar-api.artzero.io/getCollectionByAddress";
|
|
13
|
+
export declare const A0_ART_ZERO_EXTERNAL_URL = "https://a0.artzero.io/#/marketplace";
|
|
14
|
+
export declare const ASTAR_ART_ZERO_EXTERNAL_URL = "https://astar.artzero.io/#/marketplace";
|
|
15
|
+
export declare function collectionApiFromArtZero(chain: string): "https://a0-test-api.artzero.io/getCollectionByAddress" | "https://a0-api.artzero.io/getCollectionByAddress" | "https://astar-api.artzero.io/getCollectionByAddress";
|
|
16
|
+
export declare function itemImageApiFromArtZero(chain: string): "https://a0-test-api.artzero.io/getImage" | "https://a0-api.artzero.io/getImage" | "https://astar-api.artzero.io/getImage";
|
|
17
|
+
export declare function collectionDetailApiFromArtZero(chain: string): "https://a0-test-api.artzero.io/getCollectionByAddress" | "https://a0-api.artzero.io/getCollectionByAddress" | "https://astar-api.artzero.io/getCollectionByAddress";
|
|
18
|
+
export declare function ipfsApiFromArtZero(chain: string): "https://a0-test-api.artzero.io/getJSON" | "https://a0-api.artzero.io/getJSON" | "https://astar-api.artzero.io/getJSON";
|
|
19
|
+
export declare function externalUrlOnArtZero(chain: string): "https://a0.artzero.io/#/marketplace" | "https://astar.artzero.io/#/marketplace";
|
|
@@ -1,10 +1,59 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const A0_ART_ZERO_TESTNET_IMAGE_API = 'https://a0-test-api.artzero.io/getImage';
|
|
5
|
+
export const ASTAR_ART_ZERO_TESTNET_IMAGE_API = 'https://astar-test-api.artzero.io/getImage';
|
|
5
6
|
export const ART_ZERO_TESTNET_IPFS_API = 'https://a0-test-api.artzero.io/getJSON';
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
8
|
-
export const
|
|
9
|
-
export const
|
|
10
|
-
export const
|
|
7
|
+
export const ASTAR_ART_ZERO_TESTNET_IPFS_API = 'https://astar-test-api.artzero.io/getJSON';
|
|
8
|
+
export const A0_ART_ZERO_TESTNET_COLLECTION_API = 'https://a0-test-api.artzero.io/getCollectionByAddress';
|
|
9
|
+
export const ASTAR_ART_ZERO_TESTNET_COLLECTION_API = 'https://astar-test-api.artzero.io/getCollectionByAddress';
|
|
10
|
+
export const A0_ART_ZERO_IMAGE_API = 'https://a0-api.artzero.io/getImage';
|
|
11
|
+
export const ASTAR_ART_ZERO_IMAGE_API = 'https://astar-api.artzero.io/getImage';
|
|
12
|
+
export const A0_ART_ZERO_IPFS_API = 'https://a0-api.artzero.io/getJSON';
|
|
13
|
+
export const ASTAR_ART_ZERO_IPFS_API = 'https://astar-api.artzero.io/getJSON';
|
|
14
|
+
export const A0_ART_ZERO_COLLECTION_API = 'https://a0-api.artzero.io/getCollectionByAddress';
|
|
15
|
+
export const ASTAR_ART_ZERO_COLLECTION_API = 'https://astar-api.artzero.io/getCollectionByAddress';
|
|
16
|
+
export const A0_ART_ZERO_EXTERNAL_URL = 'https://a0.artzero.io/#/marketplace';
|
|
17
|
+
export const ASTAR_ART_ZERO_EXTERNAL_URL = 'https://astar.artzero.io/#/marketplace';
|
|
18
|
+
export function collectionApiFromArtZero(chain) {
|
|
19
|
+
if (chain === 'alephTest') {
|
|
20
|
+
return A0_ART_ZERO_TESTNET_COLLECTION_API;
|
|
21
|
+
}
|
|
22
|
+
if (chain === 'astar') {
|
|
23
|
+
return ASTAR_ART_ZERO_COLLECTION_API;
|
|
24
|
+
}
|
|
25
|
+
return A0_ART_ZERO_COLLECTION_API;
|
|
26
|
+
}
|
|
27
|
+
export function itemImageApiFromArtZero(chain) {
|
|
28
|
+
if (chain === 'alephTest') {
|
|
29
|
+
return A0_ART_ZERO_TESTNET_IMAGE_API;
|
|
30
|
+
}
|
|
31
|
+
if (chain === 'astar') {
|
|
32
|
+
return ASTAR_ART_ZERO_IMAGE_API;
|
|
33
|
+
}
|
|
34
|
+
return A0_ART_ZERO_IMAGE_API;
|
|
35
|
+
}
|
|
36
|
+
export function collectionDetailApiFromArtZero(chain) {
|
|
37
|
+
if (chain === 'alephTest') {
|
|
38
|
+
return A0_ART_ZERO_TESTNET_COLLECTION_API;
|
|
39
|
+
}
|
|
40
|
+
if (chain === 'astar') {
|
|
41
|
+
return ASTAR_ART_ZERO_COLLECTION_API;
|
|
42
|
+
}
|
|
43
|
+
return A0_ART_ZERO_COLLECTION_API;
|
|
44
|
+
}
|
|
45
|
+
export function ipfsApiFromArtZero(chain) {
|
|
46
|
+
if (chain === 'alephTest') {
|
|
47
|
+
return ART_ZERO_TESTNET_IPFS_API;
|
|
48
|
+
}
|
|
49
|
+
if (chain === 'astar') {
|
|
50
|
+
return ASTAR_ART_ZERO_IPFS_API;
|
|
51
|
+
}
|
|
52
|
+
return A0_ART_ZERO_IPFS_API;
|
|
53
|
+
}
|
|
54
|
+
export function externalUrlOnArtZero(chain) {
|
|
55
|
+
if (chain === 'astar') {
|
|
56
|
+
return ASTAR_ART_ZERO_EXTERNAL_URL;
|
|
57
|
+
}
|
|
58
|
+
return A0_ART_ZERO_EXTERNAL_URL;
|
|
59
|
+
}
|
|
@@ -10,6 +10,7 @@ import RequestBytesSign from '@subwallet/extension-base/background/RequestBytesS
|
|
|
10
10
|
import RequestExtrinsicSign from '@subwallet/extension-base/background/RequestExtrinsicSign';
|
|
11
11
|
import { ALL_ACCOUNT_KEY, CRON_GET_API_MAP_STATUS } from '@subwallet/extension-base/constants';
|
|
12
12
|
import { PHISHING_PAGE_REDIRECT } from '@subwallet/extension-base/defaults';
|
|
13
|
+
import { _CHAIN_VALIDATION_ERROR } from '@subwallet/extension-base/services/chain-service/handler/types';
|
|
13
14
|
import { _generateCustomProviderKey } from '@subwallet/extension-base/services/chain-service/utils';
|
|
14
15
|
import { DEFAULT_CHAIN_PATROL_ENABLE } from '@subwallet/extension-base/services/setting-service/constants';
|
|
15
16
|
import { canDerive } from '@subwallet/extension-base/utils';
|
|
@@ -365,7 +366,7 @@ export default class KoniTabs {
|
|
|
365
366
|
async addEvmToken(id, url, {
|
|
366
367
|
params
|
|
367
368
|
}) {
|
|
368
|
-
var _input$type, _input$options, _input$options2;
|
|
369
|
+
var _input$type, _input$options, _input$options2, _input$options3, _input$options4, _input$options5;
|
|
369
370
|
const input = params;
|
|
370
371
|
const _tokenType = (input === null || input === void 0 ? void 0 : (_input$type = input.type) === null || _input$type === void 0 ? void 0 : _input$type.toLowerCase()) || '';
|
|
371
372
|
if (_tokenType !== 'erc20' && _tokenType !== 'erc721') {
|
|
@@ -380,28 +381,42 @@ export default class KoniTabs {
|
|
|
380
381
|
throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'Current chain is not available');
|
|
381
382
|
}
|
|
382
383
|
const tokenType = _tokenType === 'erc20' ? _AssetType.ERC20 : _AssetType.ERC721;
|
|
383
|
-
const
|
|
384
|
+
const tokenInfo = {
|
|
385
|
+
slug: '',
|
|
386
|
+
type: tokenType,
|
|
387
|
+
name: (input === null || input === void 0 ? void 0 : (_input$options3 = input.options) === null || _input$options3 === void 0 ? void 0 : _input$options3.symbol) || '',
|
|
388
|
+
contractAddress: input.options.address,
|
|
389
|
+
symbol: (input === null || input === void 0 ? void 0 : (_input$options4 = input.options) === null || _input$options4 === void 0 ? void 0 : _input$options4.symbol) || '',
|
|
390
|
+
decimals: (input === null || input === void 0 ? void 0 : (_input$options5 = input.options) === null || _input$options5 === void 0 ? void 0 : _input$options5.decimals) || 0,
|
|
391
|
+
originChain: chain,
|
|
392
|
+
contractError: false,
|
|
393
|
+
validated: false
|
|
394
|
+
};
|
|
395
|
+
this.#koniState.validateCustomAsset({
|
|
384
396
|
type: tokenType,
|
|
385
397
|
contractAddress: input.options.address,
|
|
386
398
|
originChain: chain
|
|
399
|
+
}).then(validate => {
|
|
400
|
+
if (validate.contractError) {
|
|
401
|
+
tokenInfo.contractError = true;
|
|
402
|
+
} else {
|
|
403
|
+
tokenInfo.slug = validate === null || validate === void 0 ? void 0 : validate.existedSlug;
|
|
404
|
+
tokenInfo.name = validate.name;
|
|
405
|
+
tokenInfo.symbol = validate.symbol;
|
|
406
|
+
tokenInfo.decimals = validate.decimals;
|
|
407
|
+
}
|
|
408
|
+
}).catch(() => {
|
|
409
|
+
tokenInfo.contractError = true;
|
|
410
|
+
}).finally(() => {
|
|
411
|
+
tokenInfo.validated = true;
|
|
412
|
+
this.#koniState.requestService.updateConfirmation(id, 'addTokenRequest', tokenInfo);
|
|
387
413
|
});
|
|
388
414
|
|
|
389
415
|
// Below code is comment because we will handle exited token in the ui-view
|
|
390
416
|
// if (validate.isExist) {
|
|
391
417
|
// throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'Current token is existed');
|
|
392
418
|
// } else
|
|
393
|
-
|
|
394
|
-
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Contract address is invalid');
|
|
395
|
-
}
|
|
396
|
-
const tokenInfo = {
|
|
397
|
-
slug: validate === null || validate === void 0 ? void 0 : validate.existedSlug,
|
|
398
|
-
type: tokenType,
|
|
399
|
-
name: validate.name,
|
|
400
|
-
contractAddress: input.options.address,
|
|
401
|
-
symbol: validate.symbol,
|
|
402
|
-
decimals: validate.decimals,
|
|
403
|
-
originChain: chain
|
|
404
|
-
};
|
|
419
|
+
|
|
405
420
|
return await this.#koniState.addTokenConfirm(id, url, tokenInfo);
|
|
406
421
|
}
|
|
407
422
|
async addEvmChain(id, url, {
|
|
@@ -413,6 +428,10 @@ export default class KoniTabs {
|
|
|
413
428
|
blockExplorerUrls,
|
|
414
429
|
chainId,
|
|
415
430
|
chainName,
|
|
431
|
+
nativeCurrency: {
|
|
432
|
+
decimals,
|
|
433
|
+
symbol
|
|
434
|
+
},
|
|
416
435
|
rpcUrls
|
|
417
436
|
} = input[0];
|
|
418
437
|
if (chainId) {
|
|
@@ -463,12 +482,19 @@ export default class KoniTabs {
|
|
|
463
482
|
throw new EvmProviderError(EvmProviderErrorType.INTERNAL_ERROR, 'Currently HTTP provider for EVM network');
|
|
464
483
|
}
|
|
465
484
|
const provider = filteredUrls[0];
|
|
466
|
-
const chainInfo =
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
485
|
+
const chainInfo = {
|
|
486
|
+
existentialDeposit: '0',
|
|
487
|
+
genesisHash: '',
|
|
488
|
+
success: true,
|
|
489
|
+
addressPrefix: '',
|
|
490
|
+
evmChainId: chainIdNum,
|
|
491
|
+
decimals: decimals,
|
|
492
|
+
symbol: symbol,
|
|
493
|
+
paraId: null,
|
|
494
|
+
name: chainName
|
|
495
|
+
};
|
|
470
496
|
const newProviderKey = _generateCustomProviderKey(0);
|
|
471
|
-
|
|
497
|
+
const networkData = {
|
|
472
498
|
mode: 'insert',
|
|
473
499
|
chainSpec: {
|
|
474
500
|
evmChainId: chainInfo.evmChainId,
|
|
@@ -488,8 +514,31 @@ export default class KoniTabs {
|
|
|
488
514
|
symbol: chainInfo.symbol,
|
|
489
515
|
chainType: 'EVM',
|
|
490
516
|
name: chainInfo.name
|
|
517
|
+
},
|
|
518
|
+
unconfirmed: true
|
|
519
|
+
};
|
|
520
|
+
this.#koniState.validateCustomChain(provider).then(res => {
|
|
521
|
+
if (!res.success) {
|
|
522
|
+
networkData.providerError = res.error;
|
|
523
|
+
} else {
|
|
524
|
+
networkData.chainSpec = {
|
|
525
|
+
evmChainId: res.evmChainId,
|
|
526
|
+
decimals: res.decimals,
|
|
527
|
+
existentialDeposit: res.existentialDeposit,
|
|
528
|
+
genesisHash: res.genesisHash,
|
|
529
|
+
paraId: res.paraId,
|
|
530
|
+
addressPrefix: res.addressPrefix ? parseInt(res.addressPrefix) : 0
|
|
531
|
+
};
|
|
532
|
+
networkData.chainEditInfo.symbol = res.symbol;
|
|
533
|
+
networkData.chainEditInfo.name = res.name;
|
|
491
534
|
}
|
|
535
|
+
}).catch(() => {
|
|
536
|
+
networkData.providerError = _CHAIN_VALIDATION_ERROR.NONE;
|
|
537
|
+
}).finally(() => {
|
|
538
|
+
networkData.unconfirmed = false;
|
|
539
|
+
this.#koniState.requestService.updateConfirmation(id, 'addNetworkRequest', networkData);
|
|
492
540
|
});
|
|
541
|
+
return await this.#koniState.addNetworkConfirm(id, url, networkData);
|
|
493
542
|
} else {
|
|
494
543
|
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Invalid provider');
|
|
495
544
|
}
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"./cjs/detectPackage.js"
|
|
18
18
|
],
|
|
19
19
|
"type": "module",
|
|
20
|
-
"version": "1.0.
|
|
20
|
+
"version": "1.0.7-0",
|
|
21
21
|
"main": "./cjs/index.js",
|
|
22
22
|
"module": "./index.js",
|
|
23
23
|
"types": "./index.d.ts",
|
|
@@ -1697,11 +1697,11 @@
|
|
|
1697
1697
|
"@sora-substrate/type-definitions": "^1.17.7",
|
|
1698
1698
|
"@subsocial/types": "^0.6.8",
|
|
1699
1699
|
"@substrate/connect": "^0.7.26",
|
|
1700
|
-
"@subwallet/chain-list": "^0.1.
|
|
1701
|
-
"@subwallet/extension-base": "^1.0.
|
|
1702
|
-
"@subwallet/extension-chains": "^1.0.
|
|
1703
|
-
"@subwallet/extension-dapp": "^1.0.
|
|
1704
|
-
"@subwallet/extension-inject": "^1.0.
|
|
1700
|
+
"@subwallet/chain-list": "^0.1.9",
|
|
1701
|
+
"@subwallet/extension-base": "^1.0.7-0",
|
|
1702
|
+
"@subwallet/extension-chains": "^1.0.7-0",
|
|
1703
|
+
"@subwallet/extension-dapp": "^1.0.7-0",
|
|
1704
|
+
"@subwallet/extension-inject": "^1.0.7-0",
|
|
1705
1705
|
"@subwallet/keyring": "^0.0.9",
|
|
1706
1706
|
"@subwallet/ui-keyring": "^0.0.9",
|
|
1707
1707
|
"@unique-nft/types": "^0.6.0-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.0.
|
|
10
|
+
version: '1.0.7-0'
|
|
11
11
|
};
|
|
@@ -652,17 +652,19 @@ export class ChainService {
|
|
|
652
652
|
parsedStoredAssetRegistry[storedAsset.slug] = storedAsset;
|
|
653
653
|
}
|
|
654
654
|
});
|
|
655
|
-
for (const
|
|
655
|
+
for (const storedAssetInfo of Object.values(parsedStoredAssetRegistry)) {
|
|
656
656
|
let duplicated = false;
|
|
657
657
|
for (const defaultChainAsset of Object.values(latestAssetRegistry)) {
|
|
658
658
|
// case merge custom asset with default asset
|
|
659
|
-
if (_isEqualSmartContractAsset(
|
|
659
|
+
if (_isEqualSmartContractAsset(storedAssetInfo, defaultChainAsset)) {
|
|
660
660
|
duplicated = true;
|
|
661
661
|
break;
|
|
662
662
|
}
|
|
663
663
|
}
|
|
664
664
|
if (!duplicated) {
|
|
665
|
-
mergedAssetRegistry[
|
|
665
|
+
mergedAssetRegistry[storedAssetInfo.slug] = storedAssetInfo;
|
|
666
|
+
} else {
|
|
667
|
+
deprecatedAssets.push(storedAssetInfo.slug);
|
|
666
668
|
}
|
|
667
669
|
}
|
|
668
670
|
this.dataMap.assetRegistry = mergedAssetRegistry;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _AssetRef, _AssetType, _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
|
+
import { _CHAIN_VALIDATION_ERROR } from '@subwallet/extension-base/services/chain-service/handler/types';
|
|
2
3
|
import Web3 from 'web3';
|
|
3
4
|
import { ApiPromise } from '@polkadot/api';
|
|
4
5
|
import { SubmittableExtrinsicFunction } from '@polkadot/api/promise/types';
|
|
@@ -88,6 +89,8 @@ export declare type _NetworkUpsertParams = {
|
|
|
88
89
|
existentialDeposit: string;
|
|
89
90
|
decimals: number;
|
|
90
91
|
};
|
|
92
|
+
unconfirmed?: boolean;
|
|
93
|
+
providerError?: _CHAIN_VALIDATION_ERROR;
|
|
91
94
|
};
|
|
92
95
|
export declare const _CUSTOM_PREFIX = "custom-";
|
|
93
96
|
export interface _ValidateCustomAssetRequest {
|
|
@@ -11,8 +11,8 @@ export default class MigrationService {
|
|
|
11
11
|
async run() {
|
|
12
12
|
const keys = Object.keys(MigrationScripts).sort((a, b) => a.localeCompare(b));
|
|
13
13
|
|
|
14
|
-
// Await timeout
|
|
15
|
-
await new Promise(resolve => setTimeout(resolve,
|
|
14
|
+
// Await timeout 1s
|
|
15
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
16
16
|
for (let i = 0; i < keys.length; i++) {
|
|
17
17
|
try {
|
|
18
18
|
const JobClass = MigrationScripts[keys[i]];
|
|
@@ -11,6 +11,7 @@ export default class EvmRequestHandler {
|
|
|
11
11
|
get numEvmRequests(): number;
|
|
12
12
|
getConfirmationsQueueSubject(): BehaviorSubject<ConfirmationsQueue>;
|
|
13
13
|
addConfirmation<CT extends ConfirmationType>(id: string, url: string, type: CT, payload: ConfirmationDefinitions[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitions[CT][1]) => Error | undefined): Promise<ConfirmationDefinitions[CT][1]>;
|
|
14
|
+
updateConfirmation<CT extends ConfirmationType>(id: string, type: CT, payload: ConfirmationDefinitions[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitions[CT][1]) => Error | undefined): void;
|
|
14
15
|
private signMessage;
|
|
15
16
|
configToTransaction(config: TransactionConfig): Transaction;
|
|
16
17
|
private signTransaction;
|
|
@@ -72,6 +72,27 @@ export default class EvmRequestHandler {
|
|
|
72
72
|
this.#requestService.updateIconV2();
|
|
73
73
|
return promise;
|
|
74
74
|
}
|
|
75
|
+
updateConfirmation(id, type, payload, options = {}, validator) {
|
|
76
|
+
const confirmations = this.confirmationsQueueSubject.getValue();
|
|
77
|
+
const confirmationType = confirmations[type];
|
|
78
|
+
|
|
79
|
+
// Check duplicate request
|
|
80
|
+
const exists = confirmationType[id];
|
|
81
|
+
if (!exists) {
|
|
82
|
+
throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, 'Request does not exist');
|
|
83
|
+
}
|
|
84
|
+
const payloadJson = JSON.stringify(payload);
|
|
85
|
+
confirmationType[id] = {
|
|
86
|
+
...exists,
|
|
87
|
+
payload,
|
|
88
|
+
payloadJson,
|
|
89
|
+
...options
|
|
90
|
+
};
|
|
91
|
+
if (validator) {
|
|
92
|
+
this.confirmationsPromiseMap[id].validator = validator;
|
|
93
|
+
}
|
|
94
|
+
this.confirmationsQueueSubject.next(confirmations);
|
|
95
|
+
}
|
|
75
96
|
async signMessage(confirmation) {
|
|
76
97
|
const {
|
|
77
98
|
account,
|
|
@@ -51,6 +51,7 @@ export default class RequestService {
|
|
|
51
51
|
signInternalTransaction(id: string, address: string, url: string, payload: SignerPayloadJSON): Promise<ResponseSigning>;
|
|
52
52
|
addConfirmation<CT extends ConfirmationType>(id: string, url: string, type: CT, payload: ConfirmationDefinitions[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitions[CT][1]) => Error | undefined): Promise<ConfirmationDefinitions[CT][1]>;
|
|
53
53
|
completeConfirmation(request: RequestConfirmationComplete): Promise<boolean>;
|
|
54
|
+
updateConfirmation<CT extends ConfirmationType>(id: string, type: CT, payload: ConfirmationDefinitions[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitions[CT][1]) => Error | undefined): void;
|
|
54
55
|
get numRequests(): number;
|
|
55
56
|
resetWallet(): void;
|
|
56
57
|
}
|