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