Adding Metadata to TransferContract in klever/sdk-node

Hi team!

I’m working on a Node.js script using @klever/sdk-node@2.4.1 and need to add metadata (e.g., “Reward for delegation to klv15…”) to the data field of a TransferContract transaction, so it shows as a readable string on kleverscan.org. Could you share the best way to do this?

Can you provide a working code example for adding metadata to a TransferContract?
Thanks for your help!

Hi @Sovkosov_Ignat :waving_hand:

To include readable metadata (e.g., “Reward for delegation to klv15…”) in the data field of a TransferContract so it displays correctly on kleverscan.org, you can use either online or offline transaction building methods, depending on your setup.


:white_check_mark: 1. Online Build using account.quickSend()

If you’re signing and sending the transaction directly using an initialized account, you can add the metadata as a second parameter in quickSend(). Here’s a working example:

import { Account, utils, TransactionType } from "@klever/sdk-node";

utils.setProviders({
  api: "https://api.testnet.klever.org",
  node: "https://node.testnet.klever.org",
});

const privateKey = "yourPrivateKeyHere"; // Replace with your actual private key

const transferPayload = {
  amount: 1 * 10 ** 6,
  receiver: "klv1nnu8d0mcqnxunqyy5tc7kj7vqtp4auy4a24gv35fn58n2qytl9xsx7wsjl",
  kda: "KLV",
};

const contracts = [
  {
    type: TransactionType.Transfer,
    payload: transferPayload,
  },
];

const account = new Account(privateKey);
await utils.accountsReady([account]);

// ✅ Add your metadata here:
const res1 = account.quickSend(contracts, ["Reward for delegation to klv15..."]);

const txRes = await utils.transactionsProcessed([res1]);

console.log(txRes);

:white_check_mark: 2. Offline Build using Raw Transaction (Advanced)

If you’re building and signing the transaction offline, you can manually push the encoded metadata string into the tx.data.RawData.Data field before signing.

Here’s a simplified working example:

import {
  Account,
  Contracts,
  TXContract_ContractType,
  Transaction,
  utils,
} from "@klever/sdk-node";

const chainIDs = {
  TESTNET: "109",
  MAINNET: "108",
};

const initTest = async () => {
  try {
    utils.setProviders({
      api: "https://api.testnet.klever.org",
      node: "https://node.testnet.klever.org",
    });

    const enc = new TextEncoder();

    const privateKey = "your_private_key_here"; // replace with your private key
    const senderDecoded = await utils.decodeAddress(
      "your_address_here" // replace with your address
    );

    const account = new Account(privateKey);
    await account.ready;

    const nonce = account.getNonce();

    const metadata = enc.encode("KLEVER TEST");

    const BandwidthFee = 1000000 + metadata.length * 4000;

    const tx = new Transaction({
      Sender: senderDecoded,
      Nonce: nonce,
      BandwidthFee: BandwidthFee,
      KAppFee: 500000, // KApp fee for the transfer transaction
      Version: 1,
      ChainID: enc.encode(chainIDs.TESTNET),
    });
    tx.data.RawData?.Data?.push(metadata);

    const transfer = Contracts.TransferContract.fromPartial({
      ToAddress: await utils.decodeAddress(
        "klv1fr724pjdjp3l8unuvgda0k6vt06d875hj7t5ggrxymzcg3jcveysejzljc"
      ),
      AssetID: enc.encode("KLV"),
      Amount: 1 * 10 ** 6,
    });

    tx.addContract(TXContract_ContractType.TransferContractType, transfer);

    await tx.sign(privateKey);

    const res1 = await utils.broadcastTransactions([tx.toBroadcast()]);

    console.log(res1);
  } catch (e) {
    console.log("error", e);
  }
};
initTest();

:brain: Notes:

  • Each character increases the bandwidth cost slightly, so keep an eye on BandwidthFee.
  • Once broadcast, the metadata will be viewable in kleverscan.org under the “data” field of the transaction.

Let us know if you need help adapting this to your specific case!

2 Likes

A post was split to a new topic: SDK endpoints with wrong domain hardcoded