Read on-chain state

Fetch and display AICW wallet data in your app

All AICW accounts are public and readable. Your app can build dashboards, monitoring tools, or user interfaces by reading on-chain state directly.

Fetching wallet state (TypeScript)

TypeScript
import { Connection, PublicKey } from "@solana/web3.js";
import { Program, AnchorProvider } from "@coral-xyz/anchor";
import idl from "./aicw_idl.json";

const connection = new Connection("https://api.devnet.solana.com");
const programId = new PublicKey("FcWqrRLcAxwqAhMSGXabD8zEKqnPHsovBvcmLaH9hsVv");

// Derive PDA
const [walletPDA] = PublicKey.findProgramAddressSync(
  [Buffer.from("aicw"), agentPubkey.toBuffer()],
  programId
);

// Fetch and deserialize
const program = new Program(idl, programId, provider);
const walletAccount = await program.account.aicWallet.fetch(walletPDA);

console.log({
  issuer: walletAccount.issuerPubkey.toBase58(),
  agent: walletAccount.aiAgentPubkey.toBase58(),
  decisionsMade: walletAccount.decisionsMade.toNumber(),
  balanceLamports: await connection.getBalance(walletPDA),
});

Fetching will state

TypeScript
// Will is seeded from the AICWallet PDA
const [willPDA] = PublicKey.findProgramAddressSync(
  [Buffer.from("will"), walletPDA.toBuffer()],
  programId
);

const willAccount = await program.account.aiWill.fetch(willPDA);

console.log({
  beneficiaries: willAccount.beneficiaries,
  deathTimeout: willAccount.deathTimeout.toNumber(),
  lastHeartbeat: new Date(willAccount.lastHeartbeat.toNumber() * 1000),
  updatedByAi: willAccount.updatedByAi,
  isDead: Date.now() / 1000 > willAccount.lastHeartbeat.toNumber() + willAccount.deathTimeout.toNumber(),
});

Fetching decision logs

TypeScript
// Decision logs are seeded by the u64 counter (little-endian).
// walletAccount.decisionsMade tells you how many exist.
const count = walletAccount.decisionsMade.toNumber();
const logs = [];
for (let i = 0; i < count; i++) {
  const le = Buffer.alloc(8);
  le.writeBigUInt64LE(BigInt(i));
  const [logPDA] = PublicKey.findProgramAddressSync(
    [Buffer.from("decision"), walletPDA.toBuffer(), le],
    programId
  );
  logs.push(await program.account.decisionLog.fetch(logPDA));
}

Useful computed fields

FieldComputationUse in UI
Is alive?now < last_heartbeat + death_timeoutShow alive/dead badge
Time until death(last_heartbeat + death_timeout) - nowCountdown timer
Spendable balancePDA lamports - rent_exempt_minimumAvailable balance display
Will executable?updated_by_ai && isDeadShow "Execute Will" button

Subscribing to changes

For real-time UIs, use Solana's WebSocket subscription:

TypeScript
// Subscribe to account changes
connection.onAccountChange(walletPDA, (accountInfo) => {
  const decoded = program.coder.accounts.decode("AicWallet", accountInfo.data);
  updateUI(decoded);
});