Features

Transferring Assets

Last updated January 31, 2026

This guide shows how to transfer Core Assets between wallets on Solana using the Metaplex Core SDK. Send NFTs to other users with a single instruction.

What You'll Learn

  • Transfer an Asset to a new owner
  • Handle transfers for Assets in Collections
  • Use Transfer Delegate for authorized transfers
  • Understand transfer authority requirements

Summary

Transfer a Core Asset to a new owner using the transfer instruction. Only the current owner (or an authorized Transfer Delegate) can initiate a transfer.

  • Call transfer(umi, { asset, newOwner }) with the recipient's address
  • For Collection Assets, include the collection parameter
  • Transfer Delegates can transfer on behalf of owners
  • Transfers are free (only transaction fee applies)

Out of Scope

Token Metadata transfers (use mpl-token-metadata), batch transfers (loop through Assets), and marketplace sales (use escrow programs).

Quick Start

Jump to: Basic Transfer · Collection Transfer · Delegate Transfer

  1. Install: npm install @metaplex-foundation/mpl-core @metaplex-foundation/umi
  2. Fetch the Asset to verify ownership and collection membership
  3. Call transfer(umi, { asset, newOwner })
  4. Verify with fetchAsset() that ownership changed

Prerequisites

  • Umi configured with a signer that owns the Asset (or is its Transfer Delegate)
  • Asset address of the Asset to transfer
  • Recipient address (public key) of the new owner The owner of a Core Asset can transfer ownership to another account by using the transfer instruction to the MPL Core program.

Transferring a Core Asset

1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
2import { transfer } from '@metaplex-foundation/mpl-core'
3import { mplCore } from '@metaplex-foundation/mpl-core'
4import { publicKey } from '@metaplex-foundation/umi'
5
6// Initialize UMI
7const umi = createUmi('https://api.devnet.solana.com')
8 .use(mplCore())
9
10// Transfer an existing NFT asset to a new owner
11const result = await transfer(umi, {
12 asset: publicKey('AssetAddressHere...'),
13 newOwner: publicKey('RecipientAddressHere...'),
14}).sendAndConfirm(umi)
15
16console.log('Asset transferred:', result.signature)

Transferring a Core Asset in a Collection

If you are transferring an Asset which has a collection you will need to pass the collection address in. How to tell if an asset is in a Collection?

Transfer an Asset that is part of a Collection

import { publicKey } from '@metaplex-foundation/umi'
import { transferV1 } from '@metaplex-foundation/mpl-core'
const asset = publicKey('11111111111111111111111111111111')
await transferV1(umi, {
asset: asset.publicKey,
newOwner: newOwner.publicKey,
collection: colleciton.publicKey,
}).sendAndConfirm(umi)

What if I am the Transfer Delegate of an Asset?

If you are the Transfer Delegate of an Asset via the Transfer Delegate plugin then you can call the transferV1 function as you would if you were the owner of the Asset.

Common Errors

Authority mismatch

You're not the owner or Transfer Delegate of the Asset. Check ownership:

const asset = await fetchAsset(umi, assetAddress)
console.log(asset.owner) // Must match your signer

Asset is frozen

The Asset has a Freeze Delegate plugin and is currently frozen. The freeze authority must unfreeze it before transfer.

Missing collection parameter

For Assets in a Collection, you must pass the collection address. Check if the Asset has a collection:

const asset = await fetchAsset(umi, assetAddress)
if (asset.updateAuthority.type === 'Collection') {
console.log('Collection:', asset.updateAuthority.address)
}

Notes

  • Transfers are free - no rent cost, only the transaction fee (~0.000005 SOL)
  • The new owner receives full control of the Asset
  • Transfer, Burn, and Freeze Delegates are revoked after a successful transfer
  • Frozen Assets cannot be transferred until unfrozen
  • Always fetch the Asset first to check collection membership

Quick Reference

Transfer Parameters

ParameterRequiredDescription
assetYesAsset address or fetched object
newOwnerYesRecipient's public key
collectionIf in collectionCollection address
authorityNoDefaults to signer (use for delegates)

Who Can Transfer?

AuthorityCan Transfer?
Asset OwnerYes
Transfer DelegateYes (revoked after)
Update AuthorityNo
Collection AuthorityNo

FAQ

How do I know if an Asset is in a Collection?

Fetch the Asset and check its updateAuthority:

const asset = await fetchAsset(umi, assetAddress)
if (asset.updateAuthority.type === 'Collection') {
// Pass asset.updateAuthority.address as collection parameter
}

Can I transfer to myself?

Yes. Transferring to your own address is valid (useful for consolidating wallets or testing).

What happens to the Transfer Delegate after a transfer?

The Transfer Delegate plugin is automatically revoked when the transfer completes. The new owner must assign a new delegate if needed.

Can I cancel a transfer?

No. Transfers are atomic - once the transaction confirms, ownership has changed. There's no pending state to cancel.

Can I transfer multiple Assets at once?

Not in a single instruction. You can batch multiple transfer instructions in one transaction (up to transaction size limits), but each Asset requires its own transfer call.

Does transferring change the update authority?

No. Transfer only changes ownership. The update authority remains the same unless explicitly changed via the update instruction.

Glossary

TermDefinition
OwnerThe wallet that currently owns the Asset
Transfer DelegateAn account authorized to transfer on behalf of the owner
FrozenAn Asset state where transfers are blocked
New OwnerThe recipient wallet receiving the Asset
CollectionThe Collection an Asset belongs to (affects transfer requirements)