Advanced transfers

To get the full story behind an NFT transfer, you'll need to dig deeper than the data you see on the chain. Read on to learn about some of the complexities associated with NFT transfer data, and how Mnemonic's API can help you solve for them.

Transfers represent a value exchange or a transfer of ownership between two accounts on the Ethereum blockchain. Mnemonic's API provides access to historical transfers of NFTs and fungible tokens, enabling you to retreive, analyze, and embed this information into your application without scanning the blockchain, which is a challenging and time-consuming task.

Furthermore, obtaining just a single transfer event from the blockchain often doesn't provide enough context to help understand what actually happened in the transaction beyond just the transfer of ownership. The most valuable information is often hidden in internal calls that happen between various contracts, in the relation to other transfers within the same transaction, such as ERC20 payments, swaps, and other properties.

Our Transfer Insights endpoints retreive rich data on transfers, making it easy to:

  • Get the accurate price of an NFT
  • Differentiate between mints, burns, sales, and airdrops
  • Calculate wash trades, bundles, and swaps
  • Calculate various fees paid by the buyer and the seller
  • Calculate fees received by a third-party

Read further to better understand the taxonomy of Mnemonic's Advanced Transfer endpoints.

General structure

ERC721 and ERC1155 transfers represent transfers of non-fungible and semi-fungible tokens between accounts.

Below is the top level NftTransfer object returned in the transfer responses, followed by a breakdown of each property.

Copy
Copied
message NftTransfer {
    // Blockchain event details.
    mnemonic.uniform.types.transfers.v1beta2.BlockchainEvent blockchain_event = 1;

    // Contract address that tracks the NFT.
    string contract_address = 2;

    // Token ID of the NFT.
    string token_id = 3;

    // Type of the token (ERC-721, ERC-1155, etc), detected by the event type
    // on the blockchain.
    mnemonic.uniform.types.nfts.v1beta2.Type token_type = 4;

    // Quantity of the NFTs in the transfer (given as string to provide simple
    // representation of uint256).
    //
    // All pricing details for the transfer event are provided according to this
    // quantity. For ERC-1155 quantity can be `0`, in this case pricing details
    // won't be provided.
    string quantity = 5;

    // Sender details.
    mnemonic.uniform.types.transfers.v1beta2.Address sender = 6;

    // Sale price details (how much sender received for the NFT).
    mnemonic.uniform.types.transfers.v1beta2.Price sender_received = 7;

    // Recipient details.
    mnemonic.uniform.types.transfers.v1beta2.Address recipient = 8;

    // Purchase price details (how much recipient paid for the NFT).
    mnemonic.uniform.types.transfers.v1beta2.Price recipient_paid = 9;

    // Labels represets kind of transaction and additional insites,
    // based on NFT, native and fungible token transfers inside the transaction:   
    // - indicate the type of transfer, possible values:  MINT, BURN, SALE or TRANSFER; at least one labels of this type is always applied;
    // - indicate the type of transaction, possible values: BUNDLE and SWAP;
    // - indicate the specific marketplaces involved, starts with the prefix "MARKETPLACE".
    repeated mnemonic.uniform.types.transfers.v1beta2.Label labels = 10;
}

ERC1155 Transfers

ERC1155 transfers represent transfers of semi-fungible tokens.

These transfers are defined using the same message type from above, however it is worth noting a couple of special cases.

Single Transfers

Single transfers are treated similarly to ERC721.

Batch Transfers

Batch transfers are provided unwrapped. If multiple tokens were transferred within a single transaction there will be multiple transfers provided in the response (one for each token in a batch).

In order to be able to differentiate between a single transfer and a batch transfer, an additonal seq_index field is provided within the BlockchainEvent message.

Copy
Copied
message BlockchainEvent {
    ...

    // Sequence index of the token transfer within a batch transfer, zero
    // otherwise.
    uint64 seq_index = 3;
}

Native Transfers (ETH, MATIC, etc)

While a single transfer event indicates a transfer of ownership of an NFT, there is usually more detail hidden in the transaction itself and in the special types of calls made between the contracts in the same transaction.

This data provides critical information needed to accurately compute an NFT price and the various fees paid by the parties involved.

Mnemonic provides a fully unwrapped list of such events in association with each NFT transfer.

Copy
Copied
// NativeTransfer represents native token transfer.
message NativeTransfer {
    // Sender address of the transfer.
    string from_address = 1;

    // Recipient address of the transfer.
    string to_address = 2;

    // Transfer value as stored on chain (e.g. in wei for Ethereum).
    string value_raw = 3;

    // Transfer value decimal normalized (e.g. in ETH for Ethereum).
    string value_normalized = 4;
}

Fungible (ERC20) Transfers

ERC20 transfers represent transfers of fungible tokens between addresses. In the context of NFTs, fungible transfers often used as payments for an NFT, and sometimes there can be multiple ERC20 tokens involved.

Mnemonic provides a full list of all ERC20 transfers with normalized values into ETH according to the exchange rate at the time of the transaction. This makes it possible to easily calculate the price of an NFT paid by the buyer with ERC20, or to get a list of all tokens that have been involved in an exchange.

Copy
Copied
message FungibleTransfer {
    // Sender of the transfer.
    string from_address = 1;

    // Recipient of the transfer.
    string to_address = 2;

    // Contract that tracks respective fungible token.
    string contract_address = 3;
    
    // Transfer value as stored on chain (e.g. uint256 for EVM-based chains).
    string value_raw = 4;

    // Value provided as decimal according to the decimal places of the
    // contract that tracks respective fungible token. The value may be `null`
    // if the contract does not provide decimals information.
    google.protobuf.StringValue value_normalized = 5;

    // Value of the fungible token converted to the Native Token by the
    // exchange rate effective on the related block minting timestamp.
    // The value may be `null` if either `value_normalized` is `null` or
    // there is no exchange rate available for the current fungible token.
    google.protobuf.StringValue value_native = 6;
}

EIP-2309 (ERC721) Consecutive Transfers

Consecutive transfers are not provided by Mnemonic at this time. However, we are collecting this data as well. If your use case requires access to these rarely used types of transfers please reach out to us, we would love to learn more about your use case.