@metamask-previews/assets-controllers 66.0.0-preview-e9f8bc88 → 68.0.0-preview-510657d5
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/CHANGELOG.md +22 -1
- package/dist/NftController.cjs +82 -84
- package/dist/NftController.cjs.map +1 -1
- package/dist/NftController.d.cts +26 -41
- package/dist/NftController.d.cts.map +1 -1
- package/dist/NftController.d.mts +26 -41
- package/dist/NftController.d.mts.map +1 -1
- package/dist/NftController.mjs +83 -85
- package/dist/NftController.mjs.map +1 -1
- package/dist/NftDetectionController.cjs +2 -2
- package/dist/NftDetectionController.cjs.map +1 -1
- package/dist/NftDetectionController.d.cts +2 -1
- package/dist/NftDetectionController.d.cts.map +1 -1
- package/dist/NftDetectionController.d.mts +2 -1
- package/dist/NftDetectionController.d.mts.map +1 -1
- package/dist/NftDetectionController.mjs +2 -2
- package/dist/NftDetectionController.mjs.map +1 -1
- package/dist/token-prices-service/codefi-v2.cjs +0 -2
- package/dist/token-prices-service/codefi-v2.cjs.map +1 -1
- package/dist/token-prices-service/codefi-v2.d.cts +1 -1
- package/dist/token-prices-service/codefi-v2.d.cts.map +1 -1
- package/dist/token-prices-service/codefi-v2.d.mts +1 -1
- package/dist/token-prices-service/codefi-v2.d.mts.map +1 -1
- package/dist/token-prices-service/codefi-v2.mjs +0 -2
- package/dist/token-prices-service/codefi-v2.mjs.map +1 -1
- package/package.json +15 -15
package/dist/NftController.mjs
CHANGED
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
11
11
|
};
|
12
|
-
var _NftController_instances, _NftController_mutex, _NftController_selectedAccountId,
|
12
|
+
var _NftController_instances, _NftController_mutex, _NftController_selectedAccountId, _NftController_ipfsGateway, _NftController_openSeaEnabled, _NftController_useIpfsSubdomains, _NftController_isIpfsGatewayEnabled, _NftController_onNftAdded, _NftController_onPreferencesControllerStateChange, _NftController_onSelectedAccountChange, _NftController_updateNestedNftState, _NftController_getNftCollectionApi, _NftController_getNftInformationFromApi, _NftController_getNftInformationFromTokenURI, _NftController_getNftURIAndStandard, _NftController_getNftInformation, _NftController_getNftContractInformationFromContract, _NftController_getNftContractInformation, _NftController_addIndividualNft, _NftController_addNftContract, _NftController_removeAndIgnoreIndividualNft, _NftController_removeIndividualNft, _NftController_removeNftContract, _NftController_validateWatchNft, _NftController_getAddressOrSelectedAddress, _NftController_updateNftUpdateForAccount, _NftController_bulkSanitizeNftMetadata, _NftController_sanitizeNftMetadata;
|
13
13
|
function $importDefault(module) {
|
14
14
|
if (module?.__esModule) {
|
15
15
|
return module.default;
|
@@ -18,7 +18,7 @@ function $importDefault(module) {
|
|
18
18
|
}
|
19
19
|
import { isAddress } from "@ethersproject/address";
|
20
20
|
import { BaseController } from "@metamask/base-controller";
|
21
|
-
import { safelyExecute, handleFetch, toChecksumHexAddress, BNToHex, fetchWithErrorHandling, IPFS_DEFAULT_GATEWAY_URL, ERC721, ERC1155, ApprovalType, NFT_API_BASE_URL, NFT_API_VERSION, convertHexToDecimal } from "@metamask/controller-utils";
|
21
|
+
import { safelyExecute, handleFetch, toChecksumHexAddress, BNToHex, fetchWithErrorHandling, IPFS_DEFAULT_GATEWAY_URL, ERC721, ERC1155, ApprovalType, NFT_API_BASE_URL, NFT_API_VERSION, convertHexToDecimal, toHex } from "@metamask/controller-utils";
|
22
22
|
import { RecommendedAction } from "@metamask/phishing-controller";
|
23
23
|
import { rpcErrors } from "@metamask/rpc-errors";
|
24
24
|
import { remove0x } from "@metamask/utils";
|
@@ -53,7 +53,6 @@ export class NftController extends BaseController {
|
|
53
53
|
* Creates an NftController instance.
|
54
54
|
*
|
55
55
|
* @param options - The controller options.
|
56
|
-
* @param options.chainId - The chain ID of the current network.
|
57
56
|
* @param options.ipfsGateway - The configured IPFS gateway.
|
58
57
|
* @param options.openSeaEnabled - Controls whether the OpenSea API is used.
|
59
58
|
* @param options.useIpfsSubdomains - Controls whether IPFS subdomains are used.
|
@@ -63,7 +62,7 @@ export class NftController extends BaseController {
|
|
63
62
|
* @param options.messenger - The messenger.
|
64
63
|
* @param options.state - Initial state to set on this controller.
|
65
64
|
*/
|
66
|
-
constructor({
|
65
|
+
constructor({ ipfsGateway = IPFS_DEFAULT_GATEWAY_URL, openSeaEnabled = false, useIpfsSubdomains = true, isIpfsGatewayEnabled = true, onNftAdded, messenger, state = {}, }) {
|
67
66
|
super({
|
68
67
|
name: controllerName,
|
69
68
|
metadata: nftControllerMetadata,
|
@@ -76,14 +75,12 @@ export class NftController extends BaseController {
|
|
76
75
|
_NftController_instances.add(this);
|
77
76
|
_NftController_mutex.set(this, new Mutex());
|
78
77
|
_NftController_selectedAccountId.set(this, void 0);
|
79
|
-
_NftController_chainId.set(this, void 0);
|
80
78
|
_NftController_ipfsGateway.set(this, void 0);
|
81
79
|
_NftController_openSeaEnabled.set(this, void 0);
|
82
80
|
_NftController_useIpfsSubdomains.set(this, void 0);
|
83
81
|
_NftController_isIpfsGatewayEnabled.set(this, void 0);
|
84
82
|
_NftController_onNftAdded.set(this, void 0);
|
85
83
|
__classPrivateFieldSet(this, _NftController_selectedAccountId, this.messagingSystem.call('AccountsController:getSelectedAccount').id, "f");
|
86
|
-
__classPrivateFieldSet(this, _NftController_chainId, initialChainId, "f");
|
87
84
|
__classPrivateFieldSet(this, _NftController_ipfsGateway, ipfsGateway, "f");
|
88
85
|
__classPrivateFieldSet(this, _NftController_openSeaEnabled, openSeaEnabled, "f");
|
89
86
|
__classPrivateFieldSet(this, _NftController_useIpfsSubdomains, useIpfsSubdomains, "f");
|
@@ -93,7 +90,6 @@ export class NftController extends BaseController {
|
|
93
90
|
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
94
91
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
95
92
|
__classPrivateFieldGet(this, _NftController_instances, "m", _NftController_onPreferencesControllerStateChange).bind(this));
|
96
|
-
this.messagingSystem.subscribe('NetworkController:networkDidChange', __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_onNetworkControllerNetworkDidChange).bind(this));
|
97
93
|
this.messagingSystem.subscribe('AccountsController:selectedEvmAccountChange',
|
98
94
|
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
99
95
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
@@ -113,17 +109,20 @@ export class NftController extends BaseController {
|
|
113
109
|
* @param asset.tokenId - The ID of the asset.
|
114
110
|
* @param type - The asset type.
|
115
111
|
* @param origin - Domain origin to register the asset from.
|
112
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
116
113
|
* @param options - Options bag.
|
117
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
118
114
|
* @param options.userAddress - The address of the account where the NFT is being added.
|
119
115
|
* @returns Object containing a Promise resolving to the suggestedAsset address if accepted.
|
120
116
|
*/
|
121
|
-
async watchNft(asset, type, origin,
|
117
|
+
async watchNft(asset, type, origin, networkClientId, { userAddress, } = {}) {
|
122
118
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
123
119
|
if (!addressToSearch) {
|
124
120
|
return;
|
125
121
|
}
|
126
|
-
|
122
|
+
if (!networkClientId) {
|
123
|
+
throw rpcErrors.invalidParams('Network client id is required');
|
124
|
+
}
|
125
|
+
await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_validateWatchNft).call(this, asset, type, addressToSearch, networkClientId);
|
127
126
|
const nftMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, asset.address, asset.tokenId, networkClientId);
|
128
127
|
// Sanitize metadata
|
129
128
|
const sanitizedMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_sanitizeNftMetadata).call(this, nftMetadata);
|
@@ -141,7 +140,7 @@ export class NftController extends BaseController {
|
|
141
140
|
await this._requestApproval(suggestedNftMeta);
|
142
141
|
const { address, tokenId } = asset;
|
143
142
|
const { name, standard, description, image } = sanitizedMetadata;
|
144
|
-
await this.addNft(address, tokenId, {
|
143
|
+
await this.addNft(address, tokenId, networkClientId, {
|
145
144
|
nftMetadata: {
|
146
145
|
name: name ?? null,
|
147
146
|
description: description ?? null,
|
@@ -150,7 +149,6 @@ export class NftController extends BaseController {
|
|
150
149
|
},
|
151
150
|
userAddress,
|
152
151
|
source: Source.Dapp,
|
153
|
-
networkClientId,
|
154
152
|
});
|
155
153
|
}
|
156
154
|
/**
|
@@ -167,11 +165,10 @@ export class NftController extends BaseController {
|
|
167
165
|
* @param ownerAddress - User public address.
|
168
166
|
* @param nftAddress - NFT contract address.
|
169
167
|
* @param tokenId - NFT token ID.
|
170
|
-
* @param
|
171
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
168
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
172
169
|
* @returns Promise resolving the NFT ownership.
|
173
170
|
*/
|
174
|
-
async isNftOwner(ownerAddress, nftAddress, tokenId,
|
171
|
+
async isNftOwner(ownerAddress, nftAddress, tokenId, networkClientId) {
|
175
172
|
// Checks the ownership for ERC-721.
|
176
173
|
try {
|
177
174
|
const owner = await this.messagingSystem.call('AssetsContractController:getERC721OwnerOf', nftAddress, tokenId, networkClientId);
|
@@ -198,20 +195,17 @@ export class NftController extends BaseController {
|
|
198
195
|
*
|
199
196
|
* @param address - Hex address of the NFT contract.
|
200
197
|
* @param tokenId - The NFT identifier.
|
198
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
201
199
|
* @param options - an object of arguments
|
202
200
|
* @param options.userAddress - The address of the current user.
|
203
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
204
201
|
* @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
|
205
202
|
*/
|
206
|
-
async addNftVerifyOwnership(address, tokenId, { userAddress,
|
203
|
+
async addNftVerifyOwnership(address, tokenId, networkClientId, { userAddress, source, } = {}) {
|
207
204
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
208
|
-
if (!(await this.isNftOwner(addressToSearch, address, tokenId, {
|
209
|
-
networkClientId,
|
210
|
-
}))) {
|
205
|
+
if (!(await this.isNftOwner(addressToSearch, address, tokenId, networkClientId))) {
|
211
206
|
throw new Error('This NFT is not owned by the user');
|
212
207
|
}
|
213
|
-
await this.addNft(address, tokenId, {
|
214
|
-
networkClientId,
|
208
|
+
await this.addNft(address, tokenId, networkClientId, {
|
215
209
|
userAddress: addressToSearch,
|
216
210
|
source,
|
217
211
|
});
|
@@ -221,22 +215,19 @@ export class NftController extends BaseController {
|
|
221
215
|
*
|
222
216
|
* @param tokenAddress - Hex address of the NFT contract.
|
223
217
|
* @param tokenId - The NFT identifier.
|
218
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
224
219
|
* @param options - an object of arguments
|
225
220
|
* @param options.nftMetadata - NFT optional metadata.
|
226
221
|
* @param options.userAddress - The address of the current user.
|
227
222
|
* @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
|
228
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
229
|
-
* @param options.chainId - The chain ID to add the NFT to.
|
230
223
|
* @returns Promise resolving to the current NFT list.
|
231
224
|
*/
|
232
|
-
async addNft(tokenAddress, tokenId, { nftMetadata, userAddress, source = Source.Custom,
|
225
|
+
async addNft(tokenAddress, tokenId, networkClientId, { nftMetadata, userAddress, source = Source.Custom, } = {}) {
|
233
226
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
234
227
|
if (!addressToSearch) {
|
235
228
|
return;
|
236
229
|
}
|
237
230
|
const checksumHexAddress = toChecksumHexAddress(tokenAddress);
|
238
|
-
// TODO: revisit this with Solana support and instead of passing chainId, make sure chainId is read from nftMetadata
|
239
|
-
const chainIdToAddTo = chainId || __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
240
231
|
if (!nftMetadata) {
|
241
232
|
const fetchedMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, checksumHexAddress, tokenId, networkClientId);
|
242
233
|
// Sanitize metadata
|
@@ -246,23 +237,23 @@ export class NftController extends BaseController {
|
|
246
237
|
// Sanitize provided metadata
|
247
238
|
nftMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_sanitizeNftMetadata).call(this, nftMetadata);
|
248
239
|
}
|
249
|
-
const newNftContracts = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addNftContract).call(this, {
|
240
|
+
const newNftContracts = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addNftContract).call(this, networkClientId, {
|
250
241
|
tokenAddress: checksumHexAddress,
|
251
242
|
userAddress: addressToSearch,
|
252
|
-
networkClientId,
|
253
243
|
source,
|
254
244
|
nftMetadata,
|
255
|
-
chainIdHex: source === Source.Detected ? chainIdToAddTo : undefined,
|
256
245
|
});
|
257
246
|
// If NFT contract was not added, do not add individual NFT
|
258
247
|
const nftContract = newNftContracts.find((contract) => contract.address.toLowerCase() === checksumHexAddress.toLowerCase());
|
248
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
259
249
|
// This is the case when the NFT is added manually and not detected automatically
|
250
|
+
// TODO: An improvement would be to make the chainId a required field and return it when getting the NFT information
|
260
251
|
if (!nftMetadata.chainId) {
|
261
|
-
nftMetadata.chainId = convertHexToDecimal(
|
252
|
+
nftMetadata.chainId = convertHexToDecimal(chainId);
|
262
253
|
}
|
263
254
|
// If NFT contract information, add individual NFT
|
264
255
|
if (nftContract) {
|
265
|
-
await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addIndividualNft).call(this, checksumHexAddress, tokenId, nftMetadata, nftContract,
|
256
|
+
await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addIndividualNft).call(this, checksumHexAddress, tokenId, nftMetadata, nftContract, chainId, addressToSearch, source);
|
266
257
|
}
|
267
258
|
}
|
268
259
|
/**
|
@@ -271,13 +262,11 @@ export class NftController extends BaseController {
|
|
271
262
|
* @param options - Options for refetching NFT metadata
|
272
263
|
* @param options.nfts - nfts to update metadata for.
|
273
264
|
* @param options.userAddress - The current user address
|
274
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
275
265
|
*/
|
276
|
-
async updateNftMetadata({ nfts, userAddress,
|
266
|
+
async updateNftMetadata({ nfts, userAddress, }) {
|
277
267
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
278
268
|
const releaseLock = await __classPrivateFieldGet(this, _NftController_mutex, "f").acquire();
|
279
269
|
try {
|
280
|
-
const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
281
270
|
const nftsWithChecksumAdr = nfts.map((nft) => {
|
282
271
|
return {
|
283
272
|
...nft,
|
@@ -286,7 +275,11 @@ export class NftController extends BaseController {
|
|
286
275
|
});
|
287
276
|
// Get all unsanitized nft metadata
|
288
277
|
const unsanitizedResults = await Promise.all(nftsWithChecksumAdr.map(async (nft) => {
|
289
|
-
|
278
|
+
// Each NFT should have a chainId; convert nft.chainId to networkClientId
|
279
|
+
const networkClientId = this.messagingSystem.call('NetworkController:findNetworkClientIdByChainId', toHex(nft.chainId));
|
280
|
+
const resMetadata = networkClientId
|
281
|
+
? await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, nft.address, nft.tokenId, networkClientId)
|
282
|
+
: undefined;
|
290
283
|
return {
|
291
284
|
nft,
|
292
285
|
newMetadata: resMetadata,
|
@@ -304,19 +297,27 @@ export class NftController extends BaseController {
|
|
304
297
|
// We want to avoid updating the state if the state and fetched nft info are the same
|
305
298
|
const nftsWithDifferentMetadata = [];
|
306
299
|
const { allNfts } = this.state;
|
307
|
-
|
300
|
+
// get from state allNfts that match nftsWithChecksumAdr
|
301
|
+
const stateNfts = nftsWithChecksumAdr.map((nft) => {
|
302
|
+
return allNfts[addressToSearch]?.[toHex(nft.chainId)]?.find((nftElement) => nftElement.address.toLowerCase() === nft.address.toLowerCase() &&
|
303
|
+
nftElement.tokenId === nft.tokenId);
|
304
|
+
});
|
308
305
|
nftMetadataResults.forEach((singleNft) => {
|
309
|
-
const existingEntry = stateNfts.find((nft) => nft
|
310
|
-
|
311
|
-
|
306
|
+
const existingEntry = stateNfts.find((nft) => nft?.address.toLowerCase() ===
|
307
|
+
singleNft.nft.address.toLowerCase() &&
|
308
|
+
nft?.tokenId === singleNft.nft.tokenId);
|
309
|
+
if (existingEntry && singleNft.newMetadata) {
|
312
310
|
const differentMetadata = compareNftMetadata(singleNft.newMetadata, existingEntry);
|
313
311
|
if (differentMetadata) {
|
314
|
-
nftsWithDifferentMetadata.push(
|
312
|
+
nftsWithDifferentMetadata.push({
|
313
|
+
nft: singleNft.nft,
|
314
|
+
newMetadata: singleNft.newMetadata,
|
315
|
+
});
|
315
316
|
}
|
316
317
|
}
|
317
318
|
});
|
318
319
|
if (nftsWithDifferentMetadata.length !== 0) {
|
319
|
-
nftsWithDifferentMetadata.forEach((elm) => this.updateNft(elm.nft, elm.newMetadata, addressToSearch, chainId));
|
320
|
+
nftsWithDifferentMetadata.forEach((elm) => this.updateNft(elm.nft, elm.newMetadata, addressToSearch, toHex(elm.nft.chainId)));
|
320
321
|
}
|
321
322
|
}
|
322
323
|
finally {
|
@@ -328,13 +329,13 @@ export class NftController extends BaseController {
|
|
328
329
|
*
|
329
330
|
* @param address - Hex address of the NFT contract.
|
330
331
|
* @param tokenId - Token identifier of the NFT.
|
332
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
331
333
|
* @param options - an object of arguments
|
332
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
333
334
|
* @param options.userAddress - The address of the account where the NFT is being removed.
|
334
335
|
*/
|
335
|
-
removeNft(address, tokenId,
|
336
|
+
removeNft(address, tokenId, networkClientId, { userAddress } = {}) {
|
336
337
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
337
|
-
const
|
338
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
338
339
|
const checksumHexAddress = toChecksumHexAddress(address);
|
339
340
|
__classPrivateFieldGet(this, _NftController_instances, "m", _NftController_removeIndividualNft).call(this, checksumHexAddress, tokenId, {
|
340
341
|
chainId,
|
@@ -355,13 +356,13 @@ export class NftController extends BaseController {
|
|
355
356
|
*
|
356
357
|
* @param address - Hex address of the NFT contract.
|
357
358
|
* @param tokenId - Token identifier of the NFT.
|
359
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
358
360
|
* @param options - an object of arguments
|
359
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
360
361
|
* @param options.userAddress - The address of the account where the NFT is being removed.
|
361
362
|
*/
|
362
|
-
removeAndIgnoreNft(address, tokenId,
|
363
|
+
removeAndIgnoreNft(address, tokenId, networkClientId, { userAddress } = {}) {
|
363
364
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
364
|
-
const
|
365
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
365
366
|
const checksumHexAddress = toChecksumHexAddress(address);
|
366
367
|
__classPrivateFieldGet(this, _NftController_instances, "m", _NftController_removeAndIgnoreIndividualNft).call(this, checksumHexAddress, tokenId, {
|
367
368
|
chainId,
|
@@ -391,20 +392,18 @@ export class NftController extends BaseController {
|
|
391
392
|
*
|
392
393
|
* @param nft - The NFT object to check and update.
|
393
394
|
* @param batch - A boolean indicating whether this method is being called as part of a batch or single update.
|
395
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
394
396
|
* @param accountParams - The userAddress and chainId to check ownership against
|
395
397
|
* @param accountParams.userAddress - the address passed through the confirmed transaction flow to ensure assets are stored to the correct account
|
396
|
-
* @param accountParams.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
397
398
|
* @returns the NFT with the updated isCurrentlyOwned value
|
398
399
|
*/
|
399
|
-
async checkAndUpdateSingleNftOwnershipStatus(nft, batch, { userAddress
|
400
|
+
async checkAndUpdateSingleNftOwnershipStatus(nft, batch, networkClientId, { userAddress } = {}) {
|
400
401
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
401
|
-
const
|
402
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
402
403
|
const { address, tokenId } = nft;
|
403
404
|
let isOwned = nft.isCurrentlyOwned;
|
404
405
|
try {
|
405
|
-
isOwned = await this.isNftOwner(addressToSearch, address, tokenId,
|
406
|
-
networkClientId,
|
407
|
-
});
|
406
|
+
isOwned = await this.isNftOwner(addressToSearch, address, tokenId, networkClientId);
|
408
407
|
}
|
409
408
|
catch {
|
410
409
|
// ignore error
|
@@ -440,18 +439,18 @@ export class NftController extends BaseController {
|
|
440
439
|
/**
|
441
440
|
* Checks whether NFTs associated with current selectedAddress/chainId combination are still owned by the user
|
442
441
|
* And updates the isCurrentlyOwned value on each accordingly.
|
442
|
+
*
|
443
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
443
444
|
* @param options - an object of arguments
|
444
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
445
445
|
* @param options.userAddress - The address of the account where the NFT ownership status is checked/updated.
|
446
446
|
*/
|
447
|
-
async checkAndUpdateAllNftsOwnershipStatus(
|
447
|
+
async checkAndUpdateAllNftsOwnershipStatus(networkClientId, { userAddress, } = {}) {
|
448
448
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
449
|
-
const
|
449
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
450
450
|
const { allNfts } = this.state;
|
451
451
|
const nfts = allNfts[addressToSearch]?.[chainId] || [];
|
452
452
|
const updatedNfts = await Promise.all(nfts.map(async (nft) => {
|
453
|
-
return ((await this.checkAndUpdateSingleNftOwnershipStatus(nft, true, {
|
454
|
-
networkClientId,
|
453
|
+
return ((await this.checkAndUpdateSingleNftOwnershipStatus(nft, true, networkClientId, {
|
455
454
|
userAddress,
|
456
455
|
})) ?? nft);
|
457
456
|
}));
|
@@ -466,13 +465,13 @@ export class NftController extends BaseController {
|
|
466
465
|
* @param address - Hex address of the NFT contract.
|
467
466
|
* @param tokenId - Hex address of the NFT contract.
|
468
467
|
* @param favorite - NFT new favorite status.
|
468
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
469
469
|
* @param options - an object of arguments
|
470
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
471
470
|
* @param options.userAddress - The address of the account where the NFT is being removed.
|
472
471
|
*/
|
473
|
-
updateNftFavoriteStatus(address, tokenId, favorite,
|
472
|
+
updateNftFavoriteStatus(address, tokenId, favorite, networkClientId, { userAddress, } = {}) {
|
474
473
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
475
|
-
const
|
474
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
476
475
|
const { allNfts } = this.state;
|
477
476
|
const nfts = [...(allNfts[addressToSearch]?.[chainId] || [])];
|
478
477
|
const index = nfts.findIndex((nft) => nft.address === address && nft.tokenId === tokenId);
|
@@ -615,12 +614,10 @@ export class NftController extends BaseController {
|
|
615
614
|
});
|
616
615
|
}
|
617
616
|
}
|
618
|
-
_NftController_mutex = new WeakMap(), _NftController_selectedAccountId = new WeakMap(),
|
619
|
-
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
|
620
|
-
__classPrivateFieldSet(this, _NftController_chainId, chainId, "f");
|
621
|
-
}, _NftController_onPreferencesControllerStateChange =
|
617
|
+
_NftController_mutex = new WeakMap(), _NftController_selectedAccountId = new WeakMap(), _NftController_ipfsGateway = new WeakMap(), _NftController_openSeaEnabled = new WeakMap(), _NftController_useIpfsSubdomains = new WeakMap(), _NftController_isIpfsGatewayEnabled = new WeakMap(), _NftController_onNftAdded = new WeakMap(), _NftController_instances = new WeakSet(), _NftController_onPreferencesControllerStateChange =
|
622
618
|
/**
|
623
619
|
* Handles the state change of the preference controller.
|
620
|
+
*
|
624
621
|
* @param preferencesState - The new state of the preference controller.
|
625
622
|
* @param preferencesState.ipfsGateway - The configured IPFS gateway.
|
626
623
|
* @param preferencesState.openSeaEnabled - Controls whether the OpenSea API is used.
|
@@ -644,6 +641,7 @@ async function _NftController_onPreferencesControllerStateChange({ ipfsGateway,
|
|
644
641
|
}, _NftController_onSelectedAccountChange =
|
645
642
|
/**
|
646
643
|
* Handles the selected account change on the accounts controller.
|
644
|
+
*
|
647
645
|
* @param internalAccount - The new selected account.
|
648
646
|
*/
|
649
647
|
async function _NftController_onSelectedAccountChange(internalAccount) {
|
@@ -866,9 +864,7 @@ async function _NftController_getNftURIAndStandard(contractAddress, tokenId, net
|
|
866
864
|
* @returns Promise resolving to the current NFT name and image.
|
867
865
|
*/
|
868
866
|
async function _NftController_getNftInformation(contractAddress, tokenId, networkClientId) {
|
869
|
-
const
|
870
|
-
networkClientId,
|
871
|
-
});
|
867
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
872
868
|
const [blockchainMetadata, nftApiMetadata] = await Promise.all([
|
873
869
|
safelyExecute(() => __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformationFromTokenURI).call(this, contractAddress, tokenId, networkClientId)),
|
874
870
|
__classPrivateFieldGet(this, _NftController_openSeaEnabled, "f") && chainId === '0x1'
|
@@ -893,7 +889,9 @@ async function _NftController_getNftInformation(contractAddress, tokenId, networ
|
|
893
889
|
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
894
890
|
* @returns Promise resolving to the current NFT name and image.
|
895
891
|
*/
|
896
|
-
async function _NftController_getNftContractInformationFromContract(
|
892
|
+
async function _NftController_getNftContractInformationFromContract(
|
893
|
+
// TODO for calls to blockchain we need to explicitly pass the currentNetworkClientId since its relying on the provider
|
894
|
+
contractAddress, networkClientId) {
|
897
895
|
const [name, symbol] = await Promise.all([
|
898
896
|
this.messagingSystem.call('AssetsContractController:getERC721AssetName', contractAddress, networkClientId),
|
899
897
|
this.messagingSystem.call('AssetsContractController:getERC721AssetSymbol', contractAddress, networkClientId),
|
@@ -1028,22 +1026,20 @@ async function _NftController_addIndividualNft(tokenAddress, tokenId, nftMetadat
|
|
1028
1026
|
/**
|
1029
1027
|
* Adds an NFT contract to the stored NFT contracts list.
|
1030
1028
|
*
|
1029
|
+
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
1031
1030
|
* @param options - options.
|
1032
1031
|
* @param options.tokenAddress - Hex address of the NFT contract.
|
1033
1032
|
* @param options.userAddress - The address of the account where the NFT is being added.
|
1034
1033
|
* @param options.nftMetadata - The retrieved NFTMetadata from API.
|
1035
|
-
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
1036
1034
|
* @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
|
1037
|
-
* @param options.chainIdHex - The chainId to add the NFT contract to.
|
1038
1035
|
* @returns Promise resolving to the current NFT contracts list.
|
1039
1036
|
*/
|
1040
|
-
async function _NftController_addNftContract({ tokenAddress, userAddress,
|
1037
|
+
async function _NftController_addNftContract(networkClientId, { tokenAddress, userAddress, source, nftMetadata, }) {
|
1041
1038
|
const releaseLock = await __classPrivateFieldGet(this, _NftController_mutex, "f").acquire();
|
1042
1039
|
try {
|
1043
1040
|
const checksumHexAddress = toChecksumHexAddress(tokenAddress);
|
1044
1041
|
const { allNftContracts } = this.state;
|
1045
|
-
|
1046
|
-
const chainId = chainIdHex || __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
1042
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
1047
1043
|
const nftContracts = allNftContracts[userAddress]?.[chainId] || [];
|
1048
1044
|
const existingEntry = nftContracts.find((nftContract) => nftContract.address.toLowerCase() ===
|
1049
1045
|
checksumHexAddress.toLowerCase());
|
@@ -1137,7 +1133,7 @@ async function _NftController_addNftContract({ tokenAddress, userAddress, networ
|
|
1137
1133
|
userAddress,
|
1138
1134
|
});
|
1139
1135
|
return newNftContracts;
|
1140
|
-
}, _NftController_validateWatchNft = async function _NftController_validateWatchNft(asset, type, userAddress,
|
1136
|
+
}, _NftController_validateWatchNft = async function _NftController_validateWatchNft(asset, type, userAddress, networkClientId) {
|
1141
1137
|
const { address: contractAddress, tokenId } = asset;
|
1142
1138
|
// Validate parameters
|
1143
1139
|
if (!type) {
|
@@ -1160,7 +1156,7 @@ async function _NftController_addNftContract({ tokenAddress, userAddress, networ
|
|
1160
1156
|
}
|
1161
1157
|
// Check if the user owns the suggested NFT
|
1162
1158
|
try {
|
1163
|
-
const isOwner = await this.isNftOwner(userAddress, contractAddress, tokenId,
|
1159
|
+
const isOwner = await this.isNftOwner(userAddress, contractAddress, tokenId, networkClientId);
|
1164
1160
|
if (!isOwner) {
|
1165
1161
|
throw rpcErrors.invalidInput('Suggested NFT is not owned by the selected account');
|
1166
1162
|
}
|
@@ -1172,12 +1168,6 @@ async function _NftController_addNftContract({ tokenAddress, userAddress, networ
|
|
1172
1168
|
}
|
1173
1169
|
throw error;
|
1174
1170
|
}
|
1175
|
-
}, _NftController_getCorrectChainId = function _NftController_getCorrectChainId({ networkClientId, }) {
|
1176
|
-
if (networkClientId) {
|
1177
|
-
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
1178
|
-
return chainId;
|
1179
|
-
}
|
1180
|
-
return __classPrivateFieldGet(this, _NftController_chainId, "f");
|
1181
1171
|
}, _NftController_getAddressOrSelectedAddress = function _NftController_getAddressOrSelectedAddress(address) {
|
1182
1172
|
if (address) {
|
1183
1173
|
return address;
|
@@ -1185,8 +1175,16 @@ async function _NftController_addNftContract({ tokenAddress, userAddress, networ
|
|
1185
1175
|
// If the address is not defined (or empty), we fallback to the currently selected account's address
|
1186
1176
|
const selectedAccount = this.messagingSystem.call('AccountsController:getAccount', __classPrivateFieldGet(this, _NftController_selectedAccountId, "f"));
|
1187
1177
|
return selectedAccount?.address || '';
|
1188
|
-
}, _NftController_updateNftUpdateForAccount =
|
1189
|
-
|
1178
|
+
}, _NftController_updateNftUpdateForAccount =
|
1179
|
+
/**
|
1180
|
+
* Updates the all nfts in state for the account.
|
1181
|
+
* Nfts will be updated if they don't have a name, description or image.
|
1182
|
+
*
|
1183
|
+
* @param account - The account to update the NFT metadata for.
|
1184
|
+
*/
|
1185
|
+
async function _NftController_updateNftUpdateForAccount(account) {
|
1186
|
+
// get all nfts for the account for all chains
|
1187
|
+
const nfts = Object.values(this.state.allNfts[account.address] || {}).flat();
|
1190
1188
|
// Filter only nfts
|
1191
1189
|
const nftsToUpdate = nfts.filter((singleNft) => !singleNft.name && !singleNft.description && !singleNft.image);
|
1192
1190
|
if (nftsToUpdate.length !== 0 &&
|