Трансфер NFT-айтема

Соберёшь и отправишь NFT transfer (TEP-62): тело transfer#5fcc3d14, адрес item и forward_amount.

Куда слать transfer

Смена владельца NFT — сообщение с opcode transfer#5fcc3d14 на адрес item. Отправитель должен быть текущим owner. В теле указываешь new_owner; collection в transfer не участвует.


Переводим NFT другому кошельку

typescript
// @ton/ton ^15.1.0, @ton/core ^0.59.0
// TEP-62: transfer#5fcc3d14
import { Address, beginCell, toNano, TonClient } from "@ton/ton";

const OP_TRANSFER = 0x5fcc3d14;
const OP_OWNERSHIP_ASSIGNED = 0x05138d91; // уведомление новому owner при forward_amount > 0

function buildNftTransfer(opts: {
  newOwner: Address;
  responseTo: Address;
  forwardTon: bigint;
  queryId?: bigint;
}) {
  return beginCell()
    .storeUint(OP_TRANSFER, 32)
    .storeUint(opts.queryId ?? 0n, 64)
    .storeAddress(opts.newOwner)
    .storeAddress(opts.responseTo) // excesses + подтверждение
    .storeBit(false) // no custom_payload
    .storeCoins(opts.forwardTon)
    .storeBit(false) // no forward_payload
    .endCell();
}

async function sendNftTransfer() {
  const client = new TonClient({
    endpoint: "https://toncenter.com/api/v2/jsonRPC",
  });

  // Адрес конкретного NFT item (не collection)
  const nftItem = Address.parse(
    "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c", // ← item
  );
  const newOwner = Address.parse(
    "EQBIh6I6oCg_v7jW0-NmPV0UYPCQm1Nk4y2w4WX1XOc6-0kA",
  );
  const currentOwner = Address.parse(
    "EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N",
  );

  // Перед отправкой: get_nft_data → owner == currentOwner
  const data = await client.runMethod(nftItem, "get_nft_data");
  data.stack.readNumber(); // init?
  data.stack.readNumber(); // index
  data.stack.readAddress(); // collection
  const onchainOwner = data.stack.readAddress();
  if (!onchainOwner?.equals(currentOwner)) {
    throw new Error("Not owner on-chain — UI устарел или неверный item");
  }

  return {
    to: nftItem,
    value: toNano("0.05"), // газ + forward + запас на storage
    body: buildNftTransfer({
      newOwner,
      responseTo: currentOwner,
      forwardTon: toNano("0.01"), // >0 → new_owner получит ownership_assigned
    }),
  };
}

Как это работает

  • Цель — item; sender() должен совпасть с owner.
  • forward_amount > 0 → item шлёт ownership_assigned#05138d91 на new_owner (нужно sale/маркетплейс-контрактам).
  • response_destination получает excesses#d53276db — остаток Gram после газа.
  • После успеха get_nft_data покажет новый owner_address.

Частые ошибки

Шлёшь на collection → owner айтема не меняется. Только адрес item.

«Not owner» → UI показывает старого владельца, или сообщение ушло не с того кошелька. См. ошибку Not owner.

forward_ton = 0, а sale ждёт ownership_assigned → контракт продажи не узнает о получении NFT.


Что дальше

Материалы gramdocs.tech носят образовательный характер и не являются финансовой, юридической или инвестиционной рекомендацией. Работа с блокчейном TON и токеном Gram связана с рисками потери средств. Правовая информация