git.delta.rocks / unique-network / refs/commits / 0595f0d3e1c9

difftreelog

feat implement ERC721 `getApproved` for NFT.

Trubnikov Sergey2023-03-07parent: #94299ed.patch.diff
in: master

3 files changed

modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -516,9 +516,14 @@
 	}
 
 	/// @dev Not implemented
-	fn get_approved(&self, _token_id: U256) -> Result<Address> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
+	fn get_approved(&self, token_id: U256) -> Result<Address> {
+		let token = token_id.try_into()?;
+		let operator = <Pallet<T>>::get_allowance(self, token).map_err(dispatch_to_evm::<T>)?;
+		Ok(if let Some(operator) = operator {
+			*operator.as_eth()
+		} else {
+			Address::zero()
+		})
 	}
 
 	/// @notice Tells whether the given `owner` approves the `operator`.
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -1083,6 +1083,18 @@
 		}
 	}
 
+	pub fn get_allowance(
+		collection: &NonfungibleHandle<T>,
+		token: TokenId,
+	) -> Result<Option<T::CrossAccountId>, DispatchError> {
+		ensure! {
+		<TokenData<T>>::iter_keys().find(
+			|(c, t)| return *c == collection.id && *t == token).is_some()
+		,<CommonError<T>>::TokenNotFound
+		};
+		Ok(<Allowance<T>>::get((collection.id, token)))
+	}
+
 	/// Set allowance for the spender to `transfer` or `burn` sender's token.
 	///
 	/// - `token`: Token the spender is allowed to `transfer` or `burn`.
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
240 }240 }
241 });241 });
242
243 itEth('Can perform setApproval()', async ({helper}) => {
244 const owner = await helper.eth.createAccountWithBalance(donor);
245 const operator = helper.eth.createAccount();
246
247 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
248 const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
249
250 const result = await contract.methods.mint(owner).send({from: owner});
251 const tokenId = result.events.Transfer.returnValues.tokenId;
252
253 {
254 const approved = await contract.methods.getApproved(tokenId).call();
255 expect(approved).to.be.equal('0x0000000000000000000000000000000000000000');
256 }
257 await contract.methods.approve(operator, tokenId).send({from: owner});
258 {
259 const approved = await contract.methods.getApproved(tokenId).call();
260 expect(approved).to.be.equal(operator);
261 }
262 });
263
242264
243 itEth('Can perform setApprovalForAll()', async ({helper}) => {265 itEth('Can perform setApprovalForAll()', async ({helper}) => {