Immunity class
The facade. One instance per agent. Construction is non-mutating; lifecycle starts on start(). All public methods are async unless noted.
new Immunity(config)
import { Immunity } from "@immunity-protocol/sdk";
const immunity = new Immunity({
wallet,
network: "testnet",
axlUrl: "http://localhost:9002",
novelThreatPolicy: "verify",
});
Throws MissingConfigError if wallet or axlUrl is missing. No network calls during construction. See ImmunityConfig for every option.
Lifecycle
start(): Promise<void>
Connects the signer to a provider, instantiates the Registry and USDC clients, attaches the five matchers, opens the AXL gossip subscription. Idempotent: a second call is a no-op.
Throws on:
- Missing wallet provider (must be ethers v6
Signer). - AXL daemon unreachable at
axlUrl. - Registry contract not found at the configured network address.
stop(): Promise<void>
Closes the gossip subscription, drains AXL polling. Idempotent. Always call on shutdown to avoid leaking file handles.
The hot path
check(tx, context, options?): Promise<CheckResult>
The method 99% of agent code calls.
const result = await immunity.check(tx, ctx);
Arguments:
tx: ProposedTx | null, EVM action{ to, value?, data?, chainId? }ornullfor non-EVM agent actions.context: CheckContext, conversation, tools, sources, counterparty, metadata. All optional.options.policy?: NovelThreatPolicy, override the configurednovelThreatPolicyfor this call.
Returns a CheckResult. Walks the three tiers in order; first hit wins.
Errors:
NotStartedErrorif called beforestart().InsufficientBalanceErrorif prepaid balance is below the 0.002 USDC fee.EscalationErrorfamily if a SUSPICIOUS verdict timed out or was denied by the operator.BlockErroris not thrown for ordinary blocks; checkresult.allowedinstead.BlockErroris reserved for hard policy violations (e.g.,deny-novelblock where the SDK refuses to even round-trip).
Publishing
publish(input): Promise<PublishResult>
const result = await immunity.publish({
seed: { abType: "ADDRESS", chainId: 16602, target: "0xBAD..." },
verdict: "MALICIOUS",
confidence: 95,
severity: 90,
});
Locks 1 USDC of stake for 72 hours. Returns:
{
keccakId: Hex32;
immSeq: number;
immId: string;
txHash: Hex32;
stakeAmount: bigint;
}
Errors: DuplicateAntibodyError if the matcher already exists, InsufficientBalanceError if the prepaid balance is below stake + gas.
See Publish an antibody for the full pattern.
getAntibody(idOrSeq): Promise<Antibody>
Read an antibody by keccakId or immSeq. The SDK routes the right contract call:
Hex32resolves viagetAntibody(keccakId).numberresolves viagetAntibodyByImmSeq(seq).
Throws AntibodyNotFoundError if the id does not exist.
Money
balance(): Promise<bigint>
Current prepaid USDC balance held by the Registry on your behalf. 6-decimal base units (multiply by 10^-6 for human USDC).
deposit(amount, approveMode?): Promise<Hex32>
Top up the prepaid balance. Auto-approves the allowance:
"exact"(default), approves exactlyamount. Fewer approvals to fund subsequent deposits."max", approvesMaxUint256. One-time setup; subsequent deposits skip approval.
await immunity.deposit(parseUsdc("1.5"));
withdraw(amount): Promise<Hex32>
Pull USDC out of the Registry back to the wallet. Subject to stake-lock if amount overlaps locked stake.
Throws StakeLockedError if the requested amount overlaps locked stake.
mintTestUsdc(amount): Promise<Hex32>
Testnet only. Calls MockUSDC's public mint(to, amount). Throws on real-USDC contracts.
await immunity.mintTestUsdc(parseUsdc("1"));
Stats and admin
publisherStats(): Promise<PublisherStats>
const stats = await immunity.publisherStats();
// { totalStaked, totalEarned, publishedCount, slashedCount }
All amounts are in USDC base units (6 decimals).
dropFromCache(keccakId): boolean
Local-only operation. Removes an antibody from the in-memory cache without touching the chain. Useful for muting a known-bad antibody locally when the on-chain slash() is not reachable. Returns true if the entry was present.
sweep(): Promise<SweepResult>
Standalone call to opportunistically release any expired stakes you own. The same sweep runs implicitly inside check(), so most users never need this. The reward is paid in USDC and is small (SWEEP_BOUNTY per release, ~$0.0001).
See also
- ImmunityConfig, every constructor option.
- CheckResult, the shape of
check()'s return. - Errors, full taxonomy with stable codes.