Transferring existing NFT tokens with Alchemy Web3 library

I created some NFT tokens through OpenSea and they exist on the Polygon Mumbai testnet. I need to move these tokens to different wallet addresses using the Alchemy Web3 SDK. My current implementation isn’t working properly.

This code runs inside a Node.js REST API environment, so there’s no browser wallet connection available. That’s why I need to sign transactions manually with a private key.

async function transferNFT() {
  require('dotenv').config();
  const { ALCHEMY_ENDPOINT, WALLET_PRIVATE_KEY } = process.env;
  const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
  const alchemyWeb3 = createAlchemyWeb3(ALCHEMY_ENDPOINT);
  
  const senderAddress = '*************************'
  const currentNonce = await alchemyWeb3.eth.getTransactionCount(senderAddress, 'latest');
  
  // I think this transaction structure is wrong, not sure what fields are needed
  const txObject = {
      'asset': {
        'tokenId': '******************************', // NFT ID from opensea
      },
      'gas': 53000,
      'to': '***********************', // recipient wallet address
      'quantity': 1,
      'nonce': currentNonce,
  }
 
  const signedTransaction = await alchemyWeb3.eth.accounts.signTransaction(txObject, WALLET_PRIVATE_KEY);
  
  alchemyWeb3.eth.sendSignedTransaction(signedTransaction.rawTransaction, function(err, txHash) {
    if (!err) {
      console.log("✅ Transaction hash: ", txHash, "\nCheck mempool for status!");
    } else {
      console.log("⚠️ Transaction failed:", err)
    }
  });
}

transferNFT();

your transaction object’s wrong. NFT transfers need to call the contract’s transferFrom method - you can’t just send random fields like ‘asset’ and ‘quantity’. you need to encode the function call with web3’s contract.methods or use the raw data field with proper abi encoding.

I ran into the same issue when transferring NFTs with Alchemy. The problem is you’re treating NFT transactions like regular ETH transfers, but they need a specific smart contract method call. Make sure you’re using the actual contract address for your NFT collection, not just the token ID. For ERC-721 tokens, you need safeTransferFrom(from, to, tokenId), and your transaction object must include a data field with this call. Also, 53,000 gas won’t cut it for NFT transfers - bump it up to 100k-150k. You can estimate the right amount using Alchemy’s methods. And double-check the sender actually owns the NFT you’re trying to transfer with Alchemy’s getNFTs method.

Interesting problem! Few questions - are you using ERC-721 or ERC-1155 tokens? Makes a difference for your approach.

Ray84’s right about the transaction structure, but have you tried using the actual contract address? With OpenSea NFTs, you need to hit the NFT contract directly, not send a generic transaction.

Also check if you need to approve the transfer first. Some contracts need two steps - approve, then execute.

What’s the exact error message? That’d help narrow things down. And do you have the contract ABI for your collection? You’ll likely need it to encode the function call properly.

One more thing - since you’re on Mumbai testnet, double-check your ALCHEMY_ENDPOINT points to the right network. Network mismatches can fail silently.

Can you share the specific error you’re getting?