# Anchor Program Integration

> Anchor Program Integration

- Skill: `l3wi/anchor-program-integration` (Agent Skill)
- Install (CLI): `npx skillmds@latest add l3wi/anchor-program-integration`
- Raw SKILL.md: https://api.skillmd.com/api/skills/l3wi/anchor-program-integration/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: l3wi (https://skillmd.com/u/l3wi)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/l3wi/anchor-program-integration

---

# Anchor Program Integration

Use this skill when building raw Solana instructions that interact with Anchor programs, especially when bypassing Anchor's method builders.

## Key Concept: What Anchor Method Builders Do

When you use Anchor's method builder pattern:
```typescript
await program.methods['myInstruction'](params)
  .accounts({ ... })
  .remainingAccounts([...])
  .instruction();
```

Anchor automatically:
1. Serializes instruction data with the correct discriminator
2. Orders accounts according to the IDL
3. **Appends macro-injected accounts** (like `#[event_cpi]`)

## #[event_cpi] Macro

The `#[event_cpi]` macro is used for emitting events via CPI (Cross-Program Invocation).

### What It Does

When an instruction has `#[event_cpi]`, Anchor:
1. Expects two additional accounts at the END of the instruction accounts (but BEFORE remaining_accounts when using method builder)
2. These accounts are: `event_authority` PDA and `program` ID

### Account Positions

**With Anchor method builder**: Accounts are auto-appended
**Without method builder (raw instruction)**: You must add them manually at positions [N] and [N+1] where N is the number of main instruction accounts

```typescript
// For an instruction with 7 main accounts:
// [0-6] = main accounts
// [7]   = event_authority (PDA with seed "__event_authority")
// [8]   = program ID
// [9+]  = remaining_accounts
```

### Deriving event_authority

```typescript
const [eventAuthorityPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("__event_authority")],
  PROGRAM_ID  // The program that has #[event_cpi]
);
```

## Instruction Data Serialization

Anchor instructions start with an 8-byte discriminator:

```typescript
// Discriminator = SHA256("global:instruction_name").slice(0, 8)
const discriminator = crypto
  .createHash("sha256")
  .update("global:receive_message")
  .digest()
  .slice(0, 8);
```

For Borsh serialization of Vec<u8> parameters:
```typescript
// Format: [4-byte length (u32 LE)][data bytes]
buffer.writeUInt32LE(data.length, offset);
data.copy(buffer, offset + 4);
```

## Common Pitfalls

1. **Wrong event_authority position**: Must be immediately after main accounts, not at end of all accounts
2. **Wrong program for PDA derivation**: Each program has its OWN event_authority PDA
3. **Missing discriminator**: Raw instructions need the 8-byte discriminator prefix
4. **Wrong Borsh encoding**: Vec<u8> needs length prefix, not raw bytes

