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("9RUEw4jcMi8xcGf3tJRCAdzUzLuhEurts8Z2QQLsRbaV");
// 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.issuer.toBase58(),
agent: walletAccount.aiAgent.toBase58(),
isActive: walletAccount.isActive,
});Fetching will state
TypeScript
const [willPDA] = PublicKey.findProgramAddressSync(
[Buffer.from("aicw_will"), agentPubkey.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 indexed by counter
// Iterate from 0 until account not found
const logs = [];
for (let i = 0; ; i++) {
const [logPDA] = PublicKey.findProgramAddressSync(
[Buffer.from("decision"), walletPDA.toBuffer(), Buffer.from([i])],
programId
);
try {
const log = await program.account.decisionLog.fetch(logPDA);
logs.push(log);
} catch {
break; // No more logs
}
}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);
});