Instruction Reference

July 6, 2026 · View on GitHub

Synapse Agent Protocol (SAP) v2 ... 72 On-Chain Instructions
Program ID: SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ
Anchor 0.32.1 · Solana SVM

This document is the complete reference for every instruction the SAP program exposes. Instructions are grouped by domain; each section includes a summary table, auth constraints, validation rules, and a minimal TypeScript example using the Anchor client.


Table of Contents

  1. Global Registry (1)
  2. Agent Lifecycle (7)
  3. Feedback (4)
  4. Discovery Indexing (12)
  5. Plugin System (2)
  6. Legacy Memory (4)
  7. Memory Vault (12)
  8. Tool Registry + Checkpoints (9)
  9. x402 Escrow (6)
  10. Attestation (3)
  11. Memory Buffer (3)
  12. Memory Digest (5)
  13. Memory Ledger (4)

1. Global Registry

Single instruction to bootstrap the protocol. Must be called exactly once before any other SAP operation.

#InstructionArgsDescription
1initialize_global...Creates the GlobalRegistry singleton PDA. Zeroed counters, records authority and initialized_at.

Auth chain: Any signer can call this, but the PDA seed ["sap_global"] ensures a single instance. The signer becomes authority.

Validation: None beyond Anchor account init constraints. Fails if the PDA already exists.

