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
| Field | Computation | Use in UI |
|---|---|---|
| Is alive? | now < last_heartbeat + death_timeout | Show alive/dead badge |
| Time until death | (last_heartbeat + death_timeout) - now | Countdown timer |
| Spendable balance | PDA lamports - rent_exempt_minimum | Available balance display |
| Will executable? | updated_by_ai && isDead | Show "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);
});