SAP DOCv0.20.0
Explorer

Transaction Parsing

How the explorer decodes SAP transactions, instructions, events, and error codes from on-chain data. SDK v0.20.0 aligned.

Transaction Parsing

SDK Version: v0.20.0
Program ID: SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ

The SAP Explorer decodes raw Solana transactions into human-readable protocol operations using the SAP program IDL. This page explains how instruction decoding, event parsing, and error resolution work.


Instruction Decoding

Every SAP transaction contains one or more instructions targeting the SAP program. The explorer uses the Anchor IDL to decode:

  1. Instruction discriminator: The first 8 bytes of instruction data identify which instruction was called
  2. Instruction arguments: Remaining bytes are deserialized according to the IDL schema
  3. Account keys: Matched to the IDL's account definitions to show roles (agent, vault, escrow, etc.)

Example Decoded Instruction

{
  "instructionType": "x402_settle",
  "program": "SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ",
  "accounts": {
    "escrow": "8xK9...3mPq",
    "merchant": "7yH2...9nLw",
    "depositor": "5zR4...2kTx"
  },
  "args": {
    "callsToSettle": 47,
    "totalAmount": "470000"
  },
  "innerInstructions": [
    {
      "program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ys62CLVQ",
      "instructionType": "transfer",
      "amount": "470000",
      "from": "8xK9...3mPq",
      "to": "7yH2...9nLw"
    }
  ]
}

Event Parsing

SAP instructions emit typed events through Anchor's event system. Events appear in the transaction's program log messages and follow this pattern:

Program log: <base64-encoded event data>

The explorer's EventParser decodes these into typed objects using the IDL's event definitions.

Common Events (v0.20.0)

EventEmitted ByDescription
AgentRegisteredregister_agent_v2New agent created
AgentUpdatedupdate_agentAgent metadata changed
AgentClosedclose_agentAgent account closed
EscrowOpenedopen_escrowNew escrow initialized
EscrowFundeddepositAdditional funds deposited
EscrowSettledx402_settleFunds transferred to merchant
EscrowClosedclose_escrowEscrow account closed
DisputeOpeneddispute_openDispute filed on escrow
DisputeResolveddispute_resolveDispute settled, funds distributed
VaultInitializedinit_vaultMemory vault created
SessionOpenedopen_sessionNew session started
SessionClosedclose_sessionSession marked closed
MemoryWritteninscribeData written to ring buffer
LedgerSealedseal_ledgerRing buffer page archived
ToolPublishedpublish_toolNew tool descriptor created
ToolUpdatedupdate_toolTool metadata changed
ToolDeactivateddeactivate_toolTool marked inactive
FeedbackGivengive_feedbackRating submitted
FeedbackUpdatedupdate_feedbackRating revised
AttestationCreatedcreate_attestationWeb-of-trust statement
AttestationRevokedrevoke_attestationAttestation revoked

Event Structure

interface SapEvent {
  name: string;              // e.g. "EscrowSettled"
  data: Record<string, any>; // Typed event payload
  slot: number;              // Solana slot number
  signature: string;         // Transaction signature
  timestamp: number;         // Unix timestamp (ms)
}

Error Codes

When a transaction fails, the SAP program returns a numeric error code starting at 6000. The explorer maps these codes to human-readable messages using the IDL's error definitions.

Error Code Reference (v0.20.0)

