@subwallet/extension-base 1.3.78-0 → 1.3.80-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 +16 -6
- package/cjs/core/logic-validation/index.js +0 -12
- package/cjs/core/substrate/system-pallet.js +3 -0
- package/cjs/koni/api/nft/index.js +0 -14
- package/cjs/koni/background/cron.js +0 -17
- package/cjs/koni/background/handlers/Extension.js +13 -7
- package/cjs/koni/background/handlers/State.js +24 -6
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/process.js +49 -21
- package/cjs/services/balance-service/index.js +2 -2
- package/cjs/services/balance-service/transfer/xcm/utils.js +9 -9
- package/cjs/services/chain-service/constants.js +6 -2
- package/cjs/services/earning-service/handlers/native-staking/dtao.js +13 -13
- package/cjs/services/earning-service/handlers/native-staking/tao.js +16 -10
- package/cjs/services/earning-service/handlers/special.js +12 -4
- package/cjs/services/nft-service/index.js +219 -150
- package/cjs/services/nft-service/multi-chain-nft-fetcher.js +145 -0
- package/cjs/services/nft-service/nft-handlers/base-nft-handler.js +28 -0
- package/cjs/services/nft-service/nft-handlers/evm/evm-nft-handler.js +179 -0
- package/cjs/services/nft-service/nft-handlers/registry.js +37 -0
- package/cjs/services/nft-service/nft-handlers/unique/unique-nft-handler.js +187 -0
- package/cjs/services/storage-service/DatabaseService.js +1 -1
- package/cjs/services/swap-service/handler/asset-hub/handler.js +7 -4
- package/cjs/services/swap-service/handler/asset-hub/router.js +2 -66
- package/cjs/services/swap-service/handler/base-handler.js +4 -3
- package/cjs/services/swap-service/handler/hydradx-handler.js +9 -5
- package/cjs/services/swap-service/index.js +5 -4
- package/cjs/types/swap/index.js +4 -9
- package/cjs/utils/account/common.js +44 -8
- package/core/logic-validation/index.d.ts +0 -1
- package/core/logic-validation/index.js +0 -1
- package/core/substrate/system-pallet.js +3 -0
- package/koni/api/nft/index.js +1 -15
- package/koni/background/cron.d.ts +0 -1
- package/koni/background/cron.js +1 -18
- package/koni/background/handlers/Extension.d.ts +4 -0
- package/koni/background/handlers/Extension.js +13 -7
- package/koni/background/handlers/State.d.ts +8 -2
- package/koni/background/handlers/State.js +24 -6
- package/package.json +31 -11
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/process.d.ts +1 -1
- package/services/balance-service/helpers/process.js +48 -21
- package/services/balance-service/index.js +2 -2
- package/services/balance-service/transfer/xcm/utils.js +9 -9
- package/services/chain-service/constants.d.ts +3 -0
- package/services/chain-service/constants.js +3 -0
- package/services/earning-service/handlers/native-staking/dtao.js +12 -13
- package/services/earning-service/handlers/native-staking/tao.d.ts +2 -1
- package/services/earning-service/handlers/native-staking/tao.js +15 -10
- package/services/earning-service/handlers/special.js +13 -5
- package/services/nft-service/index.d.ts +42 -6
- package/services/nft-service/index.js +219 -151
- package/services/nft-service/multi-chain-nft-fetcher.d.ts +13 -0
- package/services/nft-service/multi-chain-nft-fetcher.js +138 -0
- package/services/nft-service/nft-handlers/base-nft-handler.d.ts +13 -0
- package/services/nft-service/nft-handlers/base-nft-handler.js +21 -0
- package/services/nft-service/nft-handlers/evm/evm-nft-handler.d.ts +9 -0
- package/services/nft-service/nft-handlers/evm/evm-nft-handler.js +171 -0
- package/services/nft-service/nft-handlers/registry.d.ts +11 -0
- package/services/nft-service/nft-handlers/registry.js +29 -0
- package/services/nft-service/nft-handlers/unique/unique-nft-handler.d.ts +12 -0
- package/services/nft-service/nft-handlers/unique/unique-nft-handler.js +177 -0
- package/services/storage-service/DatabaseService.d.ts +1 -1
- package/services/storage-service/DatabaseService.js +1 -1
- package/services/swap-service/handler/asset-hub/handler.js +7 -4
- package/services/swap-service/handler/asset-hub/router.d.ts +0 -4
- package/services/swap-service/handler/asset-hub/router.js +1 -64
- package/services/swap-service/handler/base-handler.js +4 -3
- package/services/swap-service/handler/hydradx-handler.js +9 -5
- package/services/swap-service/index.js +5 -4
- package/types/swap/index.d.ts +7 -35
- package/types/swap/index.js +3 -8
- package/types/yield/actions/join/step.d.ts +1 -0
- package/types/yield/actions/join/submit.d.ts +2 -1
- package/utils/account/common.d.ts +22 -1
- package/utils/account/common.js +44 -8
- package/cjs/core/logic-validation/swap.js +0 -235
- package/core/logic-validation/swap.d.ts +0 -26
- package/core/logic-validation/swap.js +0 -219
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BaseNftHandler = void 0;
|
|
7
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
8
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
9
|
+
|
|
10
|
+
const EMPTY_NFT_RESULT = {
|
|
11
|
+
items: [],
|
|
12
|
+
collections: []
|
|
13
|
+
};
|
|
14
|
+
class BaseNftHandler {
|
|
15
|
+
constructor(chain) {
|
|
16
|
+
this.chain = chain;
|
|
17
|
+
}
|
|
18
|
+
// Optional method - subclasses can choose to implement or not
|
|
19
|
+
fetchFullListNftOfACollection(_request) {
|
|
20
|
+
return Promise.resolve(EMPTY_NFT_RESULT);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Optional method - subclasses can choose to implement or not
|
|
24
|
+
fetchNftDetail(_request) {
|
|
25
|
+
return Promise.resolve(EMPTY_NFT_RESULT);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.BaseNftHandler = BaseNftHandler;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.EvmNftHandler = void 0;
|
|
8
|
+
var _types = require("@subwallet/chain-list/types");
|
|
9
|
+
var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
|
|
10
|
+
var _utils = require("@subwallet/extension-base/services/chain-service/utils");
|
|
11
|
+
var _utils2 = require("@subwallet/extension-base/utils");
|
|
12
|
+
var _subwalletServicesSdk = _interopRequireDefault(require("@subwallet-monorepos/subwallet-services-sdk"));
|
|
13
|
+
var _baseNftHandler = require("../base-nft-handler");
|
|
14
|
+
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
15
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
|
|
17
|
+
class EvmNftHandler extends _baseNftHandler.BaseNftHandler {
|
|
18
|
+
filterAddresses(addresses) {
|
|
19
|
+
return (0, _utils2.getAddressesByChainType)(addresses, [_KoniTypes.ChainType.EVM]);
|
|
20
|
+
}
|
|
21
|
+
mapSdkToNftItem(rawInstance, collectionId, owner) {
|
|
22
|
+
var _rawInstance$token_ty, _rawInstance$id;
|
|
23
|
+
const metadata = rawInstance.metadata || {};
|
|
24
|
+
const image = metadata.image || rawInstance.image_url || rawInstance.media_url || '';
|
|
25
|
+
const attributes = Array.isArray(metadata.attributes) ? metadata.attributes : [];
|
|
26
|
+
let rarity;
|
|
27
|
+
const properties = {};
|
|
28
|
+
for (const attr of attributes) {
|
|
29
|
+
try {
|
|
30
|
+
var _attr$trait_type;
|
|
31
|
+
const key = (_attr$trait_type = attr.trait_type) === null || _attr$trait_type === void 0 ? void 0 : _attr$trait_type.trim();
|
|
32
|
+
if (!key) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
let value = attr.value;
|
|
36
|
+
if (typeof value === 'string') {
|
|
37
|
+
const lower = value.toLowerCase();
|
|
38
|
+
if (lower === 'true') {
|
|
39
|
+
value = true;
|
|
40
|
+
}
|
|
41
|
+
if (lower === 'false') {
|
|
42
|
+
value = false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
properties[key] = value;
|
|
46
|
+
if (key.toLowerCase() === 'rarity') {
|
|
47
|
+
rarity = String(value);
|
|
48
|
+
}
|
|
49
|
+
} catch {
|
|
50
|
+
// ignore
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const normalizedType = (_rawInstance$token_ty = rawInstance.token_type) === null || _rawInstance$token_ty === void 0 ? void 0 : _rawInstance$token_ty.replace('-', '').toUpperCase();
|
|
54
|
+
if (!['ERC721'].includes(normalizedType)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
id: ((_rawInstance$id = rawInstance.id) === null || _rawInstance$id === void 0 ? void 0 : _rawInstance$id.toString()) || '',
|
|
59
|
+
chain: this.chain,
|
|
60
|
+
collectionId,
|
|
61
|
+
owner: rawInstance.owner || owner,
|
|
62
|
+
name: metadata.name || `#${rawInstance.id}`,
|
|
63
|
+
image: (0, _utils2.baseParseIPFSUrl)(image),
|
|
64
|
+
externalUrl: rawInstance.external_app_url || undefined,
|
|
65
|
+
rarity,
|
|
66
|
+
description: metadata.description || undefined,
|
|
67
|
+
properties: Object.keys(properties).length > 0 ? properties : null,
|
|
68
|
+
type: normalizedType === 'ERC721' ? _types._AssetType.ERC721 : _types._AssetType.ERC721,
|
|
69
|
+
originAsset: undefined,
|
|
70
|
+
rmrk_ver: undefined,
|
|
71
|
+
onChainOption: undefined,
|
|
72
|
+
assetHubType: undefined
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
mapSdkToCollection(raw) {
|
|
76
|
+
var _raw$token_instances;
|
|
77
|
+
const token = raw.token || {};
|
|
78
|
+
return {
|
|
79
|
+
collectionId: token.address_hash,
|
|
80
|
+
chain: this.chain,
|
|
81
|
+
collectionName: token.name || token.symbol || 'Unknown Collection',
|
|
82
|
+
image: token.icon_url || undefined,
|
|
83
|
+
itemCount: Number(raw.amount) || ((_raw$token_instances = raw.token_instances) === null || _raw$token_instances === void 0 ? void 0 : _raw$token_instances.length) || 0,
|
|
84
|
+
externalUrl: undefined,
|
|
85
|
+
originAsset: undefined
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ==================== 1. PREVIEW – Used for cron / background ====================
|
|
90
|
+
async fetchPreview(addresses) {
|
|
91
|
+
const items = [];
|
|
92
|
+
const collections = [];
|
|
93
|
+
const api = _subwalletServicesSdk.default.nftDetectionApi;
|
|
94
|
+
if (!(api !== null && api !== void 0 && api.getEvmNftCollectionsByAddress)) {
|
|
95
|
+
console.warn('[EvmNftHandler] Preview API not available');
|
|
96
|
+
return {
|
|
97
|
+
items,
|
|
98
|
+
collections
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
for (const address of addresses) {
|
|
102
|
+
try {
|
|
103
|
+
const rawData = await api.getEvmNftCollectionsByAddress(address);
|
|
104
|
+
for (const [chain, sdkCollections] of Object.entries(rawData)) {
|
|
105
|
+
if (chain !== this.chain || !Array.isArray(sdkCollections)) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
for (const col of sdkCollections) {
|
|
109
|
+
const collection = this.mapSdkToCollection(col);
|
|
110
|
+
collections.push(collection);
|
|
111
|
+
if (Array.isArray(col.token_instances)) {
|
|
112
|
+
const mapped = col.token_instances.map(inst => this.mapSdkToNftItem(inst, collection.collectionId, address)).filter(i => i !== null);
|
|
113
|
+
items.push(...mapped);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error(`[EvmNftHandler] Preview failed for ${address}`, error);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
items: items,
|
|
123
|
+
collections: collections
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ==================== 2. FULL – At collection details screen ====================
|
|
128
|
+
async fetchFullListNftOfACollection(request) {
|
|
129
|
+
const items = [];
|
|
130
|
+
const collections = [];
|
|
131
|
+
const {
|
|
132
|
+
chainInfo,
|
|
133
|
+
collectionId,
|
|
134
|
+
owners
|
|
135
|
+
} = request;
|
|
136
|
+
const chainId = (0, _utils._getEvmChainId)(chainInfo);
|
|
137
|
+
if (!collectionId || !owners || !chainId) {
|
|
138
|
+
console.warn('[NftService] missing params for getFullNftInstancesByCollection');
|
|
139
|
+
return {
|
|
140
|
+
items,
|
|
141
|
+
collections
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const nftDetectionApi = _subwalletServicesSdk.default.nftDetectionApi;
|
|
146
|
+
if (!(nftDetectionApi !== null && nftDetectionApi !== void 0 && nftDetectionApi.getAllNftInstances)) {
|
|
147
|
+
console.warn('[NftService] getAllNftInstances not available');
|
|
148
|
+
return {
|
|
149
|
+
items,
|
|
150
|
+
collections
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const ownerList = Array.isArray(owners) ? owners : [owners];
|
|
154
|
+
for (const eachOwner of ownerList) {
|
|
155
|
+
try {
|
|
156
|
+
const instances = await nftDetectionApi.getAllNftInstances(collectionId, eachOwner, chainId.toString());
|
|
157
|
+
if (!Array.isArray(instances)) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const mappedItems = instances.map(inst => this.mapSdkToNftItem(inst, collectionId, eachOwner)).filter(i => Boolean(i));
|
|
161
|
+
items.push(...mappedItems);
|
|
162
|
+
} catch (innerErr) {
|
|
163
|
+
console.warn(`[NftService] getAllNftInstances failed for ${eachOwner}`, innerErr);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
} catch (err) {
|
|
167
|
+
console.error(`[NftDetectionService] getFullNftInstancesByCollection error for ${collectionId}`, err);
|
|
168
|
+
return {
|
|
169
|
+
items: [],
|
|
170
|
+
collections: []
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
items: items,
|
|
175
|
+
collections: collections
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.EvmNftHandler = EvmNftHandler;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.NFT_HANDLER_REGISTRY = void 0;
|
|
7
|
+
exports.isNftV2Chain = isNftV2Chain;
|
|
8
|
+
var _constants = require("@subwallet/extension-base/services/chain-service/constants");
|
|
9
|
+
var _utils = require("@subwallet/extension-base/services/chain-service/utils");
|
|
10
|
+
var _evmNftHandler = require("@subwallet/extension-base/services/nft-service/nft-handlers/evm/evm-nft-handler");
|
|
11
|
+
var _uniqueNftHandler = require("@subwallet/extension-base/services/nft-service/nft-handlers/unique/unique-nft-handler");
|
|
12
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
13
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
|
+
|
|
15
|
+
function isNftV2Chain(chainInfo, registry) {
|
|
16
|
+
return registry.some(desc => desc.supports(chainInfo));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// todo list: only update into when migration
|
|
20
|
+
const NFT_HANDLER_REGISTRY = [{
|
|
21
|
+
id: 'evm',
|
|
22
|
+
supports: chainInfo => (0, _utils._isChainSupportEvmNft)(chainInfo),
|
|
23
|
+
supportsFetchFullNftList: true,
|
|
24
|
+
create: chain => new _evmNftHandler.EvmNftHandler(chain)
|
|
25
|
+
}, {
|
|
26
|
+
id: 'unique_network',
|
|
27
|
+
supports: chainInfo => _constants.NFT_CHAIN_GROUPS_MIGRATED.unique_network.includes(chainInfo.slug),
|
|
28
|
+
supportsFetchFullNftList: false,
|
|
29
|
+
create: chain => new _uniqueNftHandler.UniqueNftHandler(chain)
|
|
30
|
+
}
|
|
31
|
+
// {
|
|
32
|
+
// id: 'ordinal',
|
|
33
|
+
// supports: (chainInfo) => _isSupportOrdinal(chainInfo.slug),
|
|
34
|
+
// create: (chain, state) => new OrdinalNftHandler(chain, state)
|
|
35
|
+
// }
|
|
36
|
+
];
|
|
37
|
+
exports.NFT_HANDLER_REGISTRY = NFT_HANDLER_REGISTRY;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.UniqueNftHandler = void 0;
|
|
8
|
+
var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
|
|
9
|
+
var _utils = require("@subwallet/extension-base/utils");
|
|
10
|
+
var _subwalletServicesSdk = _interopRequireDefault(require("@subwallet-monorepos/subwallet-services-sdk"));
|
|
11
|
+
var _baseNftHandler = require("../base-nft-handler");
|
|
12
|
+
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
13
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
|
+
|
|
15
|
+
class UniqueNftHandler extends _baseNftHandler.BaseNftHandler {
|
|
16
|
+
filterAddresses(addresses) {
|
|
17
|
+
return (0, _utils.getAddressesByChainType)(addresses, [_KoniTypes.ChainType.SUBSTRATE]);
|
|
18
|
+
}
|
|
19
|
+
mapUniqueCollections(raws) {
|
|
20
|
+
var _raws$collectionCover;
|
|
21
|
+
return {
|
|
22
|
+
collectionId: raws.collectionId.toString(),
|
|
23
|
+
chain: this.chain,
|
|
24
|
+
collectionName: raws.collectionName || 'Unknown Collection',
|
|
25
|
+
image: ((_raws$collectionCover = raws.collectionCover) === null || _raws$collectionCover === void 0 ? void 0 : _raws$collectionCover.url) || undefined,
|
|
26
|
+
externalUrl: undefined,
|
|
27
|
+
originAsset: undefined
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
mapUniqueRootNftToItem(raw, owner) {
|
|
31
|
+
return {
|
|
32
|
+
id: raw.tokenId.toString(),
|
|
33
|
+
chain: this.chain,
|
|
34
|
+
collectionId: raw.collectionId.toString(),
|
|
35
|
+
name: raw.name || `#${raw.tokenId}`,
|
|
36
|
+
image: raw.image || undefined,
|
|
37
|
+
description: raw.description || undefined,
|
|
38
|
+
owner: owner,
|
|
39
|
+
isBundle: false,
|
|
40
|
+
properties: null
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
mapBundleTreeToNftItem(node, topmostOwner) {
|
|
44
|
+
let level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
45
|
+
let parentId = arguments.length > 3 ? arguments[3] : undefined;
|
|
46
|
+
const item = {
|
|
47
|
+
id: node.tokenId.toString(),
|
|
48
|
+
chain: this.chain,
|
|
49
|
+
collectionId: node.collectionId.toString(),
|
|
50
|
+
name: node.name || `#${node.tokenId}`,
|
|
51
|
+
image: node.image || undefined,
|
|
52
|
+
description: node.description || undefined,
|
|
53
|
+
owner: topmostOwner,
|
|
54
|
+
isBundle: node.nested && node.nested.length > 0 && level === 0,
|
|
55
|
+
properties: null,
|
|
56
|
+
nestingLevel: level,
|
|
57
|
+
parentId: level > 0 ? parentId : undefined
|
|
58
|
+
};
|
|
59
|
+
if (node.nested && node.nested.length > 0) {
|
|
60
|
+
item.nestingTokens = node.nested.map(child => this.mapBundleTreeToNftItem(child, topmostOwner, level + 1, item.id));
|
|
61
|
+
}
|
|
62
|
+
return item;
|
|
63
|
+
}
|
|
64
|
+
async fetchNftBundle(collectionId, tokenId, topmostOwner) {
|
|
65
|
+
const api = _subwalletServicesSdk.default.uniqueNftDetectionApi;
|
|
66
|
+
if (!api) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const treeData = await api.getNftBundleTree(collectionId, tokenId);
|
|
71
|
+
if (!treeData) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return this.mapBundleTreeToNftItem(treeData, topmostOwner, 0, tokenId);
|
|
75
|
+
} catch (e) {
|
|
76
|
+
console.error('[UniqueNftHandler] Failed to fetch bundle tree', e);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ==================== MAIN HANDLER ====================
|
|
82
|
+
|
|
83
|
+
async fetchPreview(addresses) {
|
|
84
|
+
const items = [];
|
|
85
|
+
const collectionsMap = new Map();
|
|
86
|
+
const api = _subwalletServicesSdk.default.uniqueNftDetectionApi;
|
|
87
|
+
if (!api) {
|
|
88
|
+
return {
|
|
89
|
+
items: [],
|
|
90
|
+
collections: []
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
await Promise.all(addresses.map(async address => {
|
|
95
|
+
// 1. Collections
|
|
96
|
+
const sdkCollections = await api.getUniqueCollectionsByTokenOwner(address);
|
|
97
|
+
for (const col of sdkCollections) {
|
|
98
|
+
const collection = this.mapUniqueCollections(col);
|
|
99
|
+
if (!collectionsMap.has(collection.collectionId)) {
|
|
100
|
+
collectionsMap.set(collection.collectionId, collection);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 2. Root NFTs
|
|
105
|
+
const sdkNfts = await api.getAllUniqueRootNfts({
|
|
106
|
+
owner: address
|
|
107
|
+
});
|
|
108
|
+
for (const rootNft of sdkNfts) {
|
|
109
|
+
items.push(this.mapUniqueRootNftToItem(rootNft, address));
|
|
110
|
+
}
|
|
111
|
+
}));
|
|
112
|
+
} catch (e) {
|
|
113
|
+
console.error(`[UniqueNftHandler] Failed to fetch for ${this.chain}`, e);
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
items,
|
|
117
|
+
collections: Array.from(collectionsMap.values())
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
async fetchFullListNftOfACollection(request) {
|
|
121
|
+
const items = [];
|
|
122
|
+
const collections = [];
|
|
123
|
+
const {
|
|
124
|
+
collectionId,
|
|
125
|
+
owners,
|
|
126
|
+
tokenIds
|
|
127
|
+
} = request;
|
|
128
|
+
if (!collectionId || !owners || !tokenIds) {
|
|
129
|
+
console.warn('[NftService] missing params for getFullNftInstancesByCollection');
|
|
130
|
+
return {
|
|
131
|
+
items,
|
|
132
|
+
collections
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
for (const id of tokenIds) {
|
|
136
|
+
const fullTree = await this.fetchNftBundle(collectionId, id, owners[0]);
|
|
137
|
+
if (fullTree) {
|
|
138
|
+
items.push(fullTree);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
items: items,
|
|
143
|
+
collections: collections
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
async fetchNftDetail(request) {
|
|
147
|
+
const items = [];
|
|
148
|
+
const collections = [];
|
|
149
|
+
const api = _subwalletServicesSdk.default.uniqueNftDetectionApi;
|
|
150
|
+
if (!api) {
|
|
151
|
+
return {
|
|
152
|
+
items: [],
|
|
153
|
+
collections: []
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const {
|
|
157
|
+
collectionId,
|
|
158
|
+
tokenId
|
|
159
|
+
} = request;
|
|
160
|
+
if (!collectionId || !tokenId) {
|
|
161
|
+
return {
|
|
162
|
+
items,
|
|
163
|
+
collections
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
const rawNft = await api.getNftDetail(collectionId, tokenId);
|
|
168
|
+
if (!rawNft) {
|
|
169
|
+
return {
|
|
170
|
+
items: [],
|
|
171
|
+
collections: []
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const nftItem = this.mapUniqueRootNftToItem(rawNft, rawNft.owner);
|
|
175
|
+
return {
|
|
176
|
+
items: [nftItem],
|
|
177
|
+
collections: []
|
|
178
|
+
};
|
|
179
|
+
} catch (e) {
|
|
180
|
+
return {
|
|
181
|
+
items: [],
|
|
182
|
+
collections: []
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.UniqueNftHandler = UniqueNftHandler;
|
|
@@ -404,7 +404,7 @@ class DatabaseService {
|
|
|
404
404
|
return this.stores.nft.removeNfts(chain, address, collectionId, nftIds);
|
|
405
405
|
}
|
|
406
406
|
removeNftsByAddress(address) {
|
|
407
|
-
return this.stores.nft.removeNftsByAddress(
|
|
407
|
+
return this.stores.nft.removeNftsByAddress(address);
|
|
408
408
|
}
|
|
409
409
|
|
|
410
410
|
// Chain
|
|
@@ -71,7 +71,10 @@ class AssetHubSwapHandler {
|
|
|
71
71
|
const {
|
|
72
72
|
path,
|
|
73
73
|
request: {
|
|
74
|
-
|
|
74
|
+
address,
|
|
75
|
+
alternativeAddress,
|
|
76
|
+
fromAmount,
|
|
77
|
+
recipient
|
|
75
78
|
},
|
|
76
79
|
selectedQuote
|
|
77
80
|
} = params;
|
|
@@ -93,12 +96,12 @@ class AssetHubSwapHandler {
|
|
|
93
96
|
const needModifyData = swapXcm || xcmSwapXcm;
|
|
94
97
|
let bnSendingValue = (0, _bignumber.default)(fromAmount);
|
|
95
98
|
let bnExpectedReceive = (0, _bignumber.default)(selectedQuote.toAmount);
|
|
96
|
-
const sender = (0, _utils3._reformatAddressWithChain)(
|
|
97
|
-
let receiver = (0, _utils3._reformatAddressWithChain)(
|
|
99
|
+
const sender = (0, _utils3._reformatAddressWithChain)(address, originChain, alternativeAddress);
|
|
100
|
+
let receiver = (0, _utils3._reformatAddressWithChain)(recipient || address, destinationChain);
|
|
98
101
|
if (needModifyData) {
|
|
99
102
|
bnSendingValue = bnSendingValue.multipliedBy(_utils2.DEFAULT_EXCESS_AMOUNT_WEIGHT);
|
|
100
103
|
bnExpectedReceive = bnExpectedReceive.multipliedBy(_utils2.DEFAULT_EXCESS_AMOUNT_WEIGHT);
|
|
101
|
-
receiver = (0, _utils3._reformatAddressWithChain)(
|
|
104
|
+
receiver = (0, _utils3._reformatAddressWithChain)(address, destinationChain, alternativeAddress);
|
|
102
105
|
}
|
|
103
106
|
const submitStep = {
|
|
104
107
|
name: 'Swap',
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
3
|
Object.defineProperty(exports, "__esModule", {
|
|
5
4
|
value: true
|
|
6
5
|
});
|
|
7
6
|
exports.AssetHubRouter = void 0;
|
|
8
|
-
var _utils = require("@subwallet/extension-base/services/
|
|
9
|
-
var _utils2 = require("@subwallet/extension-base/services/swap-service/handler/asset-hub/utils");
|
|
10
|
-
var _swap = require("@subwallet/extension-base/types/swap");
|
|
11
|
-
var _bignumber = _interopRequireDefault(require("bignumber.js"));
|
|
7
|
+
var _utils = require("@subwallet/extension-base/services/swap-service/handler/asset-hub/utils");
|
|
12
8
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
13
9
|
// SPDX-License-Identifier: Apache-2.0
|
|
14
10
|
|
|
@@ -23,70 +19,10 @@ class AssetHubRouter {
|
|
|
23
19
|
get nativeToken() {
|
|
24
20
|
return this.chainService.getNativeTokenInfo(this.chain);
|
|
25
21
|
}
|
|
26
|
-
buildPath(pair) {
|
|
27
|
-
// const nativeToken = this.nativeToken;
|
|
28
|
-
// const nativeTokenSlug = nativeToken.slug;
|
|
29
|
-
|
|
30
|
-
const assetFrom = this.chainService.getAssetBySlug(pair.from);
|
|
31
|
-
const assetTo = this.chainService.getAssetBySlug(pair.to);
|
|
32
|
-
return [assetFrom, assetTo];
|
|
33
|
-
// if (pair.from === nativeTokenSlug || pair.to === nativeTokenSlug) {
|
|
34
|
-
// return [assetFrom, assetTo];
|
|
35
|
-
// } else {
|
|
36
|
-
// return [assetFrom, nativeToken, assetTo];
|
|
37
|
-
// }
|
|
38
|
-
}
|
|
39
|
-
async earlyValidateSwapValidation(request) {
|
|
40
|
-
const substrateApi = await this.substrateApi.isReady;
|
|
41
|
-
const paths = this.buildPath(request.pair);
|
|
42
|
-
const api = await substrateApi.api.isReady;
|
|
43
|
-
const amount = request.fromAmount;
|
|
44
|
-
const reserves = await (0, _utils2.getReserveForPath)(api, paths);
|
|
45
|
-
const amounts = (0, _utils2.estimateTokensForPath)(amount, reserves);
|
|
46
|
-
const marketRate = (0, _utils2.estimateRateForPath)(reserves);
|
|
47
|
-
const marketRateAfter = (0, _utils2.estimateRateAfterForPath)(amount, reserves);
|
|
48
|
-
const priceImpactPct = (0, _utils2.estimatePriceImpactPct)(marketRate, marketRateAfter);
|
|
49
|
-
const errors = [];
|
|
50
|
-
|
|
51
|
-
// Check liquidity
|
|
52
|
-
const liquidityError = (0, _utils2.checkLiquidityForPath)(amounts, reserves);
|
|
53
|
-
if (liquidityError) {
|
|
54
|
-
errors.push(liquidityError);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Check amount token in pool after swap
|
|
58
|
-
const minAmounts = paths.map(asset => (0, _utils._getTokenMinAmount)(asset));
|
|
59
|
-
const minAmountAfterSwapError = (0, _utils2.checkMinAmountForPath)(reserves, amounts, minAmounts);
|
|
60
|
-
if (minAmountAfterSwapError) {
|
|
61
|
-
errors.push(minAmountAfterSwapError);
|
|
62
|
-
}
|
|
63
|
-
const bnAmount = new _bignumber.default(request.fromAmount);
|
|
64
|
-
if (bnAmount.lte(0)) {
|
|
65
|
-
errors.push(_swap.SwapErrorType.AMOUNT_CANNOT_BE_ZERO);
|
|
66
|
-
}
|
|
67
|
-
const metadata = {
|
|
68
|
-
chain: this.chainService.getChainInfoByKey(this.chain),
|
|
69
|
-
toAmount: amounts[amounts.length - 1],
|
|
70
|
-
quoteRate: marketRate,
|
|
71
|
-
priceImpactPct: priceImpactPct
|
|
72
|
-
};
|
|
73
|
-
return {
|
|
74
|
-
error: errors[0],
|
|
75
|
-
metadata
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
async estimateAmountOut(pair, amountIn) {
|
|
79
|
-
const substrateApi = await this.substrateApi.isReady;
|
|
80
|
-
const paths = this.buildPath(pair);
|
|
81
|
-
const api = await substrateApi.api.isReady;
|
|
82
|
-
const reserves = await (0, _utils2.getReserveForPath)(api, paths);
|
|
83
|
-
const amounts = (0, _utils2.estimateTokensForPath)(amountIn, reserves);
|
|
84
|
-
return amounts[amounts.length - 1];
|
|
85
|
-
}
|
|
86
22
|
async buildSwapExtrinsic(path, recipient, amountIn, amountOutMin) {
|
|
87
23
|
const substrateApi = await this.substrateApi.isReady;
|
|
88
24
|
const api = await substrateApi.api.isReady;
|
|
89
|
-
return (0,
|
|
25
|
+
return (0, _utils.buildSwapExtrinsic)(api, path, recipient, amountIn, amountOutMin);
|
|
90
26
|
}
|
|
91
27
|
}
|
|
92
28
|
exports.AssetHubRouter = AssetHubRouter;
|
|
@@ -79,6 +79,7 @@ class SwapBaseHandler {
|
|
|
79
79
|
path,
|
|
80
80
|
request: {
|
|
81
81
|
address,
|
|
82
|
+
alternativeAddress,
|
|
82
83
|
fromAmount,
|
|
83
84
|
recipient
|
|
84
85
|
},
|
|
@@ -102,12 +103,12 @@ class SwapBaseHandler {
|
|
|
102
103
|
throw Error('Token or chain not found');
|
|
103
104
|
}
|
|
104
105
|
let recipientAddress;
|
|
105
|
-
const senderAddress = (0, _utils5._reformatAddressWithChain)(address, fromChainInfo);
|
|
106
|
+
const senderAddress = (0, _utils5._reformatAddressWithChain)(address, fromChainInfo, alternativeAddress);
|
|
106
107
|
if (stepIndex === 0) {
|
|
107
|
-
recipientAddress = (0, _utils5._reformatAddressWithChain)(address, toChainInfo);
|
|
108
|
+
recipientAddress = (0, _utils5._reformatAddressWithChain)(address, toChainInfo, alternativeAddress);
|
|
108
109
|
} else {
|
|
109
110
|
// bridge after swap
|
|
110
|
-
recipientAddress = (0, _utils5._reformatAddressWithChain)(recipient || address, toChainInfo);
|
|
111
|
+
recipientAddress = (0, _utils5._reformatAddressWithChain)(recipient || address, toChainInfo, alternativeAddress);
|
|
111
112
|
}
|
|
112
113
|
if (!(0, _xcmParser._isXcmWithinSameConsensus)(fromChainInfo, toChainInfo) || (0, _xcmParser._isSnowBridgeXcm)(fromChainInfo, toChainInfo) || (0, _xcmParser._isAcrossBridgeXcm)(fromChainInfo, toChainInfo)) {
|
|
113
114
|
return undefined;
|
|
@@ -116,7 +116,11 @@ class HydradxHandler {
|
|
|
116
116
|
const {
|
|
117
117
|
path,
|
|
118
118
|
request: {
|
|
119
|
-
|
|
119
|
+
address,
|
|
120
|
+
alternativeAddress,
|
|
121
|
+
fromAmount,
|
|
122
|
+
recipient,
|
|
123
|
+
slippage
|
|
120
124
|
},
|
|
121
125
|
selectedQuote
|
|
122
126
|
} = params;
|
|
@@ -135,8 +139,8 @@ class HydradxHandler {
|
|
|
135
139
|
const destinationTokenInfo = this.chainService.getAssetBySlug(swapPairInfo.to);
|
|
136
140
|
const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
|
|
137
141
|
const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
|
|
138
|
-
const sender = (0, _utils3._reformatAddressWithChain)(
|
|
139
|
-
let receiver = (0, _utils3._reformatAddressWithChain)(
|
|
142
|
+
const sender = (0, _utils3._reformatAddressWithChain)(address, originChain, alternativeAddress);
|
|
143
|
+
let receiver = (0, _utils3._reformatAddressWithChain)(recipient || address, destinationChain);
|
|
140
144
|
const actionList = JSON.stringify(path.map(step => step.action));
|
|
141
145
|
const xcmSwapXcm = actionList === JSON.stringify([_types.DynamicSwapType.BRIDGE, _types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
|
|
142
146
|
const swapXcm = actionList === JSON.stringify([_types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
|
|
@@ -160,7 +164,7 @@ class HydradxHandler {
|
|
|
160
164
|
slug: swapPairInfo.slug
|
|
161
165
|
},
|
|
162
166
|
fromAmount: bnSendingValue.toFixed(0, 1),
|
|
163
|
-
slippage:
|
|
167
|
+
slippage: slippage
|
|
164
168
|
});
|
|
165
169
|
} catch (error) {
|
|
166
170
|
throw new Error(`Failed to fetch swap quote: ${error.message}`);
|
|
@@ -171,7 +175,7 @@ class HydradxHandler {
|
|
|
171
175
|
}
|
|
172
176
|
const overrideQuote = quoteAskResponse.quote;
|
|
173
177
|
txHex = overrideQuote.metadata;
|
|
174
|
-
receiver = (0, _utils3._reformatAddressWithChain)(
|
|
178
|
+
receiver = (0, _utils3._reformatAddressWithChain)(address, destinationChain, alternativeAddress);
|
|
175
179
|
}
|
|
176
180
|
if (!txHex || !(0, _util.isHex)(txHex)) {
|
|
177
181
|
return Promise.resolve(undefined);
|
|
@@ -110,8 +110,7 @@ class SwapService {
|
|
|
110
110
|
if (!params.selectedQuote) {
|
|
111
111
|
return this.getDefaultProcessV2(params);
|
|
112
112
|
} else {
|
|
113
|
-
|
|
114
|
-
const providerId = ((_params$request$curre = params.request.currentQuote) === null || _params$request$curre === void 0 ? void 0 : _params$request$curre.id) || params.selectedQuote.provider.id;
|
|
113
|
+
const providerId = params.selectedQuote.provider.id;
|
|
115
114
|
const handler = this.handlers[providerId];
|
|
116
115
|
if (handler) {
|
|
117
116
|
// todo: handle error response from generateOptimalProcess
|
|
@@ -136,6 +135,8 @@ class SwapService {
|
|
|
136
135
|
console.group('Swap Logger');
|
|
137
136
|
console.log('path', path);
|
|
138
137
|
console.log('swapQuoteResponse', swapQuoteResponse);
|
|
138
|
+
|
|
139
|
+
// Just to log routing type for Uniswap Quote
|
|
139
140
|
if (swapQuoteResponse.optimalQuote && swapQuoteResponse.optimalQuote.metadata) {
|
|
140
141
|
const routing = swapQuoteResponse.optimalQuote.metadata.routing;
|
|
141
142
|
if (routing) {
|
|
@@ -154,7 +155,7 @@ class SwapService {
|
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
// override fee for quote because some cases need estimate network fee on Extension (i.e. Optimex)
|
|
157
|
-
if (swapQuoteResponse.optimalQuote) {
|
|
158
|
+
if (swapQuoteResponse.optimalQuote && [_swap.SwapProviderId.OPTIMEX, _swap.SwapProviderId.OPTIMEX_TESTNET].includes(swapQuoteResponse.optimalQuote.provider.id)) {
|
|
158
159
|
const swapIndex = optimalProcess.steps.findIndex(step => step.type === _swap.SwapStepType.SWAP);
|
|
159
160
|
swapQuoteResponse.optimalQuote.feeInfo.feeComponent = optimalProcess.totalFee[swapIndex].feeComponent;
|
|
160
161
|
}
|
|
@@ -197,7 +198,7 @@ class SwapService {
|
|
|
197
198
|
const swapAction = path.find(step => step.action === _types2.DynamicSwapType.SWAP);
|
|
198
199
|
const directSwapRequest = swapAction ? {
|
|
199
200
|
...request,
|
|
200
|
-
address: (0, _utils3._reformatAddressWithChain)(request.address, this.chainService.getChainInfoByKey((0, _utils._getAssetOriginChain)(this.chainService.getAssetBySlug(swapAction.pair.from)))),
|
|
201
|
+
address: (0, _utils3._reformatAddressWithChain)(request.address, this.chainService.getChainInfoByKey((0, _utils._getAssetOriginChain)(this.chainService.getAssetBySlug(swapAction.pair.from))), request.alternativeAddress),
|
|
201
202
|
pair: swapAction.pair
|
|
202
203
|
} : undefined;
|
|
203
204
|
if (!directSwapRequest) {
|