NFT Burn
Access prerequisites
- Permission (module):
burnNftAsset - License/Feature:
MANAGE_NFTS - Menu container: TOKENIZATION → group Tokenization → NFT Burn
- Security: execution requires step-up (password + MFA re-authentication) and passes through admin action risk verification.
What it is / when to use
Allows burning all NFTs of an asset (asset_id) — that is, removing the customer_nfts entries of that asset from all holders. This is the official path for recall, fraud, or offer closure, leaving no "ghost" balance in the main wallet and locking the asset for new sales at the moment of the burn.
The burn is asynchronous: the operator triggers the operation and receives an operationId within seconds; the on-chain processing of each NFT happens in the background (watcher), and the detail screen polls every 30s to track progress.
Pre-conditions
- Permission:
burnNftAsset(dual — CPM enumburnNftAsseton the backend + dynamic module in the DB). Without both, the action does not appear or returns 403. - License/Feature:
MANAGE_NFTS. - Mandatory step-up: password + MFA (5-minute window,
X-Step-Up-Tokenheader). This is not 4-eyes approval — it is re-authentication of the operator themselves.
Step by step
- Go to Tokenization → NFT Burn.
- Click New burn to open the creation panel.
- Search and select the asset (NFT) to be burned.
- The system generates a preview of the operation — see the table below.
- Fill in the reason (minimum 20 characters) and confirm by typing the asset name.
- Click Execute burn → the system requests step-up (password + MFA).
- Track the operation in the listing and on the detail screen (30s polling).
Operation preview
Before executing, the preview shows what will be affected:
| Preview field | What it shows |
|---|---|
| Total holders | How many users own the asset |
| Total NFTs | How many NFTs will be burned |
| Native burn (count) | NFTs that will be burned via burn(tokenId) on-chain (strategy NATIVE_BURN, v2 contract) |
| Sink transfer (count) | NFTs that will be moved to the sink wallet (strategy SINK_TRANSFER, v1 contract) |
| Sink addresses used | Sink wallet per chain (EVM/SOL/XRPL) configured by env var |
| Current block sell / block resell | Current state of the asset locks |
| Active operation? | Whether a burn is already in progress for the same asset (blocks new one) |
| Skipped | Non-burnable NFTs: AT_AUCTION (in auction), NO_SINK_CONFIGURED, XRPL_NOT_SUPPORTED, ALREADY_SINK |
Fields (creation)
| Field | What it is | Required? | System/backend effect |
|---|---|---|---|
| Asset | NFT target of the burn | Yes | assetId — scans customer_nfts WHERE asset_id = X. |
| Reason | Justification for the burn (≥ 20 characters) | Yes | reason — recorded in the operation for audit. |
| Name confirmation | Type the name (or id) of the asset | Yes | Safety lock: only enables Execute if it matches exactly. |
What happens on execution
- Asset locks:
block_sellandblock_resellare turned on in the same atomic transaction as the operation header, with a snapshot of the previous values (previous_block_sell/resell) for later manual rollback. - Holder destination: the
customer_idof each NFT changes toBURN_SINK_<CHAIN>(BURN_SINK_EVM/SOL/XRPL). The row incustomer_nftsis kept (not deleted) — it does not go toTKN_OWNER. - On-chain: according to
collections.contract_version—v2burns natively (NATIVE_BURN);v1(current default) moves to the sink wallet (SINK_TRANSFER). XRPL is not supported in the MVP (appears as skipped). - Accounting: the ledger (
general_journal) records only the debit of the holder (asset write-off), with no mirror credit.
Operation status
| Status | Meaning |
|---|---|
| PENDING / IN_PROGRESS | Off-chain already committed; on-chain still syncing (shown as success with "syncing blockchain" caption). |
| COMPLETED | All items confirmed on-chain. |
| PARTIAL_FAILED | Some items failed on-chain. |
| FAILED | The operation failed. |
Each item (NFT) has its own status: PENDING → CONFIRMED / FAILED, with transaction_hash and error_message.
Actions and modals
- Execute burn: triggers
executewith mandatory step-up. - Reprocess item (retry): on the detail screen, re-executes a failed item — also with step-up.
- Polling: the detail screen updates automatically every 30s while the operation is in progress.
Business rules / cautions
Irreversible
- The burn removes the NFT from all holders and has no automatic rollback. Each NFT can only be burned once in its history (uniqueness by
customer_nft_id). - The
block_sell/block_reselllocks remain on; rollback is manual (using theprevious_block_*snapshot).
Caution
- One burn per asset at a time: a partial unique constraint on
(asset_id) WHERE status IN ('PENDING','IN_PROGRESS')prevents two concurrent burns on the same asset. - Operational queries must filter
customer_id NOT LIKE 'BURN_SINK_%'— balances in sink are not real positions. - NFTs in auction (
AT_AUCTION) and XRPL are skipped.
- Idempotency: the operation is idempotent by asset (header) and by NFT (item). Reprocessing an already-confirmed item is safe.
Examples
Scenario 1 — Offer closure (full recall)
- Open New burn and select the asset of the closed offer.
- Preview shows, for example, 120 holders / 300 NFTs, all
SINK_TRANSFER(v1 collection). - Reason: "Closure of offer X as per clause Y of the contract."
- Confirm by typing the asset name → Execute → step-up.
- Locks turn on, 300 rows migrate to
BURN_SINK_EVM, watcher confirms each transfer. Track until COMPLETED.
Scenario 2 — Fraudulent NFT with items in auction
- Select the asset. Preview lists some items as skipped: AT_AUCTION.
- Those are not burned in this operation — finalize/cancel the auction and run the burn again to capture them.
- Items that fail on-chain can be reprocessed individually on the detail screen (with step-up).
Related screens
On-chain tracking of burns (transaction type
burn) also appears in the NFT Blockchain Transactions journal in the Tokenization container.