Programmable Calldata Policy Engine
Define type-safe constraints on ABI-encoded data. Enforce them onchain in Solidity, or offchain in TypeScript.
One spec, two implementations
The policy format is a specification with two independent implementations, a Solidity library and a TypeScript SDK. Reach for whichever your scenario needs: embed the engine in your contracts for dynamic onchain rules, or check payloads in TypeScript before they’re signed. Use one, the other, or both.
Solidity library
Dynamic guardrails in your contracts
// function approve(address spender, uint256 amount)
bytes memory policy = PolicyBuilder
.create("approve(address,uint256)")
.add(arg(0).isIn(trustedSpenders)) // spender
.add(arg(1).lte(uint256(1_000_000e6))) // amount
.build();
// reverts on a violation
PolicyEnforcer.enforce(policy, msg.data);TypeScript SDK
Check payloads before signing
// function approve(address spender, uint256 amount)
const policy = PolicyBuilder
.create("approve(address,uint256)")
.add(arg(0).isIn(trustedSpenders)) // spender
.add(arg(1).lte(1_000_000n * 10n ** 6n)) // amount
.build();
// throws on a violation
PolicyEnforcer.enforce(policy, calldata);Both implementations also expose check, which returns a result instead of reverting or throwing.
Express any constraint
Scalar arguments, nested struct fields, array elements, transaction context, even raw ABI blobs. Compose them with AND/OR logic. Pick a capability.
Set membership, ranges, and comparisons on scalar arguments.
// function withdraw(address to, uint256 amount)
bytes memory policy = PolicyBuilder
.create("withdraw(address,uint256)")
.add(arg(0).isIn(allowed)) // to
.add(arg(1).lte(uint256(1_000e18))) // amount
.build();// function withdraw(address to, uint256 amount)
const policy = PolicyBuilder
.create("withdraw(address,uint256)")
.add(arg(0).isIn(allowed)) // to
.add(arg(1).lte(1_000n * 10n ** 18n)) // amount
.build();Why it holds up
Descriptors are embedded in the policy blob, so enforcement needs no external registry or lookup.
Layer multiple constraints on any argument or field. They compose into a single policy blob.
Validation catches contradictions, redundant rules, and type mismatches before you ship.
Explore and debug, in the browser
Prototype policies visually and debug the ones you write. No install required.
Start building
Install the Solidity library or the TypeScript SDK and write your first policy.