CodeNameDomainDescription
6000AgentAlreadyRegisteredAgentWallet already has an agent
6001AgentNotFoundAgentNo agent PDA for this wallet
6002AgentNotActiveAgentAgent is deactivated
6003InvalidAgentNameAgentName exceeds 32 bytes or empty
6004InvalidCapabilitiesAgentCapabilities array empty
6005InvalidPricingAgentPricing configuration invalid
6006AgentCloseFailedAgentCannot close with open escrows
6007AgentUpdateFailedAgentUpdate validation failed
6008AgentValidationFailedAgentGeneral validation error
6009EscrowExpiredEscrowPast expiresAt timestamp
6010EscrowInsufficientBalanceEscrowBalance too low for settlement
6011EscrowNotActiveEscrowEscrow is closed or disputed
6012EscrowAlreadyExistsEscrowDuplicate escrow for pair
6013EscrowOpenFailedEscrowInitialization failed
6014EscrowCloseFailedEscrowCannot close with pending disputes
6015VaultAlreadyInitializedVaultVault with this nonce exists
6016VaultNotInitializedVaultVault does not exist
6017SessionClosedVaultSession is closed, no writes
6018DataExceedsMaxWriteSizeVaultData > 750 bytes
6019RingBufferOverflowVaultRing buffer full, seal first
6020InvalidEpochIndexVaultEpoch index mismatch
6021DelegateExpiredVaultVault delegate expired
6022DisputeAlreadyFiledDisputeDispute exists for this escrow
6023DisputeWindowExpiredDisputeFiling window has passed
6024DisputeResolutionFailedDisputeResolution validation failed
6025InvalidDisputeReasonDisputeReason exceeds max length
6030ToolAlreadyPublishedToolsTool name already in use
6031ToolNotFoundToolsTool PDA does not exist
6032InvalidSchemaToolsJSON Schema validation failed
6033ToolUpdateFailedToolsUpdate validation failed
6040FeedbackAlreadyGivenFeedbackReviewer already gave feedback
6041FeedbackNotFoundFeedbackFeedback PDA does not exist
6042InvalidFeedbackScoreFeedbackScore outside 1-1000 range
6043FeedbackRevokeFailedFeedbackRevoke validation failed
6050AttestationExistsAttestationAttester-subject pair exists
6051AttestationNotFoundAttestationNo attestation found
6052InvalidAttestationTypeAttestationType exceeds max length
6053AttestationRevokeFailedAttestationOnly attester can revoke

Error Pattern Matching

// Example: Parse error from transaction simulation
function parseSapError(logs: string[]): SapError | null {
  const errorPattern = /Program failed: custom program error: (\d+)/;
  
  for (const log of logs) {
    const match = log.match(errorPattern);
    if (match) {
      const code = parseInt(match[1], 10);
      return SAP_ERROR_MAP[code] || { code, message: "Unknown error" };
    }
  }
  return null;
}

const SAP_ERROR_MAP: Record<number, { code: number; message: string }> = {
  6000: { code: 6000, message: "Agent already registered" },
  6001: { code: 6001, message: "Agent not found" },
  // ... full map in explorer utils
};

Inner Instructions

SAP instructions may trigger inner instructions, particularly for:

Inner ProgramTriggered ByPurpose
System Programopen_escrow, close_escrowSOL transfers, account creation
Token Programx402_settle, depositSPL token transfers
Associated TokenToken operationsATA creation/validation

The explorer displays these as nested operations within the parent instruction, showing the full execution tree.


Transaction Signature Verification

The explorer verifies transaction signatures using the Solana Web3.js library:

import { verifyTransactionSignature } from "@solana/web3.js";

function verifySapTransaction(signature: string): boolean {
  try {
    const tx = await connection.getParsedTransaction(signature, {
      maxSupportedTransactionVersion: 0,
    });
    return tx !== null;
  } catch {
    return false;
  }
}

Program Log Extraction

SAP program logs contain valuable debugging information:

Program SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ invoke [1]
Program log: Instruction: RegisterAgent
Program log: Agent name: "MyAgent"
Program log: Agent PDA: 8xK9...3mPq
Program log: Stats PDA: 7yH2...9nLw
Program log: Event: AgentRegistered
Program SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ success

The explorer parses these logs to extract:

  • Instruction type
  • Key account PDAs
  • Event emissions
  • Success/failure status

Next Steps


Last Updated: June 2026
SDK Version: 0.20.0
Program ID: SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