# Writing and reading memos

### Writing a memo

This is how you would include a json object in the memo field of a transaction.

```javascript
// Create the JSON object you want to include in the memo
  const memoData = {
      invoice_id: '12345',
      description: 'Coffee and Milk',
      date: '2024-07-02'
  };

  // Convert JSON object to a string and then to hex
  const memoJson = JSON.stringify(memoData);
  const memoHex = Buffer.from(memoJson, 'utf8').toString('hex');

  // Create the Memo field
  const memo = {
      Memo: {
          MemoData: memoHex
      }
  };

  const tx = {
    TransactionType: "Payment",
    Account: wallet1.classicAddress,
    Destination: wallet2.classicAddress,
    Amount: "1234",
    Memos: [memo]
  };

  const result = await client.submitAndWait(tx, {
    autofill: true,
    wallet: wallet1,
  });
  console.log(result)
```

### Decoding memos

To decode memos from a transaction, we retrieve the memo components and decode the hexadecimal data to a string, and then parse them.

Create this file in your project and import it as needed, when you are processing the transaction data.

{% code title="parseMemo.ts" %}

```javascript
export const parseMemo = (memos) => {
  let report = {};
  if (memos && memos.length > 0) {
    for (const memo of memos) {
      if (memo.Memo.MemoData) {
        // Decode the hexadecimal memo data to a string
        const memoDataHex = memo.Memo.MemoData;
        const memoDataJson = Buffer.from(memoDataHex, "hex").toString("utf8");

        // Parse the JSON string into a JavaScript object
        const memoDataObject = JSON.parse(memoDataJson);

        // console.log('Decoded memo data:', memoDataObject)
        report = { ...report, ...memoDataObject };
      } else {
        console.log("No MemoData found.");
      }
    }
    return report;
  } else {
    console.log("No memos found in the transaction.");
  }
};

export default parseMemo
```

{% endcode %}

### Putting it all together

Here is an example of a fully fledged transaction listener that can parse the memos from the transaction we created above.

{% hint style="info" %}
replace the wallet address with the destination of the original transaction
{% endhint %}

{% code title="index.ts" %}

```javascript
import xrpl from "xrpl";
import { parseMemo } from "./parseMemo";

const serverURL = "wss://s.altnet.rippletest.net:51233"; // For testnet
const walletAddress = "r...";

const main = async () => {
  const client = new xrpl.Client(serverURL);
  await client.connect();

  // do something useful
  const subscriptionRequest = {
    command: "subscribe",
    accounts: [walletAddress],
  };

  await client.request(subscriptionRequest);
  console.log(`Subscribed to transactions for account: ${walletAddress}`);

  // Event listener for incoming transactions
  client.on("transaction", (transaction) => {
    console.log("Transaction:", transaction);
    const parsedMemos = parseMemo(transaction.transaction.Memos);
    console.log("Parsed memo:", parsedMemos);
  });

  // Event listener for errors
  client.on("error", (error) => {
    console.error("Error:", error);
  });

  // end
  // keep open
  console.log("listening...");
};

main()
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xrpl-commons.org/xrpl-basics/writing-and-reading-memos.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
