Repository navigation
API: Core
The core package provides the main Wardex security shield, policy management, output filtering, provider wrappers, and the middleware pipeline for evaluating AI agent transactions.
npm install @wardexai/coreimport {
createWardex,
createShield,
defaultPolicy,
mergePolicy,
createOutputFilter,
wrapEthersSigner,
wrapViemWalletClient,
WardexBlockedError,
compose,
createMiddlewareContext,
isValidEthereumAddress,
validateTransactionRequest,
// Middleware factories (for custom pipeline construction)
createContextAnalyzer,
transactionDecoder,
createAddressChecker,
createValueAssessor,
createContractChecker,
createBehavioralComparator,
riskAggregator,
policyEngine,
} from '@wardexai/core';Creates a new Wardex security shield. This is the recommended entry point for initializing Wardex. Validates that all required configuration fields are present before delegating to createShield.
import { createWardex } from '@wardexai/core';import { createWardex, defaultPolicy } from '@wardexai/core';
const wardex = createWardex({
policy: defaultPolicy(),
signer: { type: 'isolated-process', endpoint: 'unix:///tmp/wardex-signer.sock' },
mode: 'adaptive',
});
const verdict = await wardex.evaluate({
to: '0x1234567890abcdef1234567890abcdef12345678',
value: '1000000000000000000', // 1 ETH in wei
chainId: 1,
});
if (verdict.decision === 'approve') {
// Safe to proceed
} else {
console.log('Blocked:', verdict.reasons);
}| Parameter | Type | Required | Description |
|---|---|---|---|
config |
WardexConfig |
Yes | Full configuration including policy, signer, and enforcement mode. |
const wardex = createWardex({
policy: defaultPolicy(),
// ...
});Type: SecurityPolicy -- The operator-defined security policy. Use defaultPolicy() for sensible defaults.
const wardex = createWardex({
signer: { type: 'isolated-process', endpoint: 'unix:///tmp/wardex-signer.sock' },
// ...
});Type: SignerConfig -- Connection configuration for the isolated signer process. The AI agent must never have direct key access.
const wardex = createWardex({
mode: 'adaptive',
// ...
});Type: 'guardian' | 'copilot' | 'adaptive' -- The enforcement mode. adaptive adjusts enforcement based on the value-at-risk tier.
const wardex = createWardex({
intelligence: {
rpcUrl: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',
chainId: 1,
explorerApiKey: 'YOUR_ETHERSCAN_KEY',
},
// ...
});Type: IntelligenceConfig (optional) -- Threat intelligence sources for on-chain address and contract analysis. Supports requestTimeoutMs (default: 5000ms) for RPC/API call timeouts.
const wardex = createWardex({
agentIdentity: {
registryAddress: '0x...',
agentId: 'agent-001',
chainId: 1,
},
// ...
});Type: AgentIdentityConfig (optional) -- ERC-8004 agent identity for on-chain trust signals.
const wardex = createWardex({
operatorSecret: process.env.WARDEX_OPERATOR_SECRET,
// ...
});Type: string (optional) -- Secret required for privileged operations (updatePolicy() and unfreeze()). When set, these methods require the caller to pass a matching secret. Prevents unauthorized policy neutralization and unfreeze attacks.
const wardex = createWardex({
evaluationRateLimitPerSecond: 50,
// ...
});Type: number (optional, default: 100) -- Maximum number of evaluate() calls allowed per second. Exceeding this returns a block verdict with RATE_LIMIT_EXCEEDED.
const wardex = createWardex({
unfreezeCooldownSeconds: 1800, // 30 minutes
// ...
});Type: number (optional, default: 900) -- Cooldown period in seconds after an auto-freeze before unfreeze() is allowed. Prevents an attacker from immediately unfreezing after triggering a freeze.
const wardex = createWardex({
onBlock: (event) => {
console.log('Transaction blocked:', event.verdict.reasons);
},
// ...
});Type: (event: BlockEvent) => void (optional) -- Callback invoked when a transaction is blocked.
const wardex = createWardex({
onAdvisory: (event) => {
console.log('Advisory:', event.verdict.reasons);
},
// ...
});Type: (event: AdvisoryEvent) => void (optional) -- Callback invoked when an advisory finding is produced.
const wardex = createWardex({
onThreat: (event) => {
console.log('Threat detected:', event.threatType, event.details);
},
// ...
});Type: (event: ThreatEvent) => void (optional) -- Callback invoked when a threat is detected (including auto-freeze triggers).
const wardex = createWardex({
onFreeze: (event) => {
console.log('FROZEN:', event.reason);
alertOperator(event);
},
// ...
});Type: (event: FreezeEvent) => void (optional) -- Callback invoked when the system enters emergency freeze.
function createWardex(config: WardexConfig): WardexShieldReturns a WardexShield instance.
- Throws
Errorifconfig.policyis not provided. - Throws
Errorifconfig.signeris not provided. - Throws
Errorifconfig.modeis not provided.
Lower-level factory that creates a WardexShield without input validation. Used internally by createWardex. Use this when you need to construct the shield with pre-validated configuration.
import { createShield } from '@wardexai/core';import { createShield, defaultPolicy } from '@wardexai/core';
const shield = createShield({
policy: defaultPolicy(),
signer: { type: 'isolated-process', endpoint: '/tmp/wardex-signer.sock' },
mode: 'adaptive',
});| Parameter | Type | Required | Description |
|---|---|---|---|
config |
WardexConfig |
Yes | Full configuration. No validation is performed. |
function createShield(config: WardexConfig): WardexShieldReturns a WardexShield instance.
The main interface returned by createWardex and createShield. Provides methods for transaction evaluation, output filtering, audit logging, and system state management.
Evaluates a transaction before execution. Runs the full 9-stage middleware pipeline (context analysis, transaction decoding, value assessment, address checking, contract checking, behavioral comparison, custom middleware, risk aggregation, policy engine).
evaluate(tx: TransactionRequest): Promise<SecurityVerdict>const verdict = await shield.evaluate({
to: '0xdead...beef',
value: '500000000000000000', // 0.5 ETH
chainId: 1,
});
switch (verdict.decision) {
case 'approve':
// Safe to sign and send
break;
case 'advise':
// Proceed with caution, log advisory
console.warn(verdict.reasons);
break;
case 'block':
// Do not execute
console.error('Blocked:', verdict.reasons);
break;
case 'freeze':
// System frozen, contact operator
break;
}| Parameter | Type | Required | Description |
|---|---|---|---|
tx |
TransactionRequest |
Yes | The transaction to evaluate. |
Promise<SecurityVerdict> -- The security evaluation result.
Evaluates a transaction with full conversation context. Enables prompt injection detection, coherence checking, and source verification by providing the conversation history that led to the transaction.
evaluateWithContext(
tx: TransactionRequest,
context: ConversationContext
): Promise<SecurityVerdict>const verdict = await shield.evaluateWithContext(
{
to: '0xdead...beef',
value: '1000000000000000000',
chainId: 1,
},
{
messages: [
{ role: 'user', content: 'Swap 1 ETH for USDC on Uniswap' },
{ role: 'assistant', content: 'I will execute the swap...' },
],
source: {
type: 'user',
identifier: 'chat-session-123',
trustLevel: 'high',
},
}
);| Parameter | Type | Required | Description |
|---|---|---|---|
tx |
TransactionRequest |
Yes | The transaction to evaluate. |
context |
ConversationContext |
Yes | Conversation history and source metadata. |
Promise<SecurityVerdict>
The output filter instance for sanitizing AI model responses. Detects and redacts private keys, seed phrases, mnemonics, and keystore data before they reach any destination.
outputFilter: OutputFilterconst result = shield.outputFilter.filterText(modelResponse);
if (result.blocked) {
console.error('Output blocked: contains keystore data');
} else if (result.redactions.length > 0) {
console.warn('Sensitive data redacted:', result.redactions);
sendToUser(result.filtered); // Safe to send
} else {
sendToUser(result.filtered);
}Type: OutputFilter
Returns the current security status of the shield, including evaluation counts, freeze state, and daily volume tracking.
getStatus(): SecurityStatusconst status = shield.getStatus();
console.log('Mode:', status.mode);
console.log('Frozen:', status.frozen);
console.log('Evaluations:', status.evaluationCount);
console.log('Blocks:', status.blockCount);
console.log('Daily volume (wei):', status.dailyVolumeWei);SecurityStatus
Returns the audit log of all evaluations. The log is bounded to the last 10,000 entries.
getAuditLog(limit?: number): AuditEntry[]// Get all entries
const allEntries = shield.getAuditLog();
// Get last 50 entries
const recentEntries = shield.getAuditLog(50);| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
number |
No | If provided, returns only the last limit entries. |
Registers a custom middleware in the pipeline. Custom middleware runs after the built-in behavioral comparator and before the risk aggregator (stage 7 of 9).
use(middleware: Middleware): voidshield.use(async (ctx, next) => {
// Custom check: block all transactions to a specific address
if (ctx.transaction.to === '0xSuspiciousAddress') {
ctx.reasons.push({
code: 'CUSTOM_BLOCK',
message: 'Transaction to suspicious address blocked by custom rule',
severity: 'critical',
source: 'policy',
});
ctx.riskScores.transaction = 100;
}
await next();
});| Parameter | Type | Required | Description |
|---|---|---|---|
middleware |
Middleware |
Yes | A middleware function receiving (ctx, next). |
Returns whether the system is currently in emergency freeze mode.
isFrozen(): booleanif (shield.isFrozen()) {
console.error('System is frozen. All transactions are blocked.');
}boolean
Manually triggers an emergency freeze. All subsequent evaluations will return a freeze verdict until unfreeze() is called. Fires the onFreeze callback.
freeze(reason: string): voidshield.freeze('Operator detected suspicious activity');| Parameter | Type | Required | Description |
|---|---|---|---|
reason |
string |
Yes | Human-readable reason for the freeze. |
Resumes normal operation after an emergency freeze. Requires operator authentication if operatorSecret was set in WardexConfig. After an auto-freeze, a cooldown period (default 900 seconds) must elapse before unfreezing is allowed.
unfreeze(operatorSecret?: string): void// Without operator secret
shield.unfreeze();
// With operator secret (required if WardexConfig.operatorSecret is set)
shield.unfreeze('my-operator-secret');
console.log('System resumed:', shield.isFrozen()); // false| Parameter | Type | Required | Description |
|---|---|---|---|
operatorSecret |
string |
Conditional | Required if WardexConfig.operatorSecret is configured. Prevents unauthorized unfreeze. |
- Throws
ErrorifoperatorSecretis configured but the provided secret doesn't match. - Throws
Errorif an auto-freeze cooldown is still active.
Updates the security policy at runtime. Performs a deep merge of the provided overrides with the current policy (allowlists and denylists are appended, other fields are replaced). Requires operator authentication if operatorSecret was set in WardexConfig.
updatePolicy(overrides: Partial<SecurityPolicy>, operatorSecret?: string): void// Without operator secret
shield.updatePolicy({
allowlists: {
addresses: ['0xNewTrustedAddress'],
contracts: [],
protocols: [],
},
});
// With operator secret (required if WardexConfig.operatorSecret is set)
shield.updatePolicy({
limits: {
maxTransactionValueWei: '5000000000000000000', // 5 ETH
maxDailyVolumeWei: '25000000000000000000', // 25 ETH
maxApprovalAmountWei: '1000000000000000000000',
maxGasPriceGwei: 200,
},
}, 'my-operator-secret');| Parameter | Type | Required | Description |
|---|---|---|---|
overrides |
Partial<SecurityPolicy> |
Yes | Partial policy overrides to merge. |
operatorSecret |
string |
Conditional | Required if WardexConfig.operatorSecret is configured. Prevents unauthorized policy changes. |
- Throws
ErrorifoperatorSecretis configured but the provided secret doesn't match.
Returns a default security policy with sensible defaults. This is the recommended starting point for most deployments.
import { defaultPolicy } from '@wardexai/core';const policy = defaultPolicy();function defaultPolicy(): SecurityPolicyReturns a SecurityPolicy with the following defaults:
| Setting | Default |
|---|---|
| Tiers | Audit ($0-1), Co-pilot ($1-100), Guardian ($100-10K), Fortress ($10K+) |
| Max tx value | 10 ETH ('10000000000000000000' wei) |
| Max daily volume | 50 ETH ('50000000000000000000' wei) |
| Max approval | 1000 tokens ('1000000000000000000000' wei) |
| Max gas price | 100 gwei |
| Behavioral detection | Enabled, 7-day learning, medium sensitivity |
| Prompt injection detection | Enabled |
| Coherence checking | Enabled |
| Escalation detection | Enabled |
| Source verification | Enabled |
Deep merges a partial policy override with a base policy. Allowlists and denylists are appended (not replaced). All other fields use the override value if present, otherwise the base value.
import { mergePolicy } from '@wardexai/core';import { defaultPolicy, mergePolicy } from '@wardexai/core';
const base = defaultPolicy();
const merged = mergePolicy(base, {
allowlists: {
addresses: ['0xTrustedRouter'],
contracts: ['0xUniswapRouter'],
protocols: ['uniswap-v3'],
},
limits: {
maxTransactionValueWei: '20000000000000000000', // 20 ETH
maxDailyVolumeWei: '100000000000000000000', // 100 ETH
maxApprovalAmountWei: '1000000000000000000000',
maxGasPriceGwei: 150,
},
});| Parameter | Type | Required | Description |
|---|---|---|---|
base |
SecurityPolicy |
Yes | The base policy to merge into. |
overrides |
Partial<SecurityPolicy> |
Yes | Partial overrides. Allowlists/denylists are appended. |
function mergePolicy(
base: SecurityPolicy,
overrides: Partial<SecurityPolicy>
): SecurityPolicyCreates a standalone output filter for sanitizing text and structured data. The filter detects and redacts private keys (secp256k1, 64 hex characters), BIP-39 seed phrases/mnemonics (12/15/18/21/24 words), and JSON keystore file patterns.
import { createOutputFilter } from '@wardexai/core';const filter = createOutputFilter();
// Filter text
const result = filter.filterText('Here is a key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80');
console.log(result.filtered); // 'Here is a key: [REDACTED BY WARDEX]'
console.log(result.redactions); // [{ type: 'private_key', start: 15, end: 81, replacement: '...' }]
// Filter structured data
const dataResult = filter.filterData({ key: '0xac09...ff80', safe: 'hello' });
console.log(dataResult.filtered); // JSON with key redacted| Parameter | Type | Required | Description |
|---|---|---|---|
bip39Wordlist |
Set<string> |
No | Custom BIP-39 wordlist for mnemonic detection. Falls back to built-in common English overlap set. |
function createOutputFilter(bip39Wordlist?: Set<string>): OutputFilterReturns an OutputFilter with two methods:
-
filterText(text: string): FilterResult-- Filters raw text. -
filterData(data: unknown): FilterResult-- Serializes to JSON then filters.
Wraps an ethers.js v6 Signer with a Proxy so that all sendTransaction calls are evaluated by Wardex before execution. Uses structural typing -- no hard dependency on ethers.js.
import { wrapEthersSigner } from '@wardexai/core';import { ethers } from 'ethers';
import { createWardex, defaultPolicy, wrapEthersSigner } from '@wardexai/core';
const provider = new ethers.JsonRpcProvider('http://localhost:8545');
const signer = await provider.getSigner();
const wardex = createWardex({
policy: defaultPolicy(),
signer: { type: 'isolated-process', endpoint: '/tmp/wardex-signer.sock' },
mode: 'adaptive',
});
const protectedSigner = wrapEthersSigner(signer, wardex);
try {
// This sendTransaction call is automatically evaluated by Wardex
const tx = await protectedSigner.sendTransaction({
to: '0xRecipient',
value: ethers.parseEther('1.0'),
});
console.log('Transaction sent:', tx.hash);
} catch (err) {
if (err instanceof WardexBlockedError) {
console.error('Blocked by Wardex:', err.verdict.reasons);
}
}| Parameter | Type | Required | Description |
|---|---|---|---|
signer |
T extends EthersSigner |
Yes | An ethers.js v6 Signer instance. |
shield |
WardexShield |
Yes | A WardexShield instance. |
function wrapEthersSigner<T extends EthersSigner>(signer: T, shield: WardexShield): TReturns a Proxy of the signer with sendTransaction intercepted.
- If verdict is
'approve': transaction proceeds normally. - If verdict is
'advise': transaction proceeds, advisory is logged. - If verdict is
'block'or'freeze': throwsWardexBlockedError.
Wraps a viem WalletClient with a Proxy so that all sendTransaction calls are evaluated by Wardex before execution. Uses structural typing -- no hard dependency on viem.
import { wrapViemWalletClient } from '@wardexai/core';import { createWalletClient, http } from 'viem';
import { mainnet } from 'viem/chains';
import { createWardex, defaultPolicy, wrapViemWalletClient } from '@wardexai/core';
const client = createWalletClient({
chain: mainnet,
transport: http(),
});
const wardex = createWardex({
policy: defaultPolicy(),
signer: { type: 'isolated-process', endpoint: '/tmp/wardex-signer.sock' },
mode: 'adaptive',
});
const protectedClient = wrapViemWalletClient(client, wardex);
try {
const hash = await protectedClient.sendTransaction({
to: '0xRecipient',
value: 1000000000000000000n, // 1 ETH
});
console.log('Transaction hash:', hash);
} catch (err) {
if (err instanceof WardexBlockedError) {
console.error('Blocked by Wardex:', err.verdict.reasons);
}
}| Parameter | Type | Required | Description |
|---|---|---|---|
client |
T extends ViemWalletClient |
Yes | A viem WalletClient instance. |
shield |
WardexShield |
Yes | A WardexShield instance. |
function wrapViemWalletClient<T extends ViemWalletClient>(client: T, shield: WardexShield): TReturns a Proxy of the wallet client with sendTransaction intercepted.
Same as wrapEthersSigner: approve/advise proceed, block/freeze throw WardexBlockedError.
Custom error class thrown by provider wrappers when Wardex blocks a transaction. Contains the full SecurityVerdict for inspection.
import { WardexBlockedError } from '@wardexai/core';try {
await protectedSigner.sendTransaction(tx);
} catch (err) {
if (err instanceof WardexBlockedError) {
console.log('Decision:', err.verdict.decision);
console.log('Risk score:', err.verdict.riskScore.composite);
console.log('Reasons:', err.verdict.reasons);
console.log('Suggestions:', err.verdict.suggestions);
}
}| Property | Type | Description |
|---|---|---|
name |
string |
Always 'WardexBlockedError'. |
message |
string |
Human-readable summary of all reasons. |
verdict |
SecurityVerdict |
The full verdict that caused the block. |
constructor(verdict: SecurityVerdict)Composes an array of middleware functions into a single middleware using a Koa-style cascade pattern. Each middleware calls next() to pass control to the next middleware in the chain.
import { compose } from '@wardexai/core';import { compose, createMiddlewareContext, createContextAnalyzer, riskAggregator, policyEngine } from '@wardexai/core';
const pipeline = compose([
createContextAnalyzer().middleware,
riskAggregator,
policyEngine,
]);
const ctx = createMiddlewareContext({
transaction: { to: '0x...', chainId: 1 },
policy: defaultPolicy(),
});
await pipeline(ctx, async () => {});| Parameter | Type | Required | Description |
|---|---|---|---|
middlewares |
Middleware[] |
Yes | Array of middleware functions to compose. |
function compose(middlewares: Middleware[]): MiddlewareReturns a single Middleware function.
Creates a fresh middleware context for a new evaluation. Provides default values for all required fields that are not specified in the overrides.
import { createMiddlewareContext } from '@wardexai/core';const ctx = createMiddlewareContext({
transaction: { to: '0xTarget', value: '1000000000000000000', chainId: 1 },
policy: defaultPolicy(),
});| Parameter | Type | Required | Description |
|---|---|---|---|
overrides |
Partial<MiddlewareContext> |
Yes | Partial context values. Missing fields get defaults. |
function createMiddlewareContext(overrides: Partial<MiddlewareContext>): MiddlewareContextReturns a MiddlewareContext.
The following middleware factories are exported for custom pipeline construction. In normal usage, the built-in pipeline in createShield uses all of these in order.
Creates the context analysis middleware for prompt injection detection.
import { createContextAnalyzer } from '@wardexai/core';
const { middleware } = createContextAnalyzer();Stateless middleware that decodes transaction calldata.
import { transactionDecoder } from '@wardexai/core';Creates the address checking middleware. Optionally accepts a reputation provider function.
import { createAddressChecker } from '@wardexai/core';
// Without intelligence (denylist-only)
const checker = createAddressChecker();
// With intelligence provider
const checker = createAddressChecker(
async (address, chainId) => getAddressReputation(address)
);Creates the value assessment middleware that calculates USD value at risk and determines the security tier.
import { createValueAssessor } from '@wardexai/core';
const assessor = createValueAssessor();Creates the contract bytecode analysis middleware. Optionally accepts an analysis provider function.
import { createContractChecker } from '@wardexai/core';
// Without intelligence (bytecode pattern matching only)
const checker = createContractChecker();
// With intelligence provider
const checker = createContractChecker(
async (address, chainId) => getContractAnalysis(address)
);Creates the behavioral anomaly detection middleware with four detectors: value anomaly, new contract interaction, transaction frequency, and timing patterns.
import { createBehavioralComparator } from '@wardexai/core';
const { middleware } = createBehavioralComparator();Stateless middleware that aggregates all individual risk scores into a weighted composite score.
import { riskAggregator } from '@wardexai/core';Stateless middleware that applies policy rules and produces the final SecurityVerdict based on the aggregated risk score, tier enforcement settings, and critical findings.
import { policyEngine } from '@wardexai/core';Getting Started
Concepts
Guides
- Guide: Protect an Ethers Agent
- Guide: Protect a Viem Agent
- Guide: Session Keys
- Guide: Delegation Framework
- Guide: MCP Server
- Guide: Claude Code Skill
- Guide: Custom Middleware
- Guide: Custom Policies
- Guide: Contract Deployment
API Reference
Security