Classify Single Transaction

Get a complete, fully interpreted view of what happened in any given transaction.

We just saw how you can Preview a transaction before it happens, and get a highly-enriched object with a transaction type, description, tagged asset transfers, and more.

Now, let's see how you can get that same object, but for a transaction that already happened.

In Noves slang, we call this "classifying" a transaction.

Let's start with a simple example: you already have the transaction hash and you want to pull it for the user.

Here's how you can do that using the /tx endpoint:

const axios = require('axios');

const NOVES_API_KEY = process.env.NOVES_API_KEY;

async function getTransaction(chain, txHash, viewAsAccountAddress) {
    const baseURL = 'https://translate.noves.fi';
    const endpoint = `${baseURL}/evm/${chain}/tx/${txHash}`;

    try {
        const response = await axios.get(endpoint, {
            params: {
                viewAsAccountAddress: viewAsAccountAddress,
            },
            headers: {
                apiKey: NOVES_API_KEY,
            },
        });
        return response.data;
    } catch (error) {
        console.error('Error fetching transaction:', error);
        return null;
    }
}

// Replace with the desired chain
const chain = 'polygon';

// Replace with the target wallet address
const account = '0x9B1054d24dC31a54739B6d8950af5a7dbAa56815';

// Set the transaction hash
const txHash =
    '0xa29e3bb51a17967402663d01f28821dd8282c82dc49e91a598a9b4749af7c08d';

getTransaction(chain, txHash, account).then((data) => {
    console.log(JSON.stringify(data, null, 2));
});

We'll get an output like this:

{
    "txTypeVersion": 2,
    "chain": "polygon",
    "accountAddress": "0x9B1054d24dC31a54739B6d8950af5a7dbAa56815",
    "classificationData": {
        "type": "removeLiquidity",
        "source": {
            "type": "human"
        },
        "description": "Removed 109,853.84 USDC and 97,129.57 agEUR from a liquidity pool.",
        "sent": [
            {
                "action": "lpTokenBurned",
                "from": {
                    "name": "This wallet",
                    "address": "0x9B1054d24dC31a54739B6d8950af5a7dbAa56815"
                },
                "to": {
                    "name": "Quickswap: v2 pool",
                    "address": "0x82A54e66c05FCd555ADAE593848a4257C9e51AD9"
                },
                "amount": "0.103002419939394076",
                "token": {
                    "symbol": "UNI-V2",
                    "name": "Uniswap V2",
                    "decimals": 18,
                    "address": "0x82a54e66c05fcd555adae593848a4257c9e51ad9"
                }
            },
            {
                "action": "paidGas",
                "from": {
                    "name": "This wallet",
                    "address": "0x9B1054d24dC31a54739B6d8950af5a7dbAa56815"
                },
                "to": {
                    "name": null,
                    "address": null
                },
                "amount": "0.006211997",
                "token": {
                    "symbol": "MATIC",
                    "name": "Matic Token",
                    "decimals": 18,
                    "address": "MATIC"
                }
            }
        ],
        "received": [
            {
                "action": "liquidityRemoved",
                "from": {
                    "name": "Quickswap: v2 pool",
                    "address": "0x82A54e66c05FCd555ADAE593848a4257C9e51AD9"
                },
                "to": {
                    "name": "This wallet",
                    "address": "0x9B1054d24dC31a54739B6d8950af5a7dbAa56815"
                },
                "amount": "109853.843065",
                "token": {
                    "symbol": "USDC",
                    "name": "USD Coin (PoS)",
                    "decimals": 6,
                    "address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174"
                }
            },
            {
                "action": "liquidityRemoved",
                "from": {
                    "name": "Quickswap: v2 pool",
                    "address": "0x82A54e66c05FCd555ADAE593848a4257C9e51AD9"
                },
                "to": {
                    "name": "This wallet",
                    "address": "0x9B1054d24dC31a54739B6d8950af5a7dbAa56815"
                },
                "amount": "97129.565093482015299955",
                "token": {
                    "symbol": "agEUR",
                    "name": "agEUR",
                    "decimals": 18,
                    "address": "0xe0b52e49357fd4daf2c15e02058dce6bc0057db4"
                }
            }
        ]
    },
    "rawTransactionData": {
        "transactionHash": "0xa29e3bb51a17967402663d01f28821dd8282c82dc49e91a598a9b4749af7c08d",
        "fromAddress": "0x9B1054d24dC31a54739B6d8950af5a7dbAa56815",
        "toAddress": "0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff",
        "blockNumber": 24982518,
        "gas": 255438,
        "gasPrice": 31000000000,
        "transactionFee": {
            "amount": 6211997000000000,
            "token": {
                "symbol": "MATIC",
                "decimals": 18
            }
        },
        "timestamp": 1644955198
    }
}

Similar to the Preview endpoint, though there's a bunch of data included here, we can simply grab the most useful fields for an account history display:

  • type
  • description
  • timestamp

And we can display those as-is (without the need for further processing or complex logic) in a basic React component:

import React from 'react';

const TransactionDetails = ({ transaction }) => {
    const { type, description } = transaction.classificationData;
    const { timestamp } = transaction.rawTransactionData;

    const date = new Date(timestamp * 1000).toLocaleString();

    return (
        <div className="transaction-item">
            <h4>Transaction Type: {type}</h4>
            <p>Description: {description}</p>
            <p>Date: {date}</p>
        </div>
    );
};

export default TransactionDetails;