@metamask-previews/assets-controllers 56.0.0-preview-3fadbce0 → 56.0.0-preview-01658838
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/dist/NftController.cjs +84 -83
- 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 -84
- 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;
|
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;
|
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 { rpcErrors } from "@metamask/rpc-errors";
|
23
23
|
import { remove0x } from "@metamask/utils";
|
24
24
|
import { Mutex } from "async-mutex";
|
@@ -52,6 +52,7 @@ export class NftController extends BaseController {
|
|
52
52
|
* Creates an NftController instance.
|
53
53
|
*
|
54
54
|
* @param options - The controller options.
|
55
|
+
* @param options.chainId - The chain ID of the current network.
|
55
56
|
* @param options.ipfsGateway - The configured IPFS gateway.
|
56
57
|
* @param options.openSeaEnabled - Controls whether the OpenSea API is used.
|
57
58
|
* @param options.useIpfsSubdomains - Controls whether IPFS subdomains are used.
|
@@ -61,7 +62,7 @@ export class NftController extends BaseController {
|
|
61
62
|
* @param options.messenger - The messenger.
|
62
63
|
* @param options.state - Initial state to set on this controller.
|
63
64
|
*/
|
64
|
-
constructor({ ipfsGateway = IPFS_DEFAULT_GATEWAY_URL, openSeaEnabled = false, useIpfsSubdomains = true, isIpfsGatewayEnabled = true, onNftAdded, messenger, state = {}, }) {
|
65
|
+
constructor({ chainId: initialChainId, ipfsGateway = IPFS_DEFAULT_GATEWAY_URL, openSeaEnabled = false, useIpfsSubdomains = true, isIpfsGatewayEnabled = true, onNftAdded, messenger, state = {}, }) {
|
65
66
|
super({
|
66
67
|
name: controllerName,
|
67
68
|
metadata: nftControllerMetadata,
|
@@ -74,12 +75,14 @@ export class NftController extends BaseController {
|
|
74
75
|
_NftController_instances.add(this);
|
75
76
|
_NftController_mutex.set(this, new Mutex());
|
76
77
|
_NftController_selectedAccountId.set(this, void 0);
|
78
|
+
_NftController_chainId.set(this, void 0);
|
77
79
|
_NftController_ipfsGateway.set(this, void 0);
|
78
80
|
_NftController_openSeaEnabled.set(this, void 0);
|
79
81
|
_NftController_useIpfsSubdomains.set(this, void 0);
|
80
82
|
_NftController_isIpfsGatewayEnabled.set(this, void 0);
|
81
83
|
_NftController_onNftAdded.set(this, void 0);
|
82
84
|
__classPrivateFieldSet(this, _NftController_selectedAccountId, this.messagingSystem.call('AccountsController:getSelectedAccount').id, "f");
|
85
|
+
__classPrivateFieldSet(this, _NftController_chainId, initialChainId, "f");
|
83
86
|
__classPrivateFieldSet(this, _NftController_ipfsGateway, ipfsGateway, "f");
|
84
87
|
__classPrivateFieldSet(this, _NftController_openSeaEnabled, openSeaEnabled, "f");
|
85
88
|
__classPrivateFieldSet(this, _NftController_useIpfsSubdomains, useIpfsSubdomains, "f");
|
@@ -89,6 +92,7 @@ export class NftController extends BaseController {
|
|
89
92
|
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
90
93
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
91
94
|
__classPrivateFieldGet(this, _NftController_instances, "m", _NftController_onPreferencesControllerStateChange).bind(this));
|
95
|
+
this.messagingSystem.subscribe('NetworkController:networkDidChange', __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_onNetworkControllerNetworkDidChange).bind(this));
|
92
96
|
this.messagingSystem.subscribe('AccountsController:selectedEvmAccountChange',
|
93
97
|
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
94
98
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
@@ -108,20 +112,17 @@ export class NftController extends BaseController {
|
|
108
112
|
* @param asset.tokenId - The ID of the asset.
|
109
113
|
* @param type - The asset type.
|
110
114
|
* @param origin - Domain origin to register the asset from.
|
111
|
-
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
112
115
|
* @param options - Options bag.
|
116
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
113
117
|
* @param options.userAddress - The address of the account where the NFT is being added.
|
114
118
|
* @returns Object containing a Promise resolving to the suggestedAsset address if accepted.
|
115
119
|
*/
|
116
|
-
async watchNft(asset, type, origin, networkClientId,
|
120
|
+
async watchNft(asset, type, origin, { networkClientId, userAddress, } = {}) {
|
117
121
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
118
122
|
if (!addressToSearch) {
|
119
123
|
return;
|
120
124
|
}
|
121
|
-
|
122
|
-
throw rpcErrors.invalidParams('Network client id is required');
|
123
|
-
}
|
124
|
-
await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_validateWatchNft).call(this, asset, type, addressToSearch, networkClientId);
|
125
|
+
await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_validateWatchNft).call(this, asset, type, addressToSearch);
|
125
126
|
const nftMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, asset.address, asset.tokenId, networkClientId);
|
126
127
|
if (nftMetadata.standard && nftMetadata.standard !== type) {
|
127
128
|
throw rpcErrors.invalidInput(`Suggested NFT of type ${nftMetadata.standard} does not match received type ${type}`);
|
@@ -137,7 +138,7 @@ export class NftController extends BaseController {
|
|
137
138
|
await this._requestApproval(suggestedNftMeta);
|
138
139
|
const { address, tokenId } = asset;
|
139
140
|
const { name, standard, description, image } = nftMetadata;
|
140
|
-
await this.addNft(address, tokenId,
|
141
|
+
await this.addNft(address, tokenId, {
|
141
142
|
nftMetadata: {
|
142
143
|
name: name ?? null,
|
143
144
|
description: description ?? null,
|
@@ -146,6 +147,7 @@ export class NftController extends BaseController {
|
|
146
147
|
},
|
147
148
|
userAddress,
|
148
149
|
source: Source.Dapp,
|
150
|
+
networkClientId,
|
149
151
|
});
|
150
152
|
}
|
151
153
|
/**
|
@@ -162,10 +164,11 @@ export class NftController extends BaseController {
|
|
162
164
|
* @param ownerAddress - User public address.
|
163
165
|
* @param nftAddress - NFT contract address.
|
164
166
|
* @param tokenId - NFT token ID.
|
165
|
-
* @param
|
167
|
+
* @param options - Options bag.
|
168
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
166
169
|
* @returns Promise resolving the NFT ownership.
|
167
170
|
*/
|
168
|
-
async isNftOwner(ownerAddress, nftAddress, tokenId, networkClientId) {
|
171
|
+
async isNftOwner(ownerAddress, nftAddress, tokenId, { networkClientId, } = {}) {
|
169
172
|
// Checks the ownership for ERC-721.
|
170
173
|
try {
|
171
174
|
const owner = await this.messagingSystem.call('AssetsContractController:getERC721OwnerOf', nftAddress, tokenId, networkClientId);
|
@@ -192,17 +195,20 @@ export class NftController extends BaseController {
|
|
192
195
|
*
|
193
196
|
* @param address - Hex address of the NFT contract.
|
194
197
|
* @param tokenId - The NFT identifier.
|
195
|
-
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
196
198
|
* @param options - an object of arguments
|
197
199
|
* @param options.userAddress - The address of the current user.
|
200
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
198
201
|
* @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
|
199
202
|
*/
|
200
|
-
async addNftVerifyOwnership(address, tokenId,
|
203
|
+
async addNftVerifyOwnership(address, tokenId, { userAddress, networkClientId, source, } = {}) {
|
201
204
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
202
|
-
if (!(await this.isNftOwner(addressToSearch, address, tokenId,
|
205
|
+
if (!(await this.isNftOwner(addressToSearch, address, tokenId, {
|
206
|
+
networkClientId,
|
207
|
+
}))) {
|
203
208
|
throw new Error('This NFT is not owned by the user');
|
204
209
|
}
|
205
|
-
await this.addNft(address, tokenId,
|
210
|
+
await this.addNft(address, tokenId, {
|
211
|
+
networkClientId,
|
206
212
|
userAddress: addressToSearch,
|
207
213
|
source,
|
208
214
|
});
|
@@ -212,39 +218,42 @@ export class NftController extends BaseController {
|
|
212
218
|
*
|
213
219
|
* @param tokenAddress - Hex address of the NFT contract.
|
214
220
|
* @param tokenId - The NFT identifier.
|
215
|
-
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
216
221
|
* @param options - an object of arguments
|
217
222
|
* @param options.nftMetadata - NFT optional metadata.
|
218
223
|
* @param options.userAddress - The address of the current user.
|
219
224
|
* @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
|
225
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
226
|
+
* @param options.chainId - The chain ID to add the NFT to.
|
220
227
|
* @returns Promise resolving to the current NFT list.
|
221
228
|
*/
|
222
|
-
async addNft(tokenAddress, tokenId,
|
229
|
+
async addNft(tokenAddress, tokenId, { nftMetadata, userAddress, source = Source.Custom, networkClientId, chainId, } = {}) {
|
223
230
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
224
231
|
if (!addressToSearch) {
|
225
232
|
return;
|
226
233
|
}
|
227
234
|
const checksumHexAddress = toChecksumHexAddress(tokenAddress);
|
235
|
+
// TODO: revisit this with Solana support and instead of passing chainId, make sure chainId is read from nftMetadata
|
236
|
+
const chainIdToAddTo = chainId || __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
228
237
|
nftMetadata =
|
229
238
|
nftMetadata ||
|
230
239
|
(await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, checksumHexAddress, tokenId, networkClientId));
|
231
|
-
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, {
|
232
241
|
tokenAddress: checksumHexAddress,
|
233
242
|
userAddress: addressToSearch,
|
243
|
+
networkClientId,
|
234
244
|
source,
|
235
245
|
nftMetadata,
|
246
|
+
chainIdHex: source === Source.Detected ? chainIdToAddTo : undefined,
|
236
247
|
});
|
237
248
|
// If NFT contract was not added, do not add individual NFT
|
238
249
|
const nftContract = newNftContracts.find((contract) => contract.address.toLowerCase() === checksumHexAddress.toLowerCase());
|
239
|
-
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
240
250
|
// This is the case when the NFT is added manually and not detected automatically
|
241
|
-
// TODO: An improvement would be to make the chainId a required field and return it when getting the NFT information
|
242
251
|
if (!nftMetadata.chainId) {
|
243
|
-
nftMetadata.chainId = convertHexToDecimal(
|
252
|
+
nftMetadata.chainId = convertHexToDecimal(chainIdToAddTo);
|
244
253
|
}
|
245
254
|
// If NFT contract information, add individual NFT
|
246
255
|
if (nftContract) {
|
247
|
-
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, chainIdToAddTo, addressToSearch, source);
|
248
257
|
}
|
249
258
|
}
|
250
259
|
/**
|
@@ -253,11 +262,13 @@ export class NftController extends BaseController {
|
|
253
262
|
* @param options - Options for refetching NFT metadata
|
254
263
|
* @param options.nfts - nfts to update metadata for.
|
255
264
|
* @param options.userAddress - The current user address
|
265
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
256
266
|
*/
|
257
|
-
async updateNftMetadata({ nfts, userAddress, }) {
|
267
|
+
async updateNftMetadata({ nfts, userAddress, networkClientId, }) {
|
258
268
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
259
269
|
const releaseLock = await __classPrivateFieldGet(this, _NftController_mutex, "f").acquire();
|
260
270
|
try {
|
271
|
+
const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
261
272
|
const nftsWithChecksumAdr = nfts.map((nft) => {
|
262
273
|
return {
|
263
274
|
...nft,
|
@@ -265,11 +276,7 @@ export class NftController extends BaseController {
|
|
265
276
|
};
|
266
277
|
});
|
267
278
|
const nftMetadataResults = await Promise.all(nftsWithChecksumAdr.map(async (nft) => {
|
268
|
-
|
269
|
-
const networkClientId = this.messagingSystem.call('NetworkController:getNetworkClientIdByChainId', toHex(nft.chainId));
|
270
|
-
const resMetadata = networkClientId
|
271
|
-
? await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, nft.address, nft.tokenId, networkClientId)
|
272
|
-
: undefined;
|
279
|
+
const resMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, nft.address, nft.tokenId, networkClientId);
|
273
280
|
return {
|
274
281
|
nft,
|
275
282
|
newMetadata: resMetadata,
|
@@ -278,27 +285,19 @@ export class NftController extends BaseController {
|
|
278
285
|
// We want to avoid updating the state if the state and fetched nft info are the same
|
279
286
|
const nftsWithDifferentMetadata = [];
|
280
287
|
const { allNfts } = this.state;
|
281
|
-
|
282
|
-
const stateNfts = nftsWithChecksumAdr.map((nft) => {
|
283
|
-
return allNfts[addressToSearch]?.[toHex(nft.chainId)]?.find((nftElement) => nftElement.address.toLowerCase() === nft.address.toLowerCase() &&
|
284
|
-
nftElement.tokenId === nft.tokenId);
|
285
|
-
});
|
288
|
+
const stateNfts = allNfts[addressToSearch]?.[chainId] || [];
|
286
289
|
nftMetadataResults.forEach((singleNft) => {
|
287
|
-
const existingEntry = stateNfts.find((nft) => nft
|
288
|
-
singleNft.nft.
|
289
|
-
|
290
|
-
if (existingEntry && singleNft.newMetadata) {
|
290
|
+
const existingEntry = stateNfts.find((nft) => nft.address.toLowerCase() === singleNft.nft.address.toLowerCase() &&
|
291
|
+
nft.tokenId === singleNft.nft.tokenId);
|
292
|
+
if (existingEntry) {
|
291
293
|
const differentMetadata = compareNftMetadata(singleNft.newMetadata, existingEntry);
|
292
294
|
if (differentMetadata) {
|
293
|
-
nftsWithDifferentMetadata.push(
|
294
|
-
nft: singleNft.nft,
|
295
|
-
newMetadata: singleNft.newMetadata,
|
296
|
-
});
|
295
|
+
nftsWithDifferentMetadata.push(singleNft);
|
297
296
|
}
|
298
297
|
}
|
299
298
|
});
|
300
299
|
if (nftsWithDifferentMetadata.length !== 0) {
|
301
|
-
nftsWithDifferentMetadata.forEach((elm) => this.updateNft(elm.nft, elm.newMetadata, addressToSearch,
|
300
|
+
nftsWithDifferentMetadata.forEach((elm) => this.updateNft(elm.nft, elm.newMetadata, addressToSearch, chainId));
|
302
301
|
}
|
303
302
|
}
|
304
303
|
finally {
|
@@ -310,13 +309,13 @@ export class NftController extends BaseController {
|
|
310
309
|
*
|
311
310
|
* @param address - Hex address of the NFT contract.
|
312
311
|
* @param tokenId - Token identifier of the NFT.
|
313
|
-
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
314
312
|
* @param options - an object of arguments
|
313
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
315
314
|
* @param options.userAddress - The address of the account where the NFT is being removed.
|
316
315
|
*/
|
317
|
-
removeNft(address, tokenId, networkClientId,
|
316
|
+
removeNft(address, tokenId, { networkClientId, userAddress, } = {}) {
|
318
317
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
319
|
-
const
|
318
|
+
const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
320
319
|
const checksumHexAddress = toChecksumHexAddress(address);
|
321
320
|
__classPrivateFieldGet(this, _NftController_instances, "m", _NftController_removeIndividualNft).call(this, checksumHexAddress, tokenId, {
|
322
321
|
chainId,
|
@@ -337,13 +336,13 @@ export class NftController extends BaseController {
|
|
337
336
|
*
|
338
337
|
* @param address - Hex address of the NFT contract.
|
339
338
|
* @param tokenId - Token identifier of the NFT.
|
340
|
-
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
341
339
|
* @param options - an object of arguments
|
340
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
342
341
|
* @param options.userAddress - The address of the account where the NFT is being removed.
|
343
342
|
*/
|
344
|
-
removeAndIgnoreNft(address, tokenId, networkClientId,
|
343
|
+
removeAndIgnoreNft(address, tokenId, { networkClientId, userAddress, } = {}) {
|
345
344
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
346
|
-
const
|
345
|
+
const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
347
346
|
const checksumHexAddress = toChecksumHexAddress(address);
|
348
347
|
__classPrivateFieldGet(this, _NftController_instances, "m", _NftController_removeAndIgnoreIndividualNft).call(this, checksumHexAddress, tokenId, {
|
349
348
|
chainId,
|
@@ -373,18 +372,20 @@ export class NftController extends BaseController {
|
|
373
372
|
*
|
374
373
|
* @param nft - The NFT object to check and update.
|
375
374
|
* @param batch - A boolean indicating whether this method is being called as part of a batch or single update.
|
376
|
-
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
377
375
|
* @param accountParams - The userAddress and chainId to check ownership against
|
378
376
|
* @param accountParams.userAddress - the address passed through the confirmed transaction flow to ensure assets are stored to the correct account
|
377
|
+
* @param accountParams.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
379
378
|
* @returns the NFT with the updated isCurrentlyOwned value
|
380
379
|
*/
|
381
|
-
async checkAndUpdateSingleNftOwnershipStatus(nft, batch,
|
380
|
+
async checkAndUpdateSingleNftOwnershipStatus(nft, batch, { userAddress, networkClientId, } = {}) {
|
382
381
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
383
|
-
const
|
382
|
+
const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
384
383
|
const { address, tokenId } = nft;
|
385
384
|
let isOwned = nft.isCurrentlyOwned;
|
386
385
|
try {
|
387
|
-
isOwned = await this.isNftOwner(addressToSearch, address, tokenId,
|
386
|
+
isOwned = await this.isNftOwner(addressToSearch, address, tokenId, {
|
387
|
+
networkClientId,
|
388
|
+
});
|
388
389
|
}
|
389
390
|
catch {
|
390
391
|
// ignore error
|
@@ -420,18 +421,18 @@ export class NftController extends BaseController {
|
|
420
421
|
/**
|
421
422
|
* Checks whether NFTs associated with current selectedAddress/chainId combination are still owned by the user
|
422
423
|
* And updates the isCurrentlyOwned value on each accordingly.
|
423
|
-
*
|
424
|
-
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
425
424
|
* @param options - an object of arguments
|
425
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
426
426
|
* @param options.userAddress - The address of the account where the NFT ownership status is checked/updated.
|
427
427
|
*/
|
428
|
-
async checkAndUpdateAllNftsOwnershipStatus(networkClientId,
|
428
|
+
async checkAndUpdateAllNftsOwnershipStatus({ networkClientId, userAddress, } = {}) {
|
429
429
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
430
|
-
const
|
430
|
+
const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
431
431
|
const { allNfts } = this.state;
|
432
432
|
const nfts = allNfts[addressToSearch]?.[chainId] || [];
|
433
433
|
const updatedNfts = await Promise.all(nfts.map(async (nft) => {
|
434
|
-
return ((await this.checkAndUpdateSingleNftOwnershipStatus(nft, true,
|
434
|
+
return ((await this.checkAndUpdateSingleNftOwnershipStatus(nft, true, {
|
435
|
+
networkClientId,
|
435
436
|
userAddress,
|
436
437
|
})) ?? nft);
|
437
438
|
}));
|
@@ -446,13 +447,13 @@ export class NftController extends BaseController {
|
|
446
447
|
* @param address - Hex address of the NFT contract.
|
447
448
|
* @param tokenId - Hex address of the NFT contract.
|
448
449
|
* @param favorite - NFT new favorite status.
|
449
|
-
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
450
450
|
* @param options - an object of arguments
|
451
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
451
452
|
* @param options.userAddress - The address of the account where the NFT is being removed.
|
452
453
|
*/
|
453
|
-
updateNftFavoriteStatus(address, tokenId, favorite, networkClientId,
|
454
|
+
updateNftFavoriteStatus(address, tokenId, favorite, { networkClientId, userAddress, } = {}) {
|
454
455
|
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
455
|
-
const
|
456
|
+
const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
456
457
|
const { allNfts } = this.state;
|
457
458
|
const nfts = [...(allNfts[addressToSearch]?.[chainId] || [])];
|
458
459
|
const index = nfts.findIndex((nft) => nft.address === address && nft.tokenId === tokenId);
|
@@ -595,10 +596,12 @@ export class NftController extends BaseController {
|
|
595
596
|
});
|
596
597
|
}
|
597
598
|
}
|
598
|
-
_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(),
|
599
|
+
_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, }) {
|
600
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
|
601
|
+
__classPrivateFieldSet(this, _NftController_chainId, chainId, "f");
|
602
|
+
}, _NftController_onPreferencesControllerStateChange =
|
599
603
|
/**
|
600
604
|
* Handles the state change of the preference controller.
|
601
|
-
*
|
602
605
|
* @param preferencesState - The new state of the preference controller.
|
603
606
|
* @param preferencesState.ipfsGateway - The configured IPFS gateway.
|
604
607
|
* @param preferencesState.openSeaEnabled - Controls whether the OpenSea API is used.
|
@@ -622,7 +625,6 @@ async function _NftController_onPreferencesControllerStateChange({ ipfsGateway,
|
|
622
625
|
}, _NftController_onSelectedAccountChange =
|
623
626
|
/**
|
624
627
|
* Handles the selected account change on the accounts controller.
|
625
|
-
*
|
626
628
|
* @param internalAccount - The new selected account.
|
627
629
|
*/
|
628
630
|
async function _NftController_onSelectedAccountChange(internalAccount) {
|
@@ -845,7 +847,9 @@ async function _NftController_getNftURIAndStandard(contractAddress, tokenId, net
|
|
845
847
|
* @returns Promise resolving to the current NFT name and image.
|
846
848
|
*/
|
847
849
|
async function _NftController_getNftInformation(contractAddress, tokenId, networkClientId) {
|
848
|
-
const
|
850
|
+
const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, {
|
851
|
+
networkClientId,
|
852
|
+
});
|
849
853
|
const [blockchainMetadata, nftApiMetadata] = await Promise.all([
|
850
854
|
safelyExecute(() => __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformationFromTokenURI).call(this, contractAddress, tokenId, networkClientId)),
|
851
855
|
__classPrivateFieldGet(this, _NftController_openSeaEnabled, "f") && chainId === '0x1'
|
@@ -868,9 +872,7 @@ async function _NftController_getNftInformation(contractAddress, tokenId, networ
|
|
868
872
|
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
869
873
|
* @returns Promise resolving to the current NFT name and image.
|
870
874
|
*/
|
871
|
-
async function _NftController_getNftContractInformationFromContract(
|
872
|
-
// TODO for calls to blockchain we need to explicitly pass the currentNetworkClientId since its relying on the provider
|
873
|
-
contractAddress, networkClientId) {
|
875
|
+
async function _NftController_getNftContractInformationFromContract(contractAddress, networkClientId) {
|
874
876
|
const [name, symbol] = await Promise.all([
|
875
877
|
this.messagingSystem.call('AssetsContractController:getERC721AssetName', contractAddress, networkClientId),
|
876
878
|
this.messagingSystem.call('AssetsContractController:getERC721AssetSymbol', contractAddress, networkClientId),
|
@@ -1005,20 +1007,22 @@ async function _NftController_addIndividualNft(tokenAddress, tokenId, nftMetadat
|
|
1005
1007
|
/**
|
1006
1008
|
* Adds an NFT contract to the stored NFT contracts list.
|
1007
1009
|
*
|
1008
|
-
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
1009
1010
|
* @param options - options.
|
1010
1011
|
* @param options.tokenAddress - Hex address of the NFT contract.
|
1011
1012
|
* @param options.userAddress - The address of the account where the NFT is being added.
|
1012
1013
|
* @param options.nftMetadata - The retrieved NFTMetadata from API.
|
1014
|
+
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
|
1013
1015
|
* @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
|
1016
|
+
* @param options.chainIdHex - The chainId to add the NFT contract to.
|
1014
1017
|
* @returns Promise resolving to the current NFT contracts list.
|
1015
1018
|
*/
|
1016
|
-
async function _NftController_addNftContract(
|
1019
|
+
async function _NftController_addNftContract({ tokenAddress, userAddress, networkClientId, source, nftMetadata, chainIdHex, }) {
|
1017
1020
|
const releaseLock = await __classPrivateFieldGet(this, _NftController_mutex, "f").acquire();
|
1018
1021
|
try {
|
1019
1022
|
const checksumHexAddress = toChecksumHexAddress(tokenAddress);
|
1020
1023
|
const { allNftContracts } = this.state;
|
1021
|
-
|
1024
|
+
// TODO: revisit this with Solana support and instead of passing chainId, make sure chainId is read from nftMetadata when nftMetadata is available
|
1025
|
+
const chainId = chainIdHex || __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
|
1022
1026
|
const nftContracts = allNftContracts[userAddress]?.[chainId] || [];
|
1023
1027
|
const existingEntry = nftContracts.find((nftContract) => nftContract.address.toLowerCase() ===
|
1024
1028
|
checksumHexAddress.toLowerCase());
|
@@ -1112,7 +1116,7 @@ async function _NftController_addNftContract(networkClientId, { tokenAddress, us
|
|
1112
1116
|
userAddress,
|
1113
1117
|
});
|
1114
1118
|
return newNftContracts;
|
1115
|
-
}, _NftController_validateWatchNft = async function _NftController_validateWatchNft(asset, type, userAddress, networkClientId) {
|
1119
|
+
}, _NftController_validateWatchNft = async function _NftController_validateWatchNft(asset, type, userAddress, { networkClientId } = {}) {
|
1116
1120
|
const { address: contractAddress, tokenId } = asset;
|
1117
1121
|
// Validate parameters
|
1118
1122
|
if (!type) {
|
@@ -1135,7 +1139,7 @@ async function _NftController_addNftContract(networkClientId, { tokenAddress, us
|
|
1135
1139
|
}
|
1136
1140
|
// Check if the user owns the suggested NFT
|
1137
1141
|
try {
|
1138
|
-
const isOwner = await this.isNftOwner(userAddress, contractAddress, tokenId, networkClientId);
|
1142
|
+
const isOwner = await this.isNftOwner(userAddress, contractAddress, tokenId, { networkClientId });
|
1139
1143
|
if (!isOwner) {
|
1140
1144
|
throw rpcErrors.invalidInput('Suggested NFT is not owned by the selected account');
|
1141
1145
|
}
|
@@ -1147,6 +1151,12 @@ async function _NftController_addNftContract(networkClientId, { tokenAddress, us
|
|
1147
1151
|
}
|
1148
1152
|
throw error;
|
1149
1153
|
}
|
1154
|
+
}, _NftController_getCorrectChainId = function _NftController_getCorrectChainId({ networkClientId, }) {
|
1155
|
+
if (networkClientId) {
|
1156
|
+
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
1157
|
+
return chainId;
|
1158
|
+
}
|
1159
|
+
return __classPrivateFieldGet(this, _NftController_chainId, "f");
|
1150
1160
|
}, _NftController_getAddressOrSelectedAddress = function _NftController_getAddressOrSelectedAddress(address) {
|
1151
1161
|
if (address) {
|
1152
1162
|
return address;
|
@@ -1154,21 +1164,12 @@ async function _NftController_addNftContract(networkClientId, { tokenAddress, us
|
|
1154
1164
|
// If the address is not defined (or empty), we fallback to the currently selected account's address
|
1155
1165
|
const selectedAccount = this.messagingSystem.call('AccountsController:getAccount', __classPrivateFieldGet(this, _NftController_selectedAccountId, "f"));
|
1156
1166
|
return selectedAccount?.address || '';
|
1157
|
-
}, _NftController_updateNftUpdateForAccount =
|
1158
|
-
|
1159
|
-
* Updates the all nfts in state for the account.
|
1160
|
-
* Nfts will be updated if they don't have a name, description or image.
|
1161
|
-
*
|
1162
|
-
* @param account - The account to update the NFT metadata for.
|
1163
|
-
*/
|
1164
|
-
async function _NftController_updateNftUpdateForAccount(account) {
|
1165
|
-
// get all nfts for the account for all chains
|
1166
|
-
const nfts = Object.values(this.state.allNfts[account.address] || {}).flat();
|
1167
|
+
}, _NftController_updateNftUpdateForAccount = async function _NftController_updateNftUpdateForAccount(account) {
|
1168
|
+
const nfts = this.state.allNfts[account.address]?.[__classPrivateFieldGet(this, _NftController_chainId, "f")] ?? [];
|
1167
1169
|
// Filter only nfts
|
1168
1170
|
const nftsToUpdate = nfts.filter((singleNft) => !singleNft.name && !singleNft.description && !singleNft.image);
|
1169
1171
|
if (nftsToUpdate.length !== 0 &&
|
1170
1172
|
nftsToUpdate.length < NFT_UPDATE_THRESHOLD) {
|
1171
|
-
// TODO: get the chainId for the NFT
|
1172
1173
|
await this.updateNftMetadata({
|
1173
1174
|
nfts: nftsToUpdate,
|
1174
1175
|
userAddress: account.address,
|