Transfer existing NFT tokens via Alchemy SDK

I created some NFT tokens on OpenSea using the Polygon Mumbai testnet. Now I need to move these tokens to different wallet addresses through Alchemy’s web3 library.

Since this runs inside a Node.js REST API without browser wallet access, I have to sign transactions manually with private keys.

My current approach isn’t working and I think the transaction structure is wrong:

async function transferNFT() {
  const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
  const web3Instance = createAlchemyWeb3(process.env.ALCHEMY_URL);
  
  const senderWallet = '0x...';
  const currentNonce = await web3Instance.eth.getTransactionCount(senderWallet, 'latest');
  
  const txData = {
    'token': {
      'id': '123456789', // NFT token identifier
    },
    'gasLimit': 53000,
    'recipient': '0x...', // destination wallet
    'amount': 1,
    'nonce': currentNonce,
  };
  
  const signedTransaction = await web3Instance.eth.accounts.signTransaction(txData, process.env.WALLET_KEY);
  
  web3Instance.eth.sendSignedTransaction(signedTransaction.rawTransaction, (err, txHash) => {
    if (!err) {
      console.log("Transaction hash:", txHash);
    } else {
      console.log("Error:", err);
    }
  });
}

What’s the correct way to structure this transaction for NFT transfers?

hmm interesting problem! i’ve been tinkering with nft transfers myself lately and noticed something in your code that might be causing issues.

Your transaction structure looks like you’re trying to send a regular eth transaction, but nft transfers actually need to call specific contract methods. Are you trying to transfer an erc-721 or erc-1155 token? this makes a difference in how you structure the call.

For erc-721 tokens, you’d typically need to encode a call to either transferFrom() or safeTransferFrom() method on the nft contract itself. your current txData object is missing some key pieces like the contract address and the encoded function call.

A few questions that might help troubleshoot:

  • do you have the contract address of your nft collection?
  • what error messages are you getting exactly when it fails?
  • have you tried using web3’s contract interface to interact with the nft contract directly instead of building raw transactions?

I’ve found that using the contract abi and calling the transfer methods through web3’s contract interface tends to be more reliable than crafting raw transactions manually. the gas estimation also works better that way.

what does your error output look like? that might give us some clues about whether its a gas issue, encoding problem, or something else entirely.

your missing the contract address and method encoding! nft transfers need to call the actual smart contract, not just send a transaction. try using web3.eth.contract with the nft’s abi and call safeTransferFrom directly - much easier than manually encoding everything.

The fundamental issue is treating NFT transfers like standard ETH transactions when they require invoking smart contract functions. I faced a similar challenge while developing an NFT marketplace backend. For ERC-721 tokens, utilize safeTransferFrom(from, to, tokenId), interacting directly with the NFT contract through its ABI. Ensure your transaction includes the contract address as to and the corresponding encoded function call as data. I recommend sourcing the contract ABI from OpenSea or Etherscan, and utilizing web3 to instantiate the contract for your transactions. Additionally, consider setting a higher gas limit, around 100k, for NFT transfers on the Polygon network. Always verify that you are the owner or an approved operator for the token to avoid reverts.