Transfer NFT from server wallet to user wallet using Ethers.js or Web3.js

I’m looking for assistance with transferring an NFT from my server wallet to a user’s wallet in my decentralized application. Previously, I implemented this using Moralis, but I now intend to utilize either Ethers.js or Web3.js.

My former Moralis implementation functioned correctly, but I encountered this error message: Contract with a Signer cannot override from. Here’s the code I used:

async function sendTokenToPlayer(contractAddr, tokenNumber) {
  let playerAddress = await getUserAddress();
  let web3Instance = await Moralis.enableWeb3({
    chainId: 0x13881,
    privateKey: "my-wallet-private-key"
  });
  
  const transferOptions = {
    type: "erc721",
    receiver: playerAddress,
    contractAddress: contractAddr,
    tokenId: tokenNumber
  };
  
  let txn = await Moralis.transfer(transferOptions);
  let receipt = await txn.wait();
  return receipt;
}

What is the most effective way to perform this same operation using just Ethers or Web3? I want to sign the transaction with my server’s private key and transfer the NFT to the user currently logged into my app.

Hmm, interesting issue! What’s your setup - backend or client-side?

Private key handling changes depending on where your code runs. For server-side transfers, create a wallet instance directly from your private key and connect it to your contract.

Try new ethers.Wallet(privateKey, provider) then use that wallet with your NFT contract. What type of contract are you working with? Standard ERC721 or custom transfer methods?

Also, how are you getting the logged-in user’s wallet address? MetaMask or something else? This affects your transfer flow structure.

Have you checked the contract’s transfer functions directly? There’s usually transferFrom vs safeTransferFrom - your error might be from using the wrong method.

that error is usually due to setting the ‘from’ field when a signer is present. with ethers.js, create a provider, sign with your private key, and call transfer directly from your nft contract. just don’t include the ‘from’ field - the signer manages it automatically.

You’re mixing signer config with manual transaction params - that’s what’s breaking it. For server-side NFT transfers with ethers.js, you need a clean connection without conflicting settings. Here’s how I fixed the same issue: javascript const { ethers } = require('ethers'); const provider = new ethers.providers.JsonRpcProvider('your-rpc-url'); const serverWallet = new ethers.Wallet('your-private-key', provider); const contract = new ethers.Contract(contractAddress, abi, serverWallet); const tx = await contract.transferFrom(serverWallet.address, userAddress, tokenId); const receipt = await tx.wait(); The wallet instance handles signing automatically, so don’t specify ‘from’ parameters. Also make sure your server wallet has token approval first or you’ll hit revert errors.