From 0595f0d3e1c9da859e9382d7d6e9e4ba0f8a8050 Mon Sep 17 00:00:00 2001 From: Trubnikov Sergey Date: Tue, 07 Mar 2023 12:29:52 +0000 Subject: [PATCH] feat: implement ERC721 `getApproved` for NFT. --- --- 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
{ - // TODO: Not implemetable - Err("not implemented".into()) + fn get_approved(&self, token_id: U256) -> Result
{ + let token = token_id.try_into()?; + let operator = >::get_allowance(self, token).map_err(dispatch_to_evm::)?; + Ok(if let Some(operator) = operator { + *operator.as_eth() + } else { + Address::zero() + }) } /// @notice Tells whether the given `owner` approves the `operator`. --- a/pallets/nonfungible/src/lib.rs +++ b/pallets/nonfungible/src/lib.rs @@ -1083,6 +1083,18 @@ } } + pub fn get_allowance( + collection: &NonfungibleHandle, + token: TokenId, + ) -> Result, DispatchError> { + ensure! { + >::iter_keys().find( + |(c, t)| return *c == collection.id && *t == token).is_some() + ,>::TokenNotFound + }; + Ok(>::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`. --- a/tests/src/eth/nonFungible.test.ts +++ b/tests/src/eth/nonFungible.test.ts @@ -240,6 +240,28 @@ } }); + itEth('Can perform setApproval()', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const operator = helper.eth.createAccount(); + + const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C'); + const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + + const result = await contract.methods.mint(owner).send({from: owner}); + const tokenId = result.events.Transfer.returnValues.tokenId; + + { + const approved = await contract.methods.getApproved(tokenId).call(); + expect(approved).to.be.equal('0x0000000000000000000000000000000000000000'); + } + await contract.methods.approve(operator, tokenId).send({from: owner}); + { + const approved = await contract.methods.getApproved(tokenId).call(); + expect(approved).to.be.equal(operator); + } + }); + + itEth('Can perform setApprovalForAll()', async ({helper}) => { const owner = await helper.eth.createAccountWithBalance(donor); const operator = helper.eth.createAccount(); -- gitstuff