Skip to content

Immutable passport is not running, but metamask is working #2627

Open
@TopCodeBeast

Description

@TopCodeBeast

I'm making NFT marketplace and there are smart contract and frontend
I'll call NFT mint and NFT CreateSale for sale and then I'll buy that NFT.
I tried with metamask and immutable passport wallet for testing.
On metamask, it worked well but on immutable passport, it shows this error.

Error: transaction execution reverted (action="sendTransaction", data=null, reason=null, invocation=null, revert=null, transaction={ "data": "", "from": "0xDF3569B056b5CA0bf38952353dc402326ABDb68c", "to": "0x8CC5B4748cBf9810Be73A90b0CB6802EBae06B59" }, receipt={ "_type": "TransactionReceipt", "blobGasPrice": null, "blobGasUsed": null, "blockHash": "0x35fbfa36dd03ac565033172f2da2322f71f5075909d8286aa5acbd10ed7961ca", "blockNumber": 24037913, "contractAddress": null, "cumulativeGasUsed": "60790", "from": "0xDF3569B056b5CA0bf38952353dc402326ABDb68c", "gasPrice": "10000000049", "gasUsed": "60790", "hash": "0x5533cf6cf93efa0de2659fef5e6d39d0332f6c9dfb115ee26bbf9eea2910558f", "index": 0, "logs": [ ], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "root": null, "status": 0, "to": "0x8CC5B4748cBf9810Be73A90b0CB6802EBae06B59" }, code=CALL_EXCEPTION, version=6.14.0)
at makeError (webpack-internal:///(app-pages-browser)/./node_modules/ethers/lib.esm/utils/errors.js:137:21)
at assert (webpack-internal:///(app-pages-browser)/./node_modules/ethers/lib.esm/utils/errors.js:156:15)
at checkReceipt (webpack-internal:///(app-pages-browser)/./node_modules/ethers/lib.esm/providers/provider.js:1141:68)
at BrowserProvider.txListener (webpack-internal:///(app-pages-browser)/./node_modules/ethers/lib.esm/providers/provider.js:1187:33)
I've got this error when buy

here is smart contract code
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.27;

import "@openzeppelin/contracts/interfaces/IERC721.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "./interfaces/IWOMs.sol";

contract WOMsMarketplace is
OwnableUpgradeable,
ReentrancyGuardUpgradeable,
IERC721Receiver,
UUPSUpgradeable
{
uint256 private platformFee;
address private feeRecipient;

struct ListNFT {
    address nft;
    uint256 tokenId;
    address seller;
    uint256 price;
    uint256 royaltyFee;
    address royaltyRecipient;
    uint256 date;
}

// nft => tokenId => list struct
mapping(address => mapping(uint256 => ListNFT)) private listNfts;

// events
event ListedNFT(
    address indexed nft,
    uint256 indexed tokenId,
    uint256 price,
    uint256 date,
    address indexed seller,
    uint256 royaltyFee,
    address royaltyRecipient
);
event BoughtNFT(
    address indexed nft,
    uint256 indexed tokenId,
    uint256 price,
    uint256 date,
    address seller,
    address indexed buyer,
    uint256 royaltyFee,
    address royaltyRecipient
);


function initialize(
    uint256 _platformFee,
    address _feeRecipient
) public initializer {
    __Ownable_init(msg.sender);
    __ReentrancyGuard_init();
    require(_platformFee <= 1000, "can't more than 10 percent");
    platformFee = _platformFee;
    feeRecipient = _feeRecipient;
}

modifier isListedNFT(address _nft, uint256 _tokenId) {
    ListNFT memory listedNFT = listNfts[_nft][_tokenId];
    require(listedNFT.seller != address(0), "not listed");
    _;
}

modifier isNotListedNFT(address _nft, uint256 _tokenId) {
    ListNFT memory listedNFT = listNfts[_nft][_tokenId];
    require(listedNFT.seller == address(0), "already listed");
    _;
}

/**
 * @notice put the NFT on marketplace
 * @param _nft specified NFT collection address
 * @param _tokenId specified NFT id to sell
 * @param _price the price of NFT
 */
function createSell(
    address _nft,
    uint256 _tokenId,
    uint256 _price
) external isNotListedNFT(_nft, _tokenId) {
    IERC721 nft = IERC721(_nft);
    require(nft.ownerOf(_tokenId) == msg.sender, "not nft owner");

    IWOMs WOMS_nft = IWOMs(_nft);
    address royaltyRecipient = WOMS_nft.getRoyaltyRecipient();
    uint256 royaltyFee = WOMS_nft.getRoyaltyFee();

    listNfts[_nft][_tokenId] = ListNFT({
        nft: _nft,
        tokenId: _tokenId,
        seller: msg.sender, // Changed to msg.sender
        price: _price,
        royaltyFee: royaltyFee,
        royaltyRecipient: royaltyRecipient,
        date: block.timestamp
    });

    emit ListedNFT(
        _nft,
        _tokenId,
        _price,
        block.timestamp,
        msg.sender, // Changed to msg.sender
        royaltyFee,
        royaltyRecipient
    );
}


/**
 * @notice buy a NFT from marketplace
 * @param _nft NFT collection address to buy
 * @param _tokenId specified NFT id to buy
 */
function buy(
    address _nft,
    uint256 _tokenId
) external payable isListedNFT(_nft, _tokenId) {
    ListNFT storage listedNft = listNfts[_nft][_tokenId];

    require(msg.value >= listedNft.price, "invalid price");

    uint256 totalPrice = msg.value;
    IWOMs nft = IWOMs(listedNft.nft);
    address royaltyRecipient = nft.getRoyaltyRecipient();
    uint256 royaltyFee = nft.getRoyaltyFee();

    if (royaltyFee > 0) {
        uint256 royaltyTotal = calculateRoyalty(royaltyFee, msg.value);
        payable(royaltyRecipient).transfer(royaltyTotal);
        totalPrice -= royaltyTotal;
    }

    // Calculate & Transfer platform fee
    uint256 platformFeeTotal = calculatePlatformFee(msg.value);
    payable(feeRecipient).transfer(platformFeeTotal);

    // Transfer to seller
    payable(listedNft.seller).transfer(totalPrice - platformFeeTotal);

    // Transfer NFT directly from seller to buyer
    IERC721(listedNft.nft).safeTransferFrom(
        listedNft.seller,
        msg.sender,
        listedNft.tokenId
    );

    address sender = listedNft.seller;

    delete listNfts[_nft][_tokenId];

    emit BoughtNFT(
        _nft,
        _tokenId,
        msg.value,
        block.timestamp,
        sender,
        msg.sender,
        royaltyFee,
        royaltyRecipient
    );
}

/**
 * @notice send a NFT from marketplace
 * @param _nft NFT collection address to buy
 * @param _tokenId specified NFT id to buy
 */
function send(address _nft, uint256 _tokenId, address getter) external {
    IERC721 nft = IERC721(_nft);
    require(nft.ownerOf(_tokenId) == msg.sender, "not nft owner");

    // Check if the NFT is listed for sale
    ListNFT storage listedNft = listNfts[_nft][_tokenId];
    if (listedNft.seller != address(0)) {
        // If listed, remove the listing
        delete listNfts[_nft][_tokenId];
    }
function calculatePlatformFee(
    uint256 _price
) public view returns (uint256) {
    return (_price * platformFee) / 10000;
}

function calculateRoyalty(
    uint256 _royalty,
    uint256 _price
) public pure returns (uint256) {
    return (_price * _royalty) / 10000;
}

function getListedNFT(
    address _nft,
    uint256 _tokenId
) public view returns (ListNFT memory) {
    return listNfts[_nft][_tokenId];
}

function updatePlatformFee(uint256 _platformFee) external onlyOwner {
    require(_platformFee <= 1000, "can't more than 10 percent");
    platformFee = _platformFee;
}

function changeFeeRecipient(address _feeRecipient) external onlyOwner {
    require(_feeRecipient != address(0), "can't be 0 address");
    feeRecipient = _feeRecipient;
}

function onERC721Received(
    address,
    address,
    uint256,
    bytes calldata
) public virtual override returns (bytes4) {
    return this.onERC721Received.selector;
}

}

for frotend code,
first createSale code
let signer: ethers.Signer | null = null;
if (connectName === 'MetaMask') {
await window.ethereum.request({ method: "eth_requestAccounts" });
const provider = new ethers.BrowserProvider(window.ethereum);
signer = await provider.getSigner();
} else if (connectName === 'Immutable Passport') {
const passportProvider = await passportInstance.connectEvm();
const provider = new ethers.BrowserProvider(passportProvider);
signer = await provider.getSigner();
// Verify network
const network = await provider.getNetwork();
console.log("Connected network:", network);
}
if (signer) {
try {
// Parse the price input
const price = ethers.parseUnits(inputValue.toString(), "ether");
if (id) {
// Extract token ID from composite id
const [nftAddress, tokenId] = id.split('-');
if (!nftAddress || !tokenId) throw new Error("Invalid NFT ID");
const tokenIdNumber = parseInt(tokenId, 10); // Ensure correct base (e.g., 10 for decimal)

          const NftContract = new ethers.Contract(NFTContract.address, NFTContract.abi, signer);
          // Check current approval
          const currentApproved = await NftContract.getApproved(tokenId);
          if (currentApproved !== MarketplaceContract.address) {
            const approve = await NftContract.approve(MarketplaceContract.address as 0x${string}, nft.index, {
              gasLimit: 5000000, // Set a custom gas limit
            });
            await approve.wait();
            console.log({ approve })
            toast.success("Success to Approve!");
            const marketplaceContract = new ethers.Contract(MarketplaceContract.address, MarketplaceContract.abi, signer);
            const tx = await marketplaceContract.createSell(NFTContract.address as 0x${string},
              tokenIdNumber,
              price,
              {
                gasLimit: 5000000, // Set a custom gas limit
              });
            await tx.wait(); // Wait for the transaction to be mined
            console.log("Transaction successful:", tx.hash);

            // Update transaction and step state
            setTx(tx.hash);
            setIsModalOpen(true)
            toast.success("Success for Sale!");
            router.push('/synapCreatorProfile');
          }
          else {
            const marketplaceContract = new ethers.Contract(MarketplaceContract.address, MarketplaceContract.abi, signer);
            const tx = await marketplaceContract.createSell(NFTContract.address as 0x${string},
              tokenIdNumber,
              price,
              address, {
              gasLimit: 5000000, // Set a custom gas limit
            });
            await tx.wait(); // Wait for the transaction to be mined
            console.log("Transaction successful:", tx.hash);

            // Update transaction and step state
            setTx(tx.hash);
            setIsModalOpen(true)
            toast.success("Success for Sale!");
            router.push('/synapCreatorProfile');
          }
        }

      } catch (error) {
        console.error("Error:", error);
      }
    }

second buy code

let signer: ethers.Signer | null = null;
    if (connectName === 'MetaMask') {
      await window.ethereum.request({ method: "eth_requestAccounts" });
      const provider = new ethers.BrowserProvider(window.ethereum);
      signer = await provider.getSigner();
      // Verify network
      const network = await provider.getNetwork();
      console.log("Connected network:", network);
    } else if (connectName === 'Immutable Passport') {
      const passportProvider = await passportInstance.connectEvm();
      const provider = new ethers.BrowserProvider(passportProvider);
      signer = await provider.getSigner();
      // Verify network
      const network = await provider.getNetwork();
      console.log("Connected network:", network);
    }
    if (signer) {
      const mintPrice = nft.listNFTs[0].price;

      if (parseInt(mintPrice.toString()) >= (balance?.value ?? 0)) {
        toast.error("Insufficient Balance for Purchasing");
        return;
      }

      const contract = new ethers.Contract(MarketplaceContract.address, MarketplaceContract.abi, signer);
      const tokenIdNumber = parseInt(nft.index, 10); // Ensure correct base (e.g., 10 for decimal)
      const tx = await contract.buy(nft.collection, tokenIdNumber, {
        value: BigInt(mintPrice),
        gasLimit: 5000000, // Set a custom gas limit
      });
      await tx.wait();
      console.log("Transaction:", tx);
      // Update transaction and step state
      setTx(tx.hash);

      setIsModalOpen(true)
      router.push('/synapCreatorProfile');
    }

In the past, it worked well and after v2.
It didn't work.
Plz tell me.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions