public-awesome / cw-nfts

Examples and helpers to build NFT contracts on CosmWasm
Apache License 2.0
186 stars 179 forks source link

burn and mint contract does not work in testnet #157

Closed NicoSerranoP closed 4 months ago

NicoSerranoP commented 4 months ago

Hi guys! I am building a swap NFTs contract: you send a NFT from an old collection and it sends you back a NFT from a new collection. It is working and passing the tests but in a testnet I am not able to send the new NFT (it does not fail or anything but it simply does not send the new NFT)

If you know cosmWASM could you take a look? The specific function is in src/execute.rs and its code is:

use std::marker::PhantomData;
use cosmwasm_std::{from_json, Addr, Empty, MessageInfo, Response};
use cw721::Cw721ReceiveMsg;
use cw721_base::msg::ExecuteMsg as Cw721ExecuteMsg;
use cw721_base::helpers::Cw721Contract;

use crate::{msg::InnerMsg, ContractError};

pub fn receive_nft(info: MessageInfo, receive_msg: Cw721ReceiveMsg) -> Result<Response, ContractError> {
    let token_id = receive_msg.token_id.as_str();
    let recipient = receive_msg.sender.as_str();
    let inner_msg: InnerMsg = from_json(&receive_msg.msg)?;
    let new_collection_addr = inner_msg.new_collection_addr;

    let old_collection_env_addr = info.sender.as_str();
    let old_collection_addr = Addr::unchecked("sei1exm3fjundhdzf6wng3xcny4nhjlawwmztxd286f35zcvx4mav4jqcnese6");
    if old_collection_addr != old_collection_env_addr {
        return Err(ContractError::Unauthorized {});
    }

    let burn_msg: cw721_base::ExecuteMsg<Empty, Empty> = Cw721ExecuteMsg::Burn {
        token_id: token_id.to_string()
    };
    Cw721Contract::<Empty, Empty>(
        old_collection_addr.clone(),
        PhantomData,
        PhantomData
    ).call(burn_msg).unwrap();

    let mint_msg: cw721_base::ExecuteMsg<Empty, Empty> = Cw721ExecuteMsg::TransferNft {
        recipient: recipient.to_string(),
        token_id: token_id.to_string() as String
    };
    Cw721Contract::<Empty, Empty>(
        new_collection_addr.clone(),
        PhantomData,
        PhantomData
    ).call(mint_msg).unwrap();

    let response = Response::new();
    // Return the response
    Ok(
        response
            .add_attribute("action", "burn_to_mint")
            .add_attribute("old_collection", old_collection_addr.to_string())
            .add_attribute("old_collection_env", old_collection_env_addr.to_string())
            .add_attribute("new_collection", new_collection_addr.to_string())
            .add_attribute("recipient", recipient.to_string())
            .add_attribute("token_id", token_id.to_string())
    )
}

old collection:

✔ CW721 Contract deployed to SEI blockchain. Contract Code ID: 6528
✔ Collection registered to Lighthouse
Transaction hash: FBD4A2A8E3D07222B714D09126ABCDBBF85637FE8E0FD70418C14DEDE1177557
Collection address: sei1exm3fjundhdzf6wng3xcny4nhjlawwmztxd286f35zcvx4mav4jqcnese6

new collection:

✔ CW721 Contract deployed to SEI blockchain. Contract Code ID: 6543
✔ Collection registered to Lighthouse
Transaction hash: B86C9E196D28EAE4377E7E00AABFADAA9B0AB7E1573AA451FF9DAC15F82C2FF2
Collection address: sei1hk432lyxulw63utftn8x9wk28pcsrnyva2jnuue7sds85vzdz99st36w3l

Code repository: https://github.com/NicoSerranoP/swap-nft-template

last transaction (didnt work): https://www.seiscan.app/atlantic-2/txs/A7335472CEAC5D455A67A41917D2FD21DA2794276A31A73223755C6CCC30A25B

yubrew commented 4 months ago

did you mint the new nft before trying to transfer it? are you calling the transfer msg from the current nft owner?

let mint_msg: cw721_base::ExecuteMsg<Empty, Empty> = Cw721ExecuteMsg::TransferNft { recipient: recipient.to_string(), token_id: token_id.to_string() as String };

On Tue, Feb 27, 2024 at 9:48 AM Nico Serrano @.***> wrote:

Hi guys! I am building a swap NFTs contract: you send a NFT from an old collection and it sends you back a NFT from a new collection. It is working and passing the tests but in a testnet I am not able to send the new NFT (it does not fail or anything but it simply does not send the new NFT)

If you know cosmWASM could you take a look? The specific function is in src/execute.rs and its code is:

use std::marker::PhantomData;use cosmwasm_std::{from_json, Addr, Empty, MessageInfo, Response};use cw721::Cw721ReceiveMsg;use cw721_base::msg::ExecuteMsg as Cw721ExecuteMsg;use cw721_base::helpers::Cw721Contract; use crate::{msg::InnerMsg, ContractError}; pub fn receive_nft(info: MessageInfo, receive_msg: Cw721ReceiveMsg) -> Result<Response, ContractError> { let token_id = receive_msg.token_id.as_str(); let recipient = receive_msg.sender.as_str(); let inner_msg: InnerMsg = from_json(&receive_msg.msg)?; let new_collection_addr = inner_msg.new_collection_addr;

let old_collection_env_addr = info.sender.as_str();
let old_collection_addr = Addr::unchecked("sei1exm3fjundhdzf6wng3xcny4nhjlawwmztxd286f35zcvx4mav4jqcnese6");
if old_collection_addr != old_collection_env_addr {
    return Err(ContractError::Unauthorized {});
}

let burn_msg: cw721_base::ExecuteMsg<Empty, Empty> = Cw721ExecuteMsg::Burn {
    token_id: token_id.to_string()
};
Cw721Contract::<Empty, Empty>(
    old_collection_addr.clone(),
    PhantomData,
    PhantomData
).call(burn_msg).unwrap();

let mint_msg: cw721_base::ExecuteMsg<Empty, Empty> = Cw721ExecuteMsg::TransferNft {
    recipient: recipient.to_string(),
    token_id: token_id.to_string() as String
};
Cw721Contract::<Empty, Empty>(
    new_collection_addr.clone(),
    PhantomData,
    PhantomData
).call(mint_msg).unwrap();

let response = Response::new();
// Return the response
Ok(
    response
        .add_attribute("action", "burn_to_mint")
        .add_attribute("old_collection", old_collection_addr.to_string())
        .add_attribute("old_collection_env", old_collection_env_addr.to_string())
        .add_attribute("new_collection", new_collection_addr.to_string())
        .add_attribute("recipient", recipient.to_string())
        .add_attribute("token_id", token_id.to_string())
)}

old collection:

✔ CW721 Contract deployed to SEI blockchain. Contract Code ID: 6528 ✔ Collection registered to Lighthouse Transaction hash: FBD4A2A8E3D07222B714D09126ABCDBBF85637FE8E0FD70418C14DEDE1177557 Collection address: sei1exm3fjundhdzf6wng3xcny4nhjlawwmztxd286f35zcvx4mav4jqcnese6

new collection:

✔ CW721 Contract deployed to SEI blockchain. Contract Code ID: 6543 ✔ Collection registered to Lighthouse Transaction hash: B86C9E196D28EAE4377E7E00AABFADAA9B0AB7E1573AA451FF9DAC15F82C2FF2 Collection address: sei1hk432lyxulw63utftn8x9wk28pcsrnyva2jnuue7sds85vzdz99st36w3l

Code repository: https://github.com/NicoSerranoP/swap-nft-template

last transaction (didnt work): https://www.seiscan.app/atlantic-2/txs/A7335472CEAC5D455A67A41917D2FD21DA2794276A31A73223755C6CCC30A25B

— Reply to this email directly, view it on GitHub https://github.com/CosmWasm/cw-nfts/issues/157, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADRXUROQJTHO2E5IP5UVHTYVYE6LAVCNFSM6AAAAABD4OZ3UCVHI2DSMVQWIX3LMV43ASLTON2WKOZSGE2TOMJSGI4DSMA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

NicoSerranoP commented 4 months ago

Yes! I minted the new NFTs and send them all to the contract address using transfer_nft. The contract is the owner of all the NFTs and only transfer them if it receives the old nft.

If you check the contract code is not even burning the previous nft after receiving it :(

NicoSerranoP commented 4 months ago

I solved it by adding the callbacks to the response object:

// ...

let burn_callback = Cw721Contract::<Empty, Empty>(
        old_collection_addr.clone(),
        PhantomData,
        PhantomData
    ).call(burn_msg)?;

    let mint_msg: cw721_base::ExecuteMsg<Empty, Empty> = Cw721ExecuteMsg::TransferNft {
        recipient: recipient.to_string(),
        token_id: token_id.to_string() as String
    };
    let mint_callback = Cw721Contract::<Empty, Empty>(
        new_collection_addr.clone(),
        PhantomData,
        PhantomData
    ).call(mint_msg)?;

    let response = Response::new();
    // Return the response
    Ok(
        response
            .add_message(burn_callback)
            .add_message(mint_callback)

//...