@metamask/assets-controllers
Advanced tools
Comparing version 18.0.0 to 19.0.0
@@ -9,2 +9,20 @@ # Changelog | ||
## [19.0.0] | ||
### Changed | ||
- **BREAKING:** Bump dependency and peer dependency on `@metamask/network-controller` to ^16.0.0 | ||
- Add optional `networkClientId` and `userAddress` args to remaining `NftController` public methods ([#2006](https://github.com/MetaMask/core/pull/2006)) | ||
- `watchNft`, `removeNft`, `removeAndIgnoreNft`, `removeNftContract`, `updateNftFavoriteStatus`, and `checkAndUpdateAllNftsOwnershipStatus` methods on `NftController` all now accept an optional options object argument containing `networkClientId` and `userAddress` to identify where in state to mutate. | ||
- **BREAKING**: `addNft` no longer accepts a `chainId` property in its options argument since this value can be retrieved by the `networkClientId` property and is therefore redundant. | ||
- **BREAKING**: The third and fourth arguments on NftController's `addNftVerifyOwnership` method, have been replaced with an options object containing optional properties `networkClientId`, `userAddress` and `source`. This method signature is more aligned with the options pattern for passing `networkClientId` and `userAddress` on this controller and elsewhere. | ||
- **BREAKING**: `checkAndUpdateSingleNftOwnershipStatus` on NftController no longer accepts a `chainId` in its options argument. This is replaced with an optional `networkClientId` property which can be used to fetch chainId. | ||
***BREAKING**: The fourth argument of the `isNftOwner` method on `NftController` is now an options object with an optional `networkClientId` property. This method signature is more aligned with the options pattern for passing `networkClientId` on this controller and elsewhere. | ||
- **BREAKING**: `validateWatchNft` method on `NftController` is now private. | ||
- **BREAKING**: `detectNfts` on `NftDetectionController` now accepts a single object argument with optional properties `networkClientId` and `userAddress`, rather than taking these as two sequential arguments. | ||
- Bump dependency `@metamask/eth-query` from ^3.0.1 to ^4.0.0 ([#2028](https://github.com/MetaMask/core/pull/2028)) | ||
- Bump dependency on `@metamask/polling-controller` to ^1.0.2 | ||
- Bump `@metamask/utils` from 8.1.0 to 8.2.0 ([#1957](https://github.com/MetaMask/core/pull/1957)) | ||
### Fixed | ||
- Add name and symbol to the payload returned by the `ERC1155Standard` class `getDetails` method for `ERC1155` contracts ([#1727](https://github.com/MetaMask/core/pull/1727)) | ||
## [18.0.0] | ||
@@ -369,3 +387,4 @@ ### Changed | ||
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@18.0.0...HEAD | ||
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@19.0.0...HEAD | ||
[19.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@18.0.0...@metamask/assets-controllers@19.0.0 | ||
[18.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@17.0.0...@metamask/assets-controllers@18.0.0 | ||
@@ -372,0 +391,0 @@ [17.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@16.0.0...@metamask/assets-controllers@17.0.0 |
@@ -259,3 +259,2 @@ /// <reference types="node" /> | ||
* @param options.tokenAddress - Hex address of the NFT contract. | ||
* @param options.chainId - The chainId of the network where the NFT is being added. | ||
* @param options.userAddress - The address of the account where the NFT is being added. | ||
@@ -272,2 +271,5 @@ * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param tokenId - Token identifier of the NFT. | ||
* @param options - options. | ||
* @param options.chainId - The chainId of the network where the NFT is being removed. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
@@ -280,2 +282,5 @@ private removeAndIgnoreIndividualNft; | ||
* @param tokenId - Token identifier of the NFT. | ||
* @param options - options. | ||
* @param options.chainId - The chainId of the network where the NFT is being removed. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
@@ -287,2 +292,5 @@ private removeIndividualNft; | ||
* @param address - Hex address of the NFT contract. | ||
* @param options - options. | ||
* @param options.chainId - The chainId of the network where the NFT is being removed. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
* @returns Promise resolving to the current NFT contracts list. | ||
@@ -351,3 +359,3 @@ */ | ||
}, config?: Partial<BaseConfig>, state?: Partial<NftState>); | ||
validateWatchNft(asset: NftAsset, type: NFTStandardType, userAddress: string): Promise<void>; | ||
private validateWatchNft; | ||
private getCorrectChainId; | ||
@@ -363,6 +371,11 @@ /** | ||
* @param origin - Domain origin to register the asset from. | ||
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options - Options bag. | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT is being added. | ||
* @returns Object containing a Promise resolving to the suggestedAsset address if accepted. | ||
*/ | ||
watchNft(asset: NftAsset, type: NFTStandardType, origin: string, networkClientId?: NetworkClientId): Promise<void>; | ||
watchNft(asset: NftAsset, type: NFTStandardType, origin: string, { networkClientId, userAddress, }?: { | ||
networkClientId?: NetworkClientId; | ||
userAddress?: string; | ||
}): Promise<void>; | ||
/** | ||
@@ -380,6 +393,9 @@ * Sets an OpenSea API key to retrieve NFT information. | ||
* @param tokenId - NFT token ID. | ||
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options - Options bag. | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @returns Promise resolving the NFT ownership. | ||
*/ | ||
isNftOwner(ownerAddress: string, nftAddress: string, tokenId: string, networkClientId?: NetworkClientId): Promise<boolean>; | ||
isNftOwner(ownerAddress: string, nftAddress: string, tokenId: string, { networkClientId, }?: { | ||
networkClientId?: NetworkClientId; | ||
}): Promise<boolean>; | ||
/** | ||
@@ -391,6 +407,12 @@ * Verifies currently selected address owns entered NFT address/tokenId combo and | ||
* @param tokenId - The NFT identifier. | ||
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param source - Whether the NFT was detected, added manually or suggested by a dapp. | ||
* @param options - an object of arguments | ||
* @param options.userAddress - The address of the current user. | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.source - Whether the NFT was detected, added manually or suggested by a dapp. | ||
*/ | ||
addNftVerifyOwnership(address: string, tokenId: string, networkClientId?: NetworkClientId, source?: Source): Promise<void>; | ||
addNftVerifyOwnership(address: string, tokenId: string, { userAddress, networkClientId, source, }?: { | ||
userAddress?: string; | ||
networkClientId?: NetworkClientId; | ||
source?: Source; | ||
}): Promise<void>; | ||
/** | ||
@@ -403,3 +425,2 @@ * Adds an NFT and respective NFT contract to the stored NFT and NFT contracts lists. | ||
* @param options.nftMetadata - NFT optional metadata. | ||
* @param options.chainId - The chain ID of the current network. | ||
* @param options.userAddress - The address of the current user. | ||
@@ -410,6 +431,4 @@ * @param options.source - Whether the NFT was detected, added manually or suggested by a dapp. | ||
*/ | ||
addNft(tokenAddress: string, tokenId: string, { nftMetadata, chainId, // TODO remove and replace chainId arg with fetch chainId using getNetworkClientById(networkClientId).configuration.chainId once polling refactor is complete | ||
userAddress, source, networkClientId, }?: { | ||
addNft(tokenAddress: string, tokenId: string, { nftMetadata, userAddress, source, networkClientId, }?: { | ||
nftMetadata?: NftMetadata; | ||
chainId?: Hex; | ||
userAddress?: string; | ||
@@ -424,4 +443,10 @@ source?: Source; | ||
* @param tokenId - Token identifier of the NFT. | ||
* @param options - an object of arguments | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
removeNft(address: string, tokenId: string): void; | ||
removeNft(address: string, tokenId: string, { networkClientId, userAddress, }?: { | ||
networkClientId?: NetworkClientId; | ||
userAddress?: string; | ||
}): void; | ||
/** | ||
@@ -432,4 +457,10 @@ * Removes an NFT from the stored token list and saves it in ignored NFTs list. | ||
* @param tokenId - Token identifier of the NFT. | ||
* @param options - an object of arguments | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
removeAndIgnoreNft(address: string, tokenId: string): void; | ||
removeAndIgnoreNft(address: string, tokenId: string, { networkClientId, userAddress, }?: { | ||
networkClientId?: NetworkClientId; | ||
userAddress?: string; | ||
}): void; | ||
/** | ||
@@ -447,8 +478,8 @@ * Removes all NFTs from the ignored list. | ||
* @param accountParams.userAddress - the address passed through the confirmed transaction flow to ensure assets are stored to the correct account | ||
* @param accountParams.chainId - the chainId passed through the confirmed transaction flow to ensure assets are stored to the correct account | ||
* @param accountParams.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @returns the NFT with the updated isCurrentlyOwned value | ||
*/ | ||
checkAndUpdateSingleNftOwnershipStatus(nft: Nft, batch: boolean, { userAddress, chainId }?: { | ||
userAddress: string; | ||
chainId: `0x${string}`; | ||
checkAndUpdateSingleNftOwnershipStatus(nft: Nft, batch: boolean, { userAddress, networkClientId, }?: { | ||
networkClientId?: NetworkClientId; | ||
userAddress?: string; | ||
}): Promise<Nft>; | ||
@@ -458,4 +489,10 @@ /** | ||
* And updates the isCurrentlyOwned value on each accordingly. | ||
* @param options - an object of arguments | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT ownership status is checked/updated. | ||
*/ | ||
checkAndUpdateAllNftsOwnershipStatus(): Promise<void>; | ||
checkAndUpdateAllNftsOwnershipStatus({ networkClientId, userAddress, }?: { | ||
networkClientId?: NetworkClientId; | ||
userAddress?: string; | ||
}): Promise<void>; | ||
/** | ||
@@ -467,4 +504,10 @@ * Update NFT favorite status. | ||
* @param favorite - NFT new favorite status. | ||
* @param options - an object of arguments | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
updateNftFavoriteStatus(address: string, tokenId: string, favorite: boolean): void; | ||
updateNftFavoriteStatus(address: string, tokenId: string, favorite: boolean, { networkClientId, userAddress, }?: { | ||
networkClientId?: NetworkClientId; | ||
userAddress?: string; | ||
}): void; | ||
/** | ||
@@ -471,0 +514,0 @@ * Returns an NFT by the address and token id. |
@@ -115,6 +115,3 @@ "use strict"; | ||
*/ | ||
updateNestedNftState(newCollection, baseStateKey, { userAddress, chainId } = { | ||
userAddress: this.config.selectedAddress, | ||
chainId: this.config.chainId, | ||
}) { | ||
updateNestedNftState(newCollection, baseStateKey, { userAddress, chainId }) { | ||
const { [baseStateKey]: oldState } = this.state; | ||
@@ -281,7 +278,5 @@ const addressState = oldState[userAddress]; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let { chainId } = this.config; | ||
if (networkClientId) { | ||
chainId = | ||
this.getNetworkClientById(networkClientId).configuration.chainId; | ||
} | ||
const chainId = this.getCorrectChainId({ | ||
networkClientId, | ||
}); | ||
const [blockchainMetadata, openSeaMetadata] = yield Promise.all([ | ||
@@ -361,5 +356,3 @@ (0, controller_utils_1.safelyExecute)(() => this.getNftInformationFromTokenURI(contractAddress, tokenId, networkClientId)), | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { chainId } = this.config; | ||
const getCurrentChainId = this.getCorrectChainId({ | ||
chainId, | ||
const chainId = this.getCorrectChainId({ | ||
networkClientId, | ||
@@ -369,3 +362,3 @@ }); | ||
(0, controller_utils_1.safelyExecute)(() => this.getNftContractInformationFromContract(contractAddress, networkClientId)), | ||
this.config.openSeaEnabled && getCurrentChainId === '0x1' | ||
this.config.openSeaEnabled && chainId === '0x1' | ||
? (0, controller_utils_1.safelyExecute)(() => this.getNftContractInformationFromApi(contractAddress)) | ||
@@ -456,3 +449,2 @@ : undefined, | ||
* @param options.tokenAddress - Hex address of the NFT contract. | ||
* @param options.chainId - The chainId of the network where the NFT is being added. | ||
* @param options.userAddress - The address of the account where the NFT is being added. | ||
@@ -463,3 +455,3 @@ * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
*/ | ||
addNftContract({ tokenAddress, chainId, userAddress, networkClientId, source, }) { | ||
addNftContract({ tokenAddress, userAddress, networkClientId, source, }) { | ||
var _a; | ||
@@ -471,8 +463,6 @@ return __awaiter(this, void 0, void 0, function* () { | ||
const { allNftContracts } = this.state; | ||
const currentChainId = this.getCorrectChainId({ | ||
chainId, | ||
const chainId = this.getCorrectChainId({ | ||
networkClientId, | ||
}); | ||
const selectedAddress = userAddress !== null && userAddress !== void 0 ? userAddress : this.config.selectedAddress; | ||
const nftContracts = ((_a = allNftContracts[selectedAddress]) === null || _a === void 0 ? void 0 : _a[currentChainId]) || []; | ||
const nftContracts = ((_a = allNftContracts[userAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const existingEntry = nftContracts.find((nftContract) => nftContract.address.toLowerCase() === tokenAddress.toLowerCase()); | ||
@@ -505,4 +495,4 @@ if (existingEntry) { | ||
this.updateNestedNftState(newNftContracts, ALL_NFTS_CONTRACTS_STATE_KEY, { | ||
chainId: currentChainId, | ||
userAddress: selectedAddress, | ||
chainId, | ||
userAddress, | ||
}); | ||
@@ -521,10 +511,12 @@ return newNftContracts; | ||
* @param tokenId - Token identifier of the NFT. | ||
* @param options - options. | ||
* @param options.chainId - The chainId of the network where the NFT is being removed. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
removeAndIgnoreIndividualNft(address, tokenId) { | ||
removeAndIgnoreIndividualNft(address, tokenId, { chainId, userAddress, }) { | ||
var _a; | ||
address = (0, controller_utils_1.toChecksumHexAddress)(address); | ||
const { allNfts, ignoredNfts } = this.state; | ||
const { chainId, selectedAddress } = this.config; | ||
const newIgnoredNfts = [...ignoredNfts]; | ||
const nfts = ((_a = allNfts[selectedAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const nfts = ((_a = allNfts[userAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const newNfts = nfts.filter((nft) => { | ||
@@ -539,3 +531,6 @@ if (nft.address.toLowerCase() === address.toLowerCase() && | ||
}); | ||
this.updateNestedNftState(newNfts, ALL_NFTS_STATE_KEY); | ||
this.updateNestedNftState(newNfts, ALL_NFTS_STATE_KEY, { | ||
userAddress, | ||
chainId, | ||
}); | ||
this.update({ | ||
@@ -550,12 +545,17 @@ ignoredNfts: newIgnoredNfts, | ||
* @param tokenId - Token identifier of the NFT. | ||
* @param options - options. | ||
* @param options.chainId - The chainId of the network where the NFT is being removed. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
removeIndividualNft(address, tokenId) { | ||
removeIndividualNft(address, tokenId, { chainId, userAddress }) { | ||
var _a; | ||
address = (0, controller_utils_1.toChecksumHexAddress)(address); | ||
const { allNfts } = this.state; | ||
const { chainId, selectedAddress } = this.config; | ||
const nfts = ((_a = allNfts[selectedAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const nfts = ((_a = allNfts[userAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const newNfts = nfts.filter((nft) => !(nft.address.toLowerCase() === address.toLowerCase() && | ||
nft.tokenId === tokenId)); | ||
this.updateNestedNftState(newNfts, ALL_NFTS_STATE_KEY); | ||
this.updateNestedNftState(newNfts, ALL_NFTS_STATE_KEY, { | ||
userAddress, | ||
chainId, | ||
}); | ||
} | ||
@@ -566,15 +566,20 @@ /** | ||
* @param address - Hex address of the NFT contract. | ||
* @param options - options. | ||
* @param options.chainId - The chainId of the network where the NFT is being removed. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
* @returns Promise resolving to the current NFT contracts list. | ||
*/ | ||
removeNftContract(address) { | ||
removeNftContract(address, { chainId, userAddress }) { | ||
var _a; | ||
address = (0, controller_utils_1.toChecksumHexAddress)(address); | ||
const { allNftContracts } = this.state; | ||
const { chainId, selectedAddress } = this.config; | ||
const nftContracts = ((_a = allNftContracts[selectedAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const nftContracts = ((_a = allNftContracts[userAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const newNftContracts = nftContracts.filter((nftContract) => !(nftContract.address.toLowerCase() === address.toLowerCase())); | ||
this.updateNestedNftState(newNftContracts, ALL_NFTS_CONTRACTS_STATE_KEY); | ||
this.updateNestedNftState(newNftContracts, ALL_NFTS_CONTRACTS_STATE_KEY, { | ||
chainId, | ||
userAddress, | ||
}); | ||
return newNftContracts; | ||
} | ||
validateWatchNft(asset, type, userAddress) { | ||
validateWatchNft(asset, type, userAddress, { networkClientId } = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -600,3 +605,3 @@ const { address: contractAddress, tokenId } = asset; | ||
try { | ||
const isOwner = yield this.isNftOwner(userAddress, contractAddress, tokenId); | ||
const isOwner = yield this.isNftOwner(userAddress, contractAddress, tokenId, { networkClientId }); | ||
if (!isOwner) { | ||
@@ -614,9 +619,6 @@ throw rpc_errors_1.rpcErrors.invalidInput('Suggested NFT is not owned by the selected account'); | ||
// Just a helper method to prefer the networkClient chainId first then the chainId argument and then finally the config chainId | ||
getCorrectChainId({ chainId, networkClientId, }) { | ||
getCorrectChainId({ networkClientId, }) { | ||
if (networkClientId) { | ||
return this.getNetworkClientById(networkClientId).configuration.chainId; | ||
} | ||
else if (chainId) { | ||
return chainId; | ||
} | ||
return this.config.chainId; | ||
@@ -633,9 +635,12 @@ } | ||
* @param origin - Domain origin to register the asset from. | ||
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options - Options bag. | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT is being added. | ||
* @returns Object containing a Promise resolving to the suggestedAsset address if accepted. | ||
*/ | ||
watchNft(asset, type, origin, networkClientId) { | ||
watchNft(asset, type, origin, { networkClientId, userAddress = this.config.selectedAddress, } = { | ||
userAddress: this.config.selectedAddress, | ||
}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { selectedAddress, chainId } = this.config; | ||
yield this.validateWatchNft(asset, type, selectedAddress); | ||
yield this.validateWatchNft(asset, type, userAddress); | ||
const nftMetadata = yield this.getNftInformation(asset.address, asset.tokenId, networkClientId); | ||
@@ -650,3 +655,3 @@ if (nftMetadata.standard && nftMetadata.standard !== type) { | ||
time: Date.now(), | ||
interactingAddress: selectedAddress, | ||
interactingAddress: userAddress, | ||
origin, | ||
@@ -664,4 +669,3 @@ }; | ||
}, | ||
chainId, | ||
userAddress: selectedAddress, | ||
userAddress, | ||
source: constants_1.Source.Dapp, | ||
@@ -686,6 +690,7 @@ networkClientId, | ||
* @param tokenId - NFT token ID. | ||
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options - Options bag. | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @returns Promise resolving the NFT ownership. | ||
*/ | ||
isNftOwner(ownerAddress, nftAddress, tokenId, networkClientId) { | ||
isNftOwner(ownerAddress, nftAddress, tokenId, { networkClientId, } = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -719,12 +724,21 @@ // Checks the ownership for ERC-721. | ||
* @param tokenId - The NFT identifier. | ||
* @param networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param source - Whether the NFT was detected, added manually or suggested by a dapp. | ||
* @param options - an object of arguments | ||
* @param options.userAddress - The address of the current user. | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.source - Whether the NFT was detected, added manually or suggested by a dapp. | ||
*/ | ||
addNftVerifyOwnership(address, tokenId, networkClientId, source) { | ||
addNftVerifyOwnership(address, tokenId, { userAddress = this.config.selectedAddress, networkClientId, source, } = { | ||
userAddress: this.config.selectedAddress, | ||
}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { selectedAddress } = this.config; | ||
if (!(yield this.isNftOwner(selectedAddress, address, tokenId, networkClientId))) { | ||
if (!(yield this.isNftOwner(userAddress, address, tokenId, { | ||
networkClientId, | ||
}))) { | ||
throw new Error('This NFT is not owned by the user'); | ||
} | ||
yield this.addNft(address, tokenId, { networkClientId, source }); | ||
yield this.addNft(address, tokenId, { | ||
networkClientId, | ||
userAddress, | ||
source, | ||
}); | ||
}); | ||
@@ -739,3 +753,2 @@ } | ||
* @param options.nftMetadata - NFT optional metadata. | ||
* @param options.chainId - The chain ID of the current network. | ||
* @param options.userAddress - The address of the current user. | ||
@@ -746,12 +759,9 @@ * @param options.source - Whether the NFT was detected, added manually or suggested by a dapp. | ||
*/ | ||
addNft(tokenAddress, tokenId, { nftMetadata, chainId, // TODO remove and replace chainId arg with fetch chainId using getNetworkClientById(networkClientId).configuration.chainId once polling refactor is complete | ||
userAddress, source = constants_1.Source.Custom, networkClientId, } = {}) { | ||
addNft(tokenAddress, tokenId, { nftMetadata, userAddress = this.config.selectedAddress, source = constants_1.Source.Custom, networkClientId, } = { userAddress: this.config.selectedAddress }) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
tokenAddress = (0, controller_utils_1.toChecksumHexAddress)(tokenAddress); | ||
const currentChainId = this.getCorrectChainId({ chainId, networkClientId }); | ||
const selectedAddress = userAddress !== null && userAddress !== void 0 ? userAddress : this.config.selectedAddress; | ||
const chainId = this.getCorrectChainId({ networkClientId }); | ||
const newNftContracts = yield this.addNftContract({ | ||
tokenAddress, | ||
chainId: currentChainId, | ||
userAddress: selectedAddress, | ||
userAddress, | ||
networkClientId, | ||
@@ -767,3 +777,3 @@ source, | ||
if (nftContract) { | ||
yield this.addIndividualNft(tokenAddress, tokenId, nftMetadata, nftContract, currentChainId, selectedAddress, source); | ||
yield this.addIndividualNft(tokenAddress, tokenId, nftMetadata, nftContract, chainId, userAddress, source); | ||
} | ||
@@ -777,13 +787,18 @@ }); | ||
* @param tokenId - Token identifier of the NFT. | ||
* @param options - an object of arguments | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
removeNft(address, tokenId) { | ||
removeNft(address, tokenId, { networkClientId, userAddress = this.config.selectedAddress, } = { | ||
userAddress: this.config.selectedAddress, | ||
}) { | ||
var _a; | ||
const chainId = this.getCorrectChainId({ networkClientId }); | ||
address = (0, controller_utils_1.toChecksumHexAddress)(address); | ||
this.removeIndividualNft(address, tokenId); | ||
this.removeIndividualNft(address, tokenId, { chainId, userAddress }); | ||
const { allNfts } = this.state; | ||
const { chainId, selectedAddress } = this.config; | ||
const nfts = ((_a = allNfts[selectedAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const nfts = ((_a = allNfts[userAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const remainingNft = nfts.find((nft) => nft.address.toLowerCase() === address.toLowerCase()); | ||
if (!remainingNft) { | ||
this.removeNftContract(address); | ||
this.removeNftContract(address, { chainId, userAddress }); | ||
} | ||
@@ -796,13 +811,21 @@ } | ||
* @param tokenId - Token identifier of the NFT. | ||
* @param options - an object of arguments | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
removeAndIgnoreNft(address, tokenId) { | ||
removeAndIgnoreNft(address, tokenId, { networkClientId, userAddress = this.config.selectedAddress, } = { | ||
userAddress: this.config.selectedAddress, | ||
}) { | ||
var _a; | ||
const chainId = this.getCorrectChainId({ networkClientId }); | ||
address = (0, controller_utils_1.toChecksumHexAddress)(address); | ||
this.removeAndIgnoreIndividualNft(address, tokenId); | ||
this.removeAndIgnoreIndividualNft(address, tokenId, { | ||
chainId, | ||
userAddress, | ||
}); | ||
const { allNfts } = this.state; | ||
const { chainId, selectedAddress } = this.config; | ||
const nfts = ((_a = allNfts[selectedAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const nfts = ((_a = allNfts[userAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const remainingNft = nfts.find((nft) => nft.address.toLowerCase() === address.toLowerCase()); | ||
if (!remainingNft) { | ||
this.removeNftContract(address); | ||
this.removeNftContract(address, { chainId, userAddress }); | ||
} | ||
@@ -824,21 +847,22 @@ } | ||
* @param accountParams.userAddress - the address passed through the confirmed transaction flow to ensure assets are stored to the correct account | ||
* @param accountParams.chainId - the chainId passed through the confirmed transaction flow to ensure assets are stored to the correct account | ||
* @param accountParams.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @returns the NFT with the updated isCurrentlyOwned value | ||
*/ | ||
checkAndUpdateSingleNftOwnershipStatus(nft, batch, { userAddress, chainId } = { | ||
checkAndUpdateSingleNftOwnershipStatus(nft, batch, { userAddress = this.config.selectedAddress, networkClientId, } = { | ||
userAddress: this.config.selectedAddress, | ||
chainId: this.config.chainId, | ||
}) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const chainId = this.getCorrectChainId({ networkClientId }); | ||
const { address, tokenId } = nft; | ||
let isOwned = nft.isCurrentlyOwned; | ||
try { | ||
isOwned = yield this.isNftOwner(userAddress, address, tokenId); | ||
isOwned = yield this.isNftOwner(userAddress, address, tokenId, { | ||
networkClientId, | ||
}); | ||
} | ||
catch (error) { | ||
if (!(error instanceof Error && | ||
error.message.includes('Unable to verify ownership'))) { | ||
throw error; | ||
} | ||
catch (_b) { | ||
// ignore error | ||
// this will only throw an error 'Unable to verify ownership' in which case | ||
// we want to keep the current value of isCurrentlyOwned for this flow. | ||
} | ||
@@ -867,14 +891,25 @@ nft.isCurrentlyOwned = isOwned; | ||
* And updates the isCurrentlyOwned value on each accordingly. | ||
* @param options - an object of arguments | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT ownership status is checked/updated. | ||
*/ | ||
checkAndUpdateAllNftsOwnershipStatus() { | ||
checkAndUpdateAllNftsOwnershipStatus({ networkClientId, userAddress = this.config.selectedAddress, } = { | ||
userAddress: this.config.selectedAddress, | ||
}) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const chainId = this.getCorrectChainId({ networkClientId }); | ||
const { allNfts } = this.state; | ||
const { chainId, selectedAddress } = this.config; | ||
const nfts = ((_a = allNfts[selectedAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const nfts = ((_a = allNfts[userAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const updatedNfts = yield Promise.all(nfts.map((nft) => __awaiter(this, void 0, void 0, function* () { | ||
var _b; | ||
return ((_b = (yield this.checkAndUpdateSingleNftOwnershipStatus(nft, true))) !== null && _b !== void 0 ? _b : nft); | ||
return ((_b = (yield this.checkAndUpdateSingleNftOwnershipStatus(nft, true, { | ||
networkClientId, | ||
userAddress, | ||
}))) !== null && _b !== void 0 ? _b : nft); | ||
}))); | ||
this.updateNestedNftState(updatedNfts, ALL_NFTS_STATE_KEY); | ||
this.updateNestedNftState(updatedNfts, ALL_NFTS_STATE_KEY, { | ||
userAddress, | ||
chainId, | ||
}); | ||
}); | ||
@@ -888,8 +923,13 @@ } | ||
* @param favorite - NFT new favorite status. | ||
* @param options - an object of arguments | ||
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. | ||
* @param options.userAddress - The address of the account where the NFT is being removed. | ||
*/ | ||
updateNftFavoriteStatus(address, tokenId, favorite) { | ||
updateNftFavoriteStatus(address, tokenId, favorite, { networkClientId, userAddress = this.config.selectedAddress, } = { | ||
userAddress: this.config.selectedAddress, | ||
}) { | ||
var _a; | ||
const chainId = this.getCorrectChainId({ networkClientId }); | ||
const { allNfts } = this.state; | ||
const { chainId, selectedAddress } = this.config; | ||
const nfts = ((_a = allNfts[selectedAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const nfts = ((_a = allNfts[userAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; | ||
const index = nfts.findIndex((nft) => nft.address === address && nft.tokenId === tokenId); | ||
@@ -902,3 +942,6 @@ if (index === -1) { | ||
nfts[index] = updatedNft; | ||
this.updateNestedNftState(nfts, ALL_NFTS_STATE_KEY); | ||
this.updateNestedNftState(nfts, ALL_NFTS_STATE_KEY, { | ||
chainId, | ||
userAddress, | ||
}); | ||
} | ||
@@ -947,3 +990,6 @@ /** | ||
]; | ||
this.updateNestedNftState(newNfts, ALL_NFTS_STATE_KEY); | ||
this.updateNestedNftState(newNfts, ALL_NFTS_STATE_KEY, { | ||
chainId, | ||
userAddress: selectedAddress, | ||
}); | ||
} | ||
@@ -972,3 +1018,6 @@ /** | ||
]; | ||
this.updateNestedNftState(newNfts, ALL_NFTS_STATE_KEY); | ||
this.updateNestedNftState(newNfts, ALL_NFTS_STATE_KEY, { | ||
chainId, | ||
userAddress: selectedAddress, | ||
}); | ||
return true; | ||
@@ -975,0 +1024,0 @@ } |
@@ -181,3 +181,2 @@ import type { BaseConfig, BaseState } from '@metamask/base-controller'; | ||
isMainnetByNetworkClientId: (networkClient: NetworkClient) => boolean; | ||
private getCorrectChainId; | ||
/** | ||
@@ -187,8 +186,12 @@ * Triggers asset ERC721 token auto detection on mainnet. Any newly detected NFTs are | ||
* | ||
* @param networkClientId - The network client ID to detect NFTs on. | ||
* @param accountAddress - The address to detect NFTs for. | ||
* @param options - Options bag. | ||
* @param options.networkClientId - The network client ID to detect NFTs on. | ||
* @param options.userAddress - The address to detect NFTs for. | ||
*/ | ||
detectNfts(networkClientId?: NetworkClientId, accountAddress?: string): Promise<void>; | ||
detectNfts({ networkClientId, userAddress, }?: { | ||
networkClientId?: NetworkClientId; | ||
userAddress: string; | ||
}): Promise<void>; | ||
} | ||
export default NftDetectionController; | ||
//# sourceMappingURL=NftDetectionController.d.ts.map |
@@ -113,3 +113,3 @@ "use strict"; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this.detectNfts(networkClientId, options.address); | ||
yield this.detectNfts({ networkClientId, userAddress: options.address }); | ||
}); | ||
@@ -154,8 +154,2 @@ } | ||
} | ||
getCorrectChainId(networkClientId) { | ||
if (networkClientId) { | ||
return this.getNetworkClientById(networkClientId).configuration.chainId; | ||
} | ||
return this.config.chainId; | ||
} | ||
/** | ||
@@ -165,9 +159,8 @@ * Triggers asset ERC721 token auto detection on mainnet. Any newly detected NFTs are | ||
* | ||
* @param networkClientId - The network client ID to detect NFTs on. | ||
* @param accountAddress - The address to detect NFTs for. | ||
* @param options - Options bag. | ||
* @param options.networkClientId - The network client ID to detect NFTs on. | ||
* @param options.userAddress - The address to detect NFTs for. | ||
*/ | ||
detectNfts(networkClientId, accountAddress) { | ||
detectNfts({ networkClientId, userAddress, } = { userAddress: this.config.selectedAddress }) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const chainId = this.getCorrectChainId(networkClientId); | ||
const selectedAddress = accountAddress || this.config.selectedAddress; | ||
/* istanbul ignore if */ | ||
@@ -178,6 +171,6 @@ if (!this.isMainnet() || this.disabled) { | ||
/* istanbul ignore else */ | ||
if (!selectedAddress) { | ||
if (!userAddress) { | ||
return; | ||
} | ||
const apiNfts = yield this.getOwnerNfts(selectedAddress); | ||
const apiNfts = yield this.getOwnerNfts(userAddress); | ||
const addNftPromises = apiNfts.map((nft) => __awaiter(this, void 0, void 0, function* () { | ||
@@ -203,5 +196,5 @@ const { token_id, num_sales, background_color, image_url, image_preview_url, image_thumbnail_url, image_original_url, animation_url, animation_original_url, name, description, external_link, creator, asset_contract: { address, schema_name }, last_sale, } = nft; | ||
nftMetadata, | ||
userAddress: selectedAddress, | ||
chainId, | ||
userAddress, | ||
source: constants_1.Source.Detected, | ||
networkClientId, | ||
}); | ||
@@ -208,0 +201,0 @@ } |
@@ -58,2 +58,16 @@ import type { Web3Provider } from '@ethersproject/providers'; | ||
/** | ||
* Query for symbol for a given asset. | ||
* | ||
* @param address - ERC1155 asset contract address. | ||
* @returns Promise resolving to the 'symbol'. | ||
*/ | ||
getAssetSymbol: (address: string) => Promise<string>; | ||
/** | ||
* Query for name for a given asset. | ||
* | ||
* @param address - ERC1155 asset contract address. | ||
* @returns Promise resolving to the 'name'. | ||
*/ | ||
getAssetName: (address: string) => Promise<string>; | ||
/** | ||
* Query if a contract implements an interface. | ||
@@ -78,4 +92,6 @@ * | ||
image: string | undefined; | ||
name: string | undefined; | ||
symbol: string | undefined; | ||
}>; | ||
} | ||
//# sourceMappingURL=ERC1155Standard.d.ts.map |
@@ -96,2 +96,44 @@ "use strict"; | ||
/** | ||
* Query for symbol for a given asset. | ||
* | ||
* @param address - ERC1155 asset contract address. | ||
* @returns Promise resolving to the 'symbol'. | ||
*/ | ||
this.getAssetSymbol = (address) => __awaiter(this, void 0, void 0, function* () { | ||
const contract = new contracts_1.Contract(address, | ||
// Contract ABI fragment containing only the symbol method to fetch the symbol of the contract. | ||
[ | ||
{ | ||
inputs: [], | ||
name: 'symbol', | ||
outputs: [{ name: '_symbol', type: 'string' }], | ||
stateMutability: 'view', | ||
type: 'function', | ||
payable: false, | ||
}, | ||
], this.provider); | ||
return contract.symbol(); | ||
}); | ||
/** | ||
* Query for name for a given asset. | ||
* | ||
* @param address - ERC1155 asset contract address. | ||
* @returns Promise resolving to the 'name'. | ||
*/ | ||
this.getAssetName = (address) => __awaiter(this, void 0, void 0, function* () { | ||
const contract = new contracts_1.Contract(address, | ||
// Contract ABI fragment containing only the name method to fetch the name of the contract. | ||
[ | ||
{ | ||
inputs: [], | ||
name: 'name', | ||
outputs: [{ name: '_name', type: 'string' }], | ||
stateMutability: 'view', | ||
type: 'function', | ||
payable: false, | ||
}, | ||
], this.provider); | ||
return contract.name(); | ||
}); | ||
/** | ||
* Query if a contract implements an interface. | ||
@@ -120,8 +162,13 @@ * | ||
} | ||
let tokenURI, image; | ||
let image; | ||
const [symbol, name, tokenURI] = yield Promise.all([ | ||
(0, controller_utils_1.safelyExecute)(() => this.getAssetSymbol(address)), | ||
(0, controller_utils_1.safelyExecute)(() => this.getAssetName(address)), | ||
tokenId | ||
? (0, controller_utils_1.safelyExecute)(() => this.getTokenURI(address, tokenId).then((uri) => uri.startsWith('ipfs://') | ||
? (0, assetsUtil_1.getFormattedIpfsUrl)(ipfsGateway, uri, true) | ||
: uri)) | ||
: undefined, | ||
]); | ||
if (tokenId) { | ||
tokenURI = yield this.getTokenURI(address, tokenId); | ||
if (tokenURI.startsWith('ipfs://')) { | ||
tokenURI = (0, assetsUtil_1.getFormattedIpfsUrl)(ipfsGateway, tokenURI, true); | ||
} | ||
try { | ||
@@ -144,2 +191,4 @@ const response = yield (0, controller_utils_1.timeoutFetch)(tokenURI); | ||
image, | ||
symbol, | ||
name, | ||
}; | ||
@@ -146,0 +195,0 @@ }); |
@@ -48,2 +48,3 @@ "use strict"; | ||
this.initialize(); | ||
this.setIntervalLength(this.config.interval); | ||
this.getTokensState = getTokensState; | ||
@@ -50,0 +51,0 @@ this.getTokenListState = getTokenListState; |
{ | ||
"name": "@metamask/assets-controllers", | ||
"version": "18.0.0", | ||
"version": "19.0.0", | ||
"description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)", | ||
@@ -27,4 +27,5 @@ "keywords": [ | ||
"publish:preview": "yarn npm publish --tag preview", | ||
"test": "jest", | ||
"test": "jest --reporters=jest-silent-reporter", | ||
"test:clean": "jest --clearCache", | ||
"test:verbose": "jest --verbose", | ||
"test:watch": "jest --watch" | ||
@@ -42,9 +43,9 @@ }, | ||
"@metamask/controller-utils": "^5.0.2", | ||
"@metamask/eth-query": "^3.0.1", | ||
"@metamask/eth-query": "^4.0.0", | ||
"@metamask/metamask-eth-abis": "3.0.0", | ||
"@metamask/network-controller": "^15.1.0", | ||
"@metamask/polling-controller": "^1.0.1", | ||
"@metamask/network-controller": "^16.0.0", | ||
"@metamask/polling-controller": "^1.0.2", | ||
"@metamask/preferences-controller": "^4.4.3", | ||
"@metamask/rpc-errors": "^6.1.0", | ||
"@metamask/utils": "^8.1.0", | ||
"@metamask/utils": "^8.2.0", | ||
"@types/uuid": "^8.3.0", | ||
@@ -59,3 +60,3 @@ "async-mutex": "^0.2.6", | ||
"devDependencies": { | ||
"@metamask/auto-changelog": "^3.4.2", | ||
"@metamask/auto-changelog": "^3.4.3", | ||
"@types/jest": "^27.4.1", | ||
@@ -76,3 +77,3 @@ "@types/node": "^16.18.54", | ||
"@metamask/approval-controller": "^4.1.0", | ||
"@metamask/network-controller": "^15.1.0", | ||
"@metamask/network-controller": "^16.0.0", | ||
"@metamask/preferences-controller": "^4.4.3" | ||
@@ -79,0 +80,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
700678
6658
+ Added@noble/hashes@1.6.0(transitive)
+ Added@types/node@22.9.3(transitive)
+ Addedcipher-base@1.0.5(transitive)
+ Addednanoid@3.3.7(transitive)
+ Addedundici-types@6.19.8(transitive)
- Removed@metamask/network-controller@15.2.0(transitive)
- Removed@noble/hashes@1.6.1(transitive)
- Removed@types/node@22.10.0(transitive)
- Removedcipher-base@1.0.6(transitive)
- Removednanoid@3.3.8(transitive)
- Removedundici-types@6.20.0(transitive)
Updated@metamask/eth-query@^4.0.0
Updated@metamask/utils@^8.2.0