> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mobula.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Borsh Parsing for Solana Instructions and Logs

> Understanding the three main methods to parse Borsh-encoded data from Solana transactions

# Borsh Parsing for Solana Instructions and Logs

When working with Solana transactions, you need to decode Borsh-encoded data to extract events and instruction data. This guide explains the three main approaches used in the codebase, each suited to different protocol implementations.

<Info>
  **Why it matters**: Different Solana protocols emit events and instructions in different formats. Understanding which parsing method to use is crucial for correctly extracting swap data, liquidity events, and other on-chain information.
</Info>

## Overview: Three Parsing Methods

There are three primary methods to parse Borsh-encoded data from Solana transactions:

1. **`parseLogs()`** - Parse events directly from transaction log messages
2. **`borsh.events.decode()`** - Decode events from instruction data
3. **`borsh.instruction.decode()`** - Decode instruction data itself

The method you use depends on how the protocol implements event emission. Some protocols emit events in transaction logs, while others embed events within instruction data.

***

## Method 1: parseLogs() - Event Parser from Logs

This method parses events directly from the transaction's log messages. It's the most straightforward approach when protocols emit events as log entries.

### How it works

The `EventParser` from Anchor reads the transaction's `logMessages` array and extracts structured event data based on the program's IDL.

### Example Implementation

```typescript theme={null}
import { getSolanaParser } from '../getSolanaParser.ts';

const logMessages = tx.meta?.logMessages || [];
const eventParser = getSolanaParser(PROGRAM_ID, 'event');
const parsedEvents = eventParser.parseLogs(logMessages);

for (const e of parsedEvents) {
  if (e.name === 'SwapEvent') {
    const eventData = e.data;
    // Process swap event data
  }
}
```

### When to use

* Events are emitted as log messages in the transaction
* The protocol uses Anchor's standard event emission
* You need to parse multiple events from a single transaction

### Characteristics

* Works directly with `tx.meta.logMessages`
* No need to decode instruction data manually
* Events are already structured according to the IDL
* Can parse multiple events from a single transaction

***

## Method 2: borsh.events.decode() - Decode Events from Instruction Data

This method decodes events that are embedded within instruction data. You extract the event portion from the instruction bytes and decode it separately.

### How it works

1. Decode the instruction data from base58
2. Skip the first 8 bytes (instruction discriminator)
3. Extract the remaining bytes as event data
4. Encode to base64 and decode using `borsh.events.decode()`

### Example Implementation

```typescript theme={null}
import { utils } from '@coral-xyz/anchor';
import { base64 } from '@coral-xyz/anchor/dist/cjs/utils/bytes/index.js';
import { getSolanaParser } from '../getSolanaParser.ts';

const borsh = getSolanaParser(PROGRAM_ID, 'borsh', true);

// Decode instruction data
const ixData = utils.bytes.bs58.decode(instruction.data);
// Skip first 8 bytes (instruction discriminator)
const eventData = ixData.subarray(8);
// Encode to base64 for decoding
const eventDataString = base64.encode(eventData);
// Decode the event
const event = borsh.events.decode(eventDataString);
```

### When to use

* Events are embedded within instruction data
* The protocol doesn't emit events as separate log messages
* You need to extract events from CPI (Cross-Program Invocation) calls

### Characteristics

* Requires manual extraction of event data from instruction bytes
* Must skip the instruction discriminator (first 8 bytes)
* Events are encoded within the instruction data structure
* Useful for parsing events from inner instructions

***

## Method 3: borsh.instruction.decode() - Decode Instruction Data

This method decodes the instruction itself, not events. It's used when you need to extract instruction parameters or when instructions contain the data you need directly.

### How it works

1. Decode the instruction data from base58
2. Convert to Buffer format
3. Decode using `borsh.instruction.decode()` with the appropriate format ('hex' or 'base64')

### Example Implementation

```typescript theme={null}
import { utils } from '@coral-xyz/anchor';
import { getSolanaParser } from '../getSolanaParser.ts';

const borsh = getSolanaParser(PROGRAM_ID, 'borsh', true);

// Decode instruction data
const decoded = utils.bytes.bs58.decode(instruction.data);
const ixData = Buffer.from(decoded.buffer, decoded.byteOffset, decoded.byteLength);
// Decode the instruction
const decodedInstruction = borsh.instruction.decode(ixData, 'hex') as {
  name: string;
  data: Record<string, unknown>;
};
```

### When to use

* You need instruction parameters, not events
* The protocol embeds data directly in instructions
* You're detecting instruction types (e.g., swap, deposit, withdraw)
* You need to identify pool creation or migration instructions

### Characteristics

* Decodes the entire instruction structure
* Provides instruction name and parameters
* Useful for instruction-based detection (e.g., pool creation)
* Can be combined with event decoding for comprehensive parsing

***

## Fundamental Borsh Differences

At the core Borsh level, the three methods differ in how they handle the **instruction discriminator** and **data structure**:

### Instruction Discriminator (8 bytes)

In Solana, all Anchor instructions start with an **8-byte discriminator** that identifies the instruction type. This discriminator is computed from the instruction name using SHA256.

**Structure of instruction data:**

```
[8 bytes: instruction discriminator][N bytes: instruction parameters]
```

### Differences at the Borsh Level

1. **`parseLogs()` - Event Parser**
   * **Does NOT deal with instruction data directly**
   * Events are emitted by Anchor's runtime as **structured log messages**
   * The EventParser reads these log messages (which are already formatted strings)
   * No discriminator handling needed - logs are pre-processed by Anchor

2. **`borsh.events.decode()` - Event from Instruction Data**
   * **Must skip the 8-byte instruction discriminator**
   * The event data is embedded **after** the discriminator in the instruction bytes
   * You extract bytes 8+ and decode them as a Borsh event
   * The discriminator identifies the instruction, not the event

3. **`borsh.instruction.decode()` - Full Instruction Decode**
   * **Includes the 8-byte discriminator in the decode process**
   * Decodes the entire instruction structure: discriminator + parameters
   * Returns both the instruction name (from discriminator) and parameter data
   * Used when you need instruction parameters, not events

### Why This Matters

The fundamental difference is **where the data lives** and **how Borsh deserializes it**:

* **Logs**: Events are serialized by Anchor's runtime and written as log messages. The EventParser deserializes from these pre-formatted strings.
* **Instruction data (events)**: Events are Borsh-encoded within instruction bytes, but you must skip the instruction discriminator to reach the event data.
* **Instruction data (full)**: The entire instruction (discriminator + params) is Borsh-encoded together and decoded as one structure.

## Key Differences Summary

| Method                       | Data Source                 | Borsh Structure                       | Discriminator Handling                      |
| ---------------------------- | --------------------------- | ------------------------------------- | ------------------------------------------- |
| `parseLogs()`                | `tx.meta.logMessages`       | Pre-formatted log strings             | Not applicable (logs are already processed) |
| `borsh.events.decode()`      | Instruction data (bytes 8+) | Event data only (after discriminator) | Must skip first 8 bytes                     |
| `borsh.instruction.decode()` | Instruction data (full)     | Discriminator + parameters            | Included in decode                          |

***

## Protocol Implementation Differences

Different protocols implement event emission differently:

The implementation approach depends on the protocol's architecture and how it structures its on-chain data. Always refer to the protocol's IDL to determine which method is appropriate.
