Build with Altana
Verify an agent's authority from anywhere
isValidKey plus a keccak256 of the public key. Free, unlimited, from any RPC.Anyone can run this. It is a plain read against the public Keystore, so it needs no admin key, no session, and nothing from Altana.
Step 1: Set up a public read client
You only need a read client pointed at the chain. No admin key and no session.
import { createPublicClient, http, keccak256 } from "viem";
import { BNB } from "@altananetwork/sdk";
const client = createPublicClient({
chain: BNB.chain,
transport: http(BNB.publicRpcUrl),
});Step 2: Derive the agent's key id
Keystore identifies a key by its key id, the keccak256 hash of the SEC1-encoded public key. Hash the agent's session public key to get the value you will ask about.
const keyId = keccak256(sessionPublicKey);Step 3: Ask the Keystore whether that key is authorized
Call isValidKey on the Keystore for the wallet you care about.
This is a plain eth_call: free, unlimited, and available from any RPC.
const KEYSTORE_ABI = [{
name: "isValidKey", type: "function", stateMutability: "view",
inputs: [
{ name: "user", type: "address" },
{ name: "keyId", type: "bytes32" },
],
outputs: [{ type: "bool" }],
}] as const;
// One eth_call answers: is this key allowed to act on this wallet right now?
const authorized = await client.readContract({
address: BNB.keyStore,
abi: KEYSTORE_ABI,
functionName: "isValidKey",
args: [walletAddress, keyId],
});isValidKey returns true only when the key exists, has not been revoked, and has not expired. If you want the whole set of keys on a wallet instead of a single yes or no, read getKeys(walletAddress) for the key ids, then check each one with isValidKey. Revocation drops a key from getKeys immediately, but expiry does not, so a key can still be listed there long after it stopped being usable.
Run this from your own script against your own wallet. This is exactly what a DEX or a counterparty agent would run, for free, from any RPC.
For the same answer without writing code, look the wallet up in the Keystore Explorer. Its key pages show the same state a human can read and link to.
Why it is different
Authorization is a public onchain object. Verification costs nothing, needs no API key, and works for parties who have never heard of your app.
Note on sub-delegation.
Only the wallet admin grants sessions. Do not read this as one agent minting a sub-key for another. It is the admin authorizing both agents, and the agents verifying each other. If session-to-session sub-delegation lands later, the docs will be updated.
What's next
Authorize across chains: take that authorization to another chain without granting it again.