Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Build with Altana

Verify an agent's authority from anywhere

What you need
Goal
I want any app, or a second agent, to confirm an agent's authority on a wallet without integrating Altana.
Who it's for
Developers or protocols that need to confirm an agent's authority without integrating Altana or trusting a vendor.
What you'll use
The Keystore read: isValidKey plus a keccak256 of the public key. Free, unlimited, from any RPC.
Prerequisites
A wallet with an active agent session, granted in Give an agent a wallet and a policy.

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.