I have the code, but the issue I am facing is, I'll need the contract ABI and for that I will need the user wallet address, the "To" address where the NFT will be sent. However that is not possible because I am only capturing that when the user clicks on the connect wallet button on my quizsite and I save the wallet address in the UserAddress variable. So how to resolve this issue? Is there a way where I can capture the user wallet address and then call the solidity contract from the JS code but the question is how do I save the ABI? Also there will be more than one users using the site, so how to tackle that?

    //For the below code to work, one must install node js and then store the keys in the .env folder 

    import { userAddress } from "./connectWallet.js";
    const ethers = require('ethers');  

    // we include the dotenv package so that it can bring the keys from the .env folder 
   //env variables can be accessed in JS by process.env 


   async function claimNFT() { 
  //An RPC URL is the URL of an Ethereum node which is working as a provider for us in the code. 
  const provider = new ethers.JsonRpcProvider(process.env.ETHEREUM_RPC_URL);
  const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
  const nftContractAddress = 'NFT_CONTRACT_ADDRESS';
  const tokenId = 'TOKEN_ID';
  const recipientAddress = 'userAddress';
  const nftContract = new ethers.Contract(nftContractAddress, ['function safeTransferFrom(address from, address to, uint256 tokenId)'], wallet);
  const tx = await nftContract.safeTransferFrom(wallet.address, userAddress, tokenId);
  await tx.wait();
  console.log(`NFT transferred successfully to ${userAddress}`);



My solidity code looks like this for now:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract NFTContract is ERC721, Ownable {
    constructor() ERC721("YourNFT", "winner") {}

    function mint(address userAddress, uint256 tokenId) public onlyOwner {
        _safeMint(userAddress, tokenId);

    // Transfer the NFT to the user
    function transferNFT ()public {
        address userAddress = msg.sender;
        ERC721(contractAddress).safeTransferFrom(msg.sender, userAddress, tokenId);

1 Answer 1


The contract ABI is not related to user address. This ABI related to the smart contract logic and should be fixed according to that smart contract address. Here is how you can find the ABI. For example, for the pancakeswap prediction smart contract: https://bscscan.com/address/0x18B2A687610328590Bc8F2e5fEdDe3b582A49cdA#code

Then, scroll down, you will see the ABI section as

enter image description here

Then, you can export the ABI or just simply copy as paste it to your code. Finally, you can use JS to load the ABI. Something like this will work

import scAbi from './abi/scAbi.json';

const web3 = new Web3(
   new Web3.providers.HttpProvider(networkRPC),

const sc = new web3.eth.Contract(
    scAbi as any,

Hope it helps you.

  • so if I run the code with any wallet address, the same ABI will be applicable for all user wallet addresses, right? Dec 27, 2023 at 18:40
  • Yes, that is right since the contract API related to smart contract code not the wallet address. Hope it helps.
    – tqdpham96
    Dec 27, 2023 at 19:29
  • Yes, it does! Thanks man! Dec 28, 2023 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.