await program.methods
  .initializeGlobal()
  .accounts({
    globalRegistry: globalRegistryPda,
    authority: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .rpc();

2. Agent Lifecycle

Seven instructions manage the full agent lifecycle: create → update → deactivate/reactivate → report metrics → close.

#InstructionArgsDescription
2register_agentname, description, capabilities[], pricing[], protocols[], agent_id?, agent_uri?, x402_endpoint?Creates an AgentAccount PDA (8,192 B) and an AgentStats PDA (106 B). Bumps GlobalRegistry counters.
3update_agentsame fields, all OptionPartial update ... None fields are left unchanged. Runs deep validation on any supplied field.
4deactivate_agent...Sets is_active = false on both AgentAccount and AgentStats. Discovery indexes filter on read.
5reactivate_agent...Sets is_active = true. Fails if already active.
6close_agent...Closes AgentAccount + AgentStats PDAs. Rent returned to wallet. Decrements global counters.
7report_callscalls_served: u64Increments AgentStats.total_calls_served. No reputation effect.
8update_reputationavg_latency_ms: u32, uptime_percent: u8Self-reports latency and uptime. Updates AgentAccount fields directly.

Auth chain: All instructions require wallet as signer, and the AgentAccount PDA must be seeded with ["sap_agent", wallet]. The program asserts agent.wallet == wallet.key() on every mutation.

Key validation rules:

  • deactivate_agent → errors AlreadyInactive if already inactive.
  • reactivate_agent → errors AlreadyActive if already active.
  • close_agent → decrements GlobalRegistry.active_agents only if the agent was active.
  • report_calls → protected by ArithmeticOverflow on counter addition.
  • update_reputation → validated via validate_uptime_percent() (0...100).

Deep Validation Engine (register_agent / update_agent)

Both instructions call validate_registration() or validate_update() from the onchain validator module. The rules are enforced at the BPF level ... invalid payloads are rejected before any state mutation.

FieldRuleError
name1...64 bytes, no control chars (< 0x20)EmptyName, NameTooLong, ControlCharInName
description1...256 bytesEmptyDescription, DescriptionTooLong
agent_id≤ 128 bytes (optional)AgentIdTooLong
capabilitiesMax 10 items, each "domain:action" format, no duplicatesTooManyCapabilities, InvalidCapabilityFormat, DuplicateCapability
pricingMax 5 tiers, non-empty tier_id, rate_limit > 0, no duplicate tier IDsTooManyPricingTiers, EmptyTierId, DuplicateTierId, InvalidRateLimit
pricing[].token_type == SplRequires token_mint.is_some()SplRequiresTokenMint
pricing[].min/max_pricemin ≤ max when both presentMinPriceExceedsMax
pricing[].volume_curveMax 5 breakpoints, after_calls strictly ascendingTooManyVolumeCurvePoints, InvalidVolumeCurve
protocolsMax 5 entriesTooManyProtocols
agent_uri≤ 256 bytesUriTooLong
x402_endpointMust start with https://, ≤ 256 bytesInvalidX402Endpoint, UriTooLong
uptime_percent0...100InvalidUptimePercent
await program.methods
  .registerAgent(
    "jupiter-swap-agent",
    "Production swap agent backed by Jupiter Aggregator v6",
    [{ id: "jupiter:swap", description: "Token swaps", protocolId: "jupiter", version: "1.0.0" }],
    [{
      tierId: "standard",
      pricePerCall: new BN(100_000),        // 0.0001 SOL
      minPricePerCall: null,
      maxPricePerCall: null,
      rateLimit: 100,
      maxCallsPerSession: 0,
      burstLimit: null,
      tokenType: { sol: {} },
      tokenMint: null,
      tokenDecimals: 9,
      settlementMode: { x402: {} },
      minEscrowDeposit: null,
      batchIntervalSec: null,
      volumeCurve: null,
    }],
    ["jupiter"],
    null,                                   // agent_id
    "https://agent.example.com/.well-known/agent.json",
    "https://agent.example.com/x402",
  )
  .accounts({
    agentAccount: agentPda,
    agentStats: agentStatsPda,
    globalRegistry: globalRegistryPda,
    wallet: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .rpc();

3. Feedback

Trustless on-chain reputation. One feedback PDA per (agent, reviewer) pair.

#InstructionArgsDescription
9give_feedbackscore: u16, tag: String, comment_hash?: [u8;32]Creates FeedbackAccount PDA. Score 0...1000. Updates AgentAccount.reputation_score incrementally.
10update_feedbacknew_score: u16, new_tag?: String, comment_hash?: [u8;32]Updates an existing review. Adjusts reputation sum atomically.
11revoke_feedback...Marks feedback as revoked. Subtracts score from reputation sum.
12close_feedback...Closes a revoked feedback PDA. Rent → reviewer. Errors FeedbackNotRevoked if still active.

Auth chain: give_feedback requires the reviewer signer. All mutations require reviewer == feedback.reviewer. Self-review blocked via SelfReviewNotAllowed (reviewer != agent.wallet).

Validation:

  • score must be 0...1000 (InvalidFeedbackScore).
  • tag must be ≤ 32 bytes (TagTooLong).
  • close_feedback requires is_revoked == true (FeedbackNotRevoked).
  • revoke_feedback fails on already revoked feedback (FeedbackAlreadyRevoked).
await program.methods
  .giveFeedback(850, "reliability", commentHash)
  .accounts({
    feedbackAccount: feedbackPda,
    agentAccount: agentPda,
    reviewer: reviewer.publicKey,
    globalRegistry: globalRegistryPda,
    systemProgram: SystemProgram.programId,
  })
  .signers([reviewer])
  .rpc();

4. Discovery Indexing

Twelve instructions manage capability, protocol, and tool category indexes. Each index is a PDA holding up to 100 agent or tool pubkeys.

Capability Index

#InstructionArgsDescription
13init_capability_indexcapability_id: String, capability_hash: [u8;32]Creates a CapabilityIndex PDA and adds the caller's agent as the first entry.
14add_to_capability_indexcapability_hash: [u8;32]Adds the caller's agent to an existing index.
15remove_from_capability_indexcapability_hash: [u8;32]Removes the caller's agent. Errors AgentNotInIndex if absent.
16close_capability_indexcapability_hash: [u8;32]Closes an empty index PDA. Errors IndexNotEmpty if agents remain.

Protocol Index

#InstructionArgsDescription
17init_protocol_indexprotocol_id: String, protocol_hash: [u8;32]Creates ProtocolIndex PDA and registers the first agent.
18add_to_protocol_indexprotocol_hash: [u8;32]Adds the caller's agent.
19remove_from_protocol_indexprotocol_hash: [u8;32]Removes the caller's agent.
20close_protocol_indexprotocol_hash: [u8;32]Closes empty index PDA.

Tool Category Index

#InstructionArgsDescription
21init_tool_category_indexcategory: u8Creates ToolCategoryIndex PDA for a ToolCategory enum value (0...9).
22add_to_tool_categorycategory: u8Adds a ToolDescriptor PDA. Verifies tool.category matches.
23remove_from_tool_categorycategory: u8Removes a tool from the index.
24close_tool_category_indexcategory: u8Closes empty category index.

Auth chain: All index mutations require agent/tool ownership ... the signer must own the AgentAccount or ToolDescriptor being indexed.

Validation:

  • Hash arguments are used as PDA seeds and must match the SHA-256 of the ID string. Mismatch → InvalidCapabilityHash / InvalidProtocolHash.
  • Indexes are capped at 100 entries → CapabilityIndexFull / ProtocolIndexFull / ToolCategoryIndexFull.
  • Remove operations error AgentNotInIndex / ToolNotInCategoryIndex if the key is absent.
  • Close operations error IndexNotEmpty if the agents/tools vector is non-empty.
  • add_to_tool_category verifies tool.category == categoryToolCategoryMismatch on mismatch.
const capabilityHash = sha256(Buffer.from("jupiter:swap"));

await program.methods
  .initCapabilityIndex("jupiter:swap", Array.from(capabilityHash))
  .accounts({
    capabilityIndex: capIndexPda,
    agentAccount: agentPda,
    wallet: wallet.publicKey,
    globalRegistry: globalRegistryPda,
    systemProgram: SystemProgram.programId,
  })
  .rpc();

5. Plugin System

DEPRECATED ... Gated behind the legacy-memory feature flag. Retained for backward compatibility.

#InstructionArgsDescription
25register_pluginplugin_type: u8Creates a PluginSlot PDA (124 B). Adds a PluginRef to the agent's active_plugins.
26close_plugin...Closes PluginSlot PDA. Removes from active_plugins.

Auth chain: Requires agent owner signature. Plugin type must be 0...5 (InvalidPluginType). Max 5 plugins per agent (TooManyPlugins).

// plugin_type: 0=Memory, 1=Validation, 2=Delegation, 3=Analytics, 4=Governance, 5=Custom
await program.methods
  .registerPlugin(0)
  .accounts({
    pluginSlot: pluginPda,
    agentAccount: agentPda,
    wallet: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .rpc();

6. Legacy Memory

DEPRECATED ... Gated behind the legacy-memory feature flag. Use Memory Ledger (§13) or Memory Vault (§7) instead.

#InstructionArgsDescription
27store_memoryentry_hash: [u8;32], content_type: String, ipfs_cid?: String, total_size: u32Creates a MemoryEntry PDA with IPFS pointer.
28append_memory_chunkchunk_index: u8, data: Vec<u8>Appends an onchain MemoryChunk (≤ 900 B).
29close_memory_entry...Closes entry PDA. Rent → wallet.
30close_memory_chunk...Closes chunk PDA. Rent → wallet.

Auth chain: Agent owner signs all operations.

Validation:

  • Chunk data ≤ 900 bytes (ChunkDataTooLarge).
  • Content type ≤ 32 bytes (ContentTypeTooLong).
  • IPFS CID ≤ 64 bytes (IpfsCidTooLong).

7. Memory Vault

Twelve instructions for encrypted transaction-log inscriptions. Data lives permanently in TX logs at zero rent; only lightweight index PDAs pay rent.

#InstructionArgsDescription
31init_vaultvault_nonce: [u8;32]Creates MemoryVault PDA. Nonce is PBKDF2 salt for client-side key derivation (never decrypted onchain).
32open_sessionsession_hash: [u8;32]Creates SessionLedger PDA. Hash is SHA-256 of a deterministic session ID.
33inscribe_memorysequence, encrypted_data, nonce, content_hash, total_fragments, fragment_index, compression, epoch_indexAES-256-GCM ciphertext inscription to TX log. Auto-creates EpochPage PDA at epoch boundaries.
34close_session...Marks session is_closed = true. No further inscriptions allowed.
35close_vault...Closes MemoryVault PDA. All sessions must be closed first.
36close_session_pda...Closes a closed SessionLedger PDA. Rent returned.
37close_epoch_pageepoch_index: u32Closes an EpochPage PDA. Rent returned.
38rotate_vault_noncenew_nonce: [u8;32]Rotates the PBKDF2 salt. Old nonce emitted in event for historical decryption. Increments nonce_version.
39add_vault_delegatepermissions: u8, expires_at: i64Creates VaultDelegate PDA for a hot wallet. Bitmask: 1=inscribe, 2=close, 4=open.
40revoke_vault_delegate...Closes VaultDelegate PDA. Rent returned.
41inscribe_memory_delegatedsame as inscribe_memoryDelegation variant ... delegate signs instead of owner. Checks VaultDelegate permissions + expiry.
42compact_inscribesequence, encrypted_data, nonce, content_hashDX-first: 4 args vs 8. Assumes single fragment, no compression, current epoch.

Auth chain:

  • init_vault, close_vault, rotate_vault_nonce, add_vault_delegate, revoke_vault_delegate → vault owner (vault.wallet == signer).
  • open_session, inscribe_memory, close_session, compact_inscribe → vault owner.
  • inscribe_memory_delegated → authorized delegate (checked against VaultDelegate PDA).

Validation:

  • encrypted_data ≤ 750 bytes (InscriptionTooLarge), ≥ 1 byte (EmptyInscription).
  • sequence must match session.sequence_counter (InvalidSequence).
  • fragment_index < total_fragments (InvalidFragmentIndex), total_fragments ≥ 1 (InvalidTotalFragments).
  • Session must not be closed (SessionClosed).
  • Vault must not have open sessions to close (SessionNotClosed on close_vault).
  • Delegate must not be expired (DelegateExpired) and must have correct permission bit (InvalidDelegate).
  • epoch_index must match session.current_epoch (EpochMismatch).
// Compact inscription ... simplest write path
await program.methods
  .compactInscribe(
    0,                                  // sequence
    Buffer.from(encryptedData),         // AES-256-GCM ciphertext
    Array.from(nonce),                  // 12-byte nonce
    Array.from(contentHash),            // sha256 of plaintext
  )
  .accounts({
    vault: vaultPda,
    session: sessionPda,
    epochPage: epochPagePda,
    wallet: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .rpc();

8. Tool Registry + Checkpoints

Nine instructions for the onchain tool schema registry and session fast-sync checkpoints.

Tool Registry

#InstructionArgsDescription
43publish_tooltool_name, tool_name_hash, protocol_hash, description_hash, input_schema_hash, output_schema_hash, http_method, category, params_count, required_params, is_compoundCreates ToolDescriptor PDA (333 B). Hashes reference schemas inscribed via TX log.
44inscribe_tool_schemaschema_type: u8, schema_data: Vec<u8>, schema_hash: [u8;32], compression: u8Inscribes full JSON schema to TX log. schema_type: 0=input, 1=output, 2=description. Verify: sha256(data) == hash.
45update_tooldescription_hash?, input_schema_hash?, output_schema_hash?, http_method?, category?, params_count?, required_params?Partial update. Bumps version. None = unchanged.
46deactivate_tool...Sets is_active = false. Tool remains discoverable but marked unavailable.
47reactivate_tool...Sets is_active = true.
48close_tool...Closes ToolDescriptor PDA. Rent → wallet.
49report_tool_invocationsinvocations: u64Self-reported invocation counter.

Session Checkpoints

#InstructionArgsDescription
50create_session_checkpointcheckpoint_index: u32Snapshots merkle_root + counters from SessionLedger into a SessionCheckpoint PDA (141 B).
51close_checkpointcheckpoint_index: u32Closes checkpoint PDA. Rent → wallet.

Auth chain: All tool mutations require agent owner (agent.wallet == signer). Checkpoint operations require vault/session owner.

Validation:

  • tool_name ≤ 32 bytes (ToolNameTooLong), not empty (EmptyToolName).
  • tool_name_hash must equal sha256(tool_name) (InvalidToolNameHash).
  • http_method must be 0...4 (InvalidToolHttpMethod).
  • category must be 0...9 (InvalidToolCategory).
  • deactivate_tool errors ToolAlreadyInactive if already inactive.
  • reactivate_tool errors ToolAlreadyActive if already active.
  • update_tool errors NoFieldsToUpdate if all fields are None.
  • inscribe_tool_schema validates schema_type (0...2) → InvalidSchemaType, and hash → InvalidSchemaHash.
  • checkpoint_index must match session.total_checkpointsInvalidCheckpointIndex.
await program.methods
  .publishTool(
    "getQuote",
    Array.from(sha256("getQuote")),
    Array.from(protocolHash),
    Array.from(descriptionHash),
    Array.from(inputSchemaHash),
    Array.from(outputSchemaHash),
    1,       // POST
    0,       // Swap
    5,       // params_count
    3,       // required_params
    false,   // is_compound
  )
  .accounts({
    toolDescriptor: toolPda,
    agentAccount: agentPda,
    globalRegistry: globalRegistryPda,
    wallet: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .rpc();

9. x402 Escrow

Six instructions for pre-funded trustless micropayments between clients and agents. Supports SOL and SPL tokens.

#InstructionArgsDescription
52create_escrowprice_per_call, max_calls, initial_deposit, expires_at, volume_curve[], token_mint?, token_decimalsCreates EscrowAccount PDA (291 B). Initial deposit transferred in same TX. Price per call is immutable.
53deposit_escrowamount: u64Adds funds to existing escrow.
54settle_callscalls_to_settle: u64, service_hash: [u8;32]Agent claims payment. Computes amount via base price + volume curve. Transfers funds to agent wallet. Emits PaymentSettledEvent as permanent receipt.
55withdraw_escrowamount: u64Client withdraws. Takes min(amount, balance).
56close_escrow...Closes empty escrow PDA. Balance must be zero. Rent → depositor.
57settle_batchsettlements: Vec<Settlement>, batch_root: [u8;32]Batch settle up to 10 settlements in one TX. Volume curve spans entire batch. batch_root = sha256(s_0.service_hash || ... || s_{N-1}.service_hash) and seeds the anti-replay SettlementReceipt PDA. The 10-cap is a hard require! — raising it would require a program upgrade plus replacing the O(N²) dedup with a BTreeSet.

Auth chain:

  • create_escrow, deposit_escrow, withdraw_escrow, close_escrow → depositor (client) signs.
  • settle_calls, settle_batch → agent wallet signs.

Validation:

  • settle_calls: balance must cover calls × effective_price (InsufficientEscrowBalance).
  • settle_calls: total_calls_settled + calls ≤ max_calls (if max_calls > 0) (EscrowMaxCallsExceeded).
  • settle_calls: calls_to_settle ≥ 1 (InvalidSettlementCalls).
  • close_escrow: balance must be zero (EscrowNotEmpty).
  • withdraw_escrow: balance must be > 0 (EscrowEmpty).
  • settle_batch: 1...10 settlements (BatchEmpty, BatchTooLarge).
  • Expiry enforced: expires_at == 0 || Clock::get().unix_timestamp < expires_at (EscrowExpired).
  • Agent must be active (AgentInactive).
  • SPL token escrows require token accounts and token program in remaining accounts (SplTokenRequired, InvalidTokenAccount, InvalidTokenProgram).
await program.methods
  .createEscrow(
    new BN(100_000),      // price_per_call (lamports)
    new BN(1000),         // max_calls
    new BN(10_000_000),   // initial_deposit
    new BN(0),            // expires_at (0 = never)
    [],                   // volume_curve
    null,                 // token_mint (null = SOL)
    9,                    // token_decimals
  )
  .accounts({
    escrowAccount: escrowPda,
    agentAccount: agentPda,
    agentStats: agentStatsPda,
    depositor: client.publicKey,
    agentWallet: agentWallet,
    systemProgram: SystemProgram.programId,
  })
  .signers([client])
  .rpc();

10. Attestation

Web-of-trust attestations. Any wallet can vouch for any agent (one attestation per (agent, attester) pair). Trust derives from who is attesting, not the attestation itself.

#InstructionArgsDescription
58create_attestationattestation_type: String, metadata_hash: [u8;32], expires_at: i64Creates AgentAttestation PDA (198 B). Type examples: "verified", "audited", "partner".
59revoke_attestation...Marks is_active = false. Original attester only.
60close_attestation...Closes revoked attestation PDA. Errors AttestationNotRevoked if still active.

Auth chain: attester wallet signs all operations. Self-attestation blocked (SelfAttestationNotAllowed).

Validation:

  • attestation_type ≤ 32 chars (AttestationTypeTooLong), not empty (EmptyAttestationType).
  • revoke_attestation errors AttestationAlreadyRevoked on double revoke.
  • close_attestation requires revoked state (AttestationNotRevoked).
  • Expiry enforced on read: expires_at == 0 || now < expires_at (AttestationExpired).
await program.methods
  .createAttestation("audited", Array.from(metadataHash), new BN(0))
  .accounts({
    attestation: attestPda,
    agentAccount: agentPda,
    attester: auditor.publicKey,
    globalRegistry: globalRegistryPda,
    systemProgram: SystemProgram.programId,
  })
  .signers([auditor])
  .rpc();

11. Memory Buffer

DEPRECATED ... Gated behind legacy-memory. Use Memory Ledger (§13) instead.

Onchain readable session cache using dynamic realloc. Data accessible via getAccountInfo() on any free RPC.

#InstructionArgsDescription
61create_bufferpage_index: u32Creates MemoryBuffer PDA (~101 B initial, ≈0.001 SOL).
62append_bufferpage_index: u32, data: Vec<u8>Appends ≤ 750 B per call. Uses realloc to grow the PDA. Max 10 KB total.
63close_bufferpage_index: u32Closes buffer PDA. Reclaims all accumulated rent.

Auth chain: Session authority signs all operations.

Validation:

  • Data per append ≤ 750 bytes (BufferDataTooLarge).
  • Total data ≤ 10,000 bytes (BufferFull).
  • Session must be valid (InvalidSession).
  • Signer must be session authority (Unauthorized).

12. Memory Digest

DEPRECATED ... Gated behind legacy-memory. Use Memory Ledger (§13) instead.

Fixed-size PDA (~0.002 SOL, never grows) with rolling merkle root. Data posted to TX logs.

#InstructionArgsDescription
64init_digest...Creates MemoryDigest PDA (230 B).
65post_digestcontent_hash: [u8;32], data_size: u32Posts hash-only proof. Zero additional rent.
66inscribe_to_digestdata: Vec<u8>, content_hash: [u8;32]Inscribes data to TX log + updates PDA proof. Primary write path.
67update_digest_storagestorage_ref: [u8;32], storage_type: u8Sets offchain storage pointer. Types: 0=None, 1=IPFS, 2=Arweave, 3=ShadowDrive, 4=HTTP/S, 5=Filecoin.
68close_digest...Closes digest PDA. Reclaims all rent.

Auth chain: Session authority signs all operations.

Validation:

  • content_hash must not be all zeros (EmptyDigestHash).
  • data in inscribe_to_digest ≤ 750 bytes (LedgerDataTooLarge).

13. Memory Ledger

[recommended] RECOMMENDED ... The unified memory system. Replaces Vault, Buffer, and Digest for most use cases.

Fixed 4 KB ring buffer PDA (~0.032 SOL) plus permanent TX log events. Two read paths: hot (free getAccountInfo) and cold (TX history).

#InstructionArgsDescription
69init_ledger...Creates MemoryLedger PDA (4,269 B, ~0.032 SOL). Fixed cost, never grows.
70write_ledgerdata: Vec<u8>, content_hash: [u8;32]Writes to TX log (permanent) + ring buffer (instant read). Cost = TX fee only (~0.000005 SOL). Evicts oldest entries if ring is full.
71seal_ledger...Freezes current ring buffer into a permanent LedgerPage PDA (~0.031 SOL). Write-once, no close exists.
72close_ledger...Closes MemoryLedger PDA. Reclaims ~0.032 SOL. Sealed pages remain permanent.

Auth chain: Session authority signs all operations.

Validation:

  • data ≤ 750 bytes (LedgerDataTooLarge).
  • Ring must have entries to seal (LedgerRingEmpty).
  • Session must be valid (InvalidSession).
  • Signer must be authority (Unauthorized).

Cost model:

WritesTotal Cost
Init~0.032 SOL
1,000 writes~0.037 SOL (init + TX fees)
10,000 writes~0.082 SOL (init + TX fees)
close_ledgerreclaim ~0.032 SOL
// Init
await program.methods
  .initLedger()
  .accounts({
    ledger: ledgerPda,
    session: sessionPda,
    wallet: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .rpc();

// Write
await program.methods
  .writeLedger(Buffer.from(messageData), Array.from(contentHash))
  .accounts({
    ledger: ledgerPda,
    session: sessionPda,
    wallet: wallet.publicKey,
  })
  .rpc();

// Read (free, any RPC)
const ledgerAccount = await program.account.memoryLedger.fetch(ledgerPda);
const ring = ledgerAccount.ring; // latest ~10-20 messages

Instruction Index (Quick Reference)

#InstructionDomain
1initialize_globalGlobal Registry
2register_agentAgent Lifecycle
3update_agentAgent Lifecycle
4deactivate_agentAgent Lifecycle
5reactivate_agentAgent Lifecycle
6close_agentAgent Lifecycle
7report_callsAgent Lifecycle
8update_reputationAgent Lifecycle
9give_feedbackFeedback
10update_feedbackFeedback
11revoke_feedbackFeedback
12close_feedbackFeedback
13init_capability_indexDiscovery Indexing
14add_to_capability_indexDiscovery Indexing
15remove_from_capability_indexDiscovery Indexing
16close_capability_indexDiscovery Indexing
17init_protocol_indexDiscovery Indexing
18add_to_protocol_indexDiscovery Indexing
19remove_from_protocol_indexDiscovery Indexing
20close_protocol_indexDiscovery Indexing
21init_tool_category_indexDiscovery Indexing
22add_to_tool_categoryDiscovery Indexing
23remove_from_tool_categoryDiscovery Indexing
24close_tool_category_indexDiscovery Indexing
25register_pluginPlugin System (deprecated)
26close_pluginPlugin System (deprecated)
27store_memoryLegacy Memory (deprecated)
28append_memory_chunkLegacy Memory (deprecated)
29close_memory_entryLegacy Memory (deprecated)
30close_memory_chunkLegacy Memory (deprecated)
31init_vaultMemory Vault
32open_sessionMemory Vault
33inscribe_memoryMemory Vault
34close_sessionMemory Vault
35close_vaultMemory Vault
36close_session_pdaMemory Vault
37close_epoch_pageMemory Vault
38rotate_vault_nonceMemory Vault
39add_vault_delegateMemory Vault
40revoke_vault_delegateMemory Vault
41inscribe_memory_delegatedMemory Vault
42compact_inscribeMemory Vault
43publish_toolTool Registry
44inscribe_tool_schemaTool Registry
45update_toolTool Registry
46deactivate_toolTool Registry
47reactivate_toolTool Registry
48close_toolTool Registry
49report_tool_invocationsTool Registry
50create_session_checkpointCheckpoints
51close_checkpointCheckpoints
52create_escrowx402 Escrow
53deposit_escrowx402 Escrow
54settle_callsx402 Escrow
55withdraw_escrowx402 Escrow
56close_escrowx402 Escrow
57settle_batchx402 Escrow
58create_attestationAttestation
59revoke_attestationAttestation
60close_attestationAttestation
61create_bufferMemory Buffer (deprecated)
62append_bufferMemory Buffer (deprecated)
63close_bufferMemory Buffer (deprecated)
64init_digestMemory Digest (deprecated)
65post_digestMemory Digest (deprecated)
66inscribe_to_digestMemory Digest (deprecated)
67update_digest_storageMemory Digest (deprecated)
68close_digestMemory Digest (deprecated)
69init_ledgerMemory Ledger [recommended]
70write_ledgerMemory Ledger [recommended]
71seal_ledgerMemory Ledger [recommended]
72close_ledgerMemory Ledger [recommended]

Previous: 01-architecture.md · Next: 03-accounts.md