HESTIAdocs

Agent tools

Turn a Hestia client into ready-made tool definitions an LLM agent can call — balance, shield, send, unshield.


Hestia is built for agents, so the SDK ships an adapter that exposes the four operations as tool definitions an LLM can call. createHestiaTools(hestia) returns an array you can map onto any tool-calling API.

The shape

ts
interface AgentTool {
  name: string;
  description: string;
  parameters: Record<string, unknown>; // JSON Schema
  execute: (args: Record<string, unknown>) => Promise<unknown>;
}

import { createHestiaTools } from "@hestia/sdk";
const tools = createHestiaTools(hestia); // AgentTool[]

Each tool carries a JSON-Schema parameters block (so a model knows how to call it) and an execute function that runs the real operation against your client.

The four tools

ToolParametersReturns
hestia_balancetoken{ token, balance } (balance as a base-unit string)
hestia_shieldtoken, amount{ txHash }
hestia_sendtoken, amount, to{ txHash }
hestia_unshieldtoken, amount, to{ txHash }

Conventions baked into the schemas:

  • token is an address; use the zero address 0x0000000000000000000000000000000000000000 for native ETH.
  • amount is a base-unit string (e.g. "10000000" for 10 USDC at 6 decimals) — strings avoid float precision loss across a tool boundary.
  • to is a hestia1… meta-address for send, and a public 0x… address for unshield.

hestia_balance, hestia_send, and hestia_unshield call hestia.sync() first, so a model always acts on a fresh view.

Wiring into a tool-calling loop

The tools are framework-agnostic. Adapt them to your provider's format and dispatch by name:

ts
const tools = createHestiaTools(hestia);

// expose schemas to the model (shape depends on your provider)
const schema = tools.map((t) => ({
  name: t.name,
  description: t.description,
  input_schema: t.parameters,
}));

// when the model asks to call a tool:
async function dispatch(name: string, args: Record<string, unknown>) {
  const tool = tools.find((t) => t.name === name);
  if (!tool) throw new Error(`unknown tool: ${name}`);
  return tool.execute(args); // → { txHash } or { token, balance }
}

// e.g. the model emits: hestia_send { token: "0x…USDC", amount: "10000000", to: "hestia1…" }
const result = await dispatch("hestia_send", {
  token: usdc, amount: "10000000", to: "hestia1…payee",
});

Safety notes for autonomous use

  • Proving is local. Even when a model triggers a tool, the witness (amounts, notes, sk) is built and proven on the device. The model sees only the public result.
  • Errors are explicit. A send/unshield for more than any single note holds throws InsufficientPrivateBalance; surface it to the model so it can consolidate or lower the amount rather than retry blindly.
  • Bound your agent. The tools execute real transfers. Apply your own policy (limits, allow-lists, confirmation) around execute for an unattended agent.

These four tools are the same operations documented in operations — the adapter just makes them legible to a model.