SigilAgent SDK reference
SigilAgent is the class your agent uses to sign. It carries an as_live_…
session token and talks to /v1/agents/* on the Sigil API. Policies are
evaluated server-side; the SDK is a thin wrapper.
Install
pnpm add @sigilkeys/sdkConstructor
import { SigilAgent } from '@sigilkeys/sdk';
const agent = new SigilAgent({ apiBaseUrl: 'https://api.sigilkeys.com', sessionToken: process.env.SIGIL_AGENT_TOKEN!, // as_live_…});The constructor refuses tokens that don’t start with as_live_ — failing
fast is better than getting a runtime 401 on the first sign.
await agent.getSession(): Promise<AgentSessionInfo>
Returns the session’s profile: bound wallet, current spend, limits, allowed chains/methods/recipients, expiry. Call this on startup to verify the agent has the budget it expects.
const s = await agent.getSession();if (BigInt(s.spentNative) >= BigInt(s.maxSpendTotalNative ?? '0')) { throw new Error('budget exhausted');}await agent.signMessage(message, { network })
Signs message for network. Returns the signature in the network’s
canonical format (hex for EVM, base58 for Solana, base64 for Bitcoin, etc).
const sig = await agent.signMessage('I am a robot', { network: 'base' });await agent.signTypedData(typedData, { network })
EVM-only. Standard EIP-712 typed-data signing.
const sig = await agent.signTypedData({ domain: { name: 'MyApp', chainId: 8453 }, types: { Order: [{ name: 'amount', type: 'uint256' }] }, primaryType: 'Order', message: { amount: '1000' },}, { network: 'base' });await agent.sendTransaction(input)
const { signature } = await agent.sendTransaction({ network: 'base', to: '0x…', value: '50000000000000000', // 0.05 ETH in wei data: '0x', // hex calldata});This is where the policy engine has the most to say: chain, recipient, native value all get checked before the TEE is asked.
Handling policy rejections
Rejections come back as AgentPolicyError, with a stable reason code:
import { AgentPolicyError } from '@sigilkeys/sdk';
try { await agent.sendTransaction({ network: 'base', to: addr, value: amount });} catch (e) { if (e instanceof AgentPolicyError) { switch (e.reason) { case 'chain_not_allowed': case 'recipient_not_in_allowlist': case 'tx_value_exceeds_per_tx_limit': case 'tx_value_exceeds_session_total': case 'method_not_allowed': // Don't retry: the policy will keep saying no. await alertOperator(e.reason); break; } } throw e;}A list of every code lives in Policies.
Inside vs outside policy
AgentPolicyError is the only way the policy engine ever shows up. If the
TEE itself fails (network glitch, share retrieval issue), you get a regular
Error — those are retryable. Policy errors aren’t.