The transaction amount limit rule
Policy Engine v1 ships with one rule kind: a transaction amount limit. For each policy you choose:- A name (up to 64 characters), which appears in the error when the policy blocks a transaction
- A chain
- A token — the chain’s native asset, a listed stablecoin, or a custom token (contract address on EVM/Tron, or mint address on Solana) along with its decimals
- A per-transaction cap, entered in display units (e.g.
0.5ETH,100USDC) - Optionally, up to 100 recipients the cap applies to
Limiting what goes to specific recipients
Add recipients to cap what a single transaction can send to particular addresses, for example “at most 1,000 USDC to this exchange”. The policy then counts only what the transaction sends to the listed recipients, adds it up across all of them, and blocks the transaction when that total is over the cap. Whatever the transaction sends to other addresses doesn’t count. Leave recipients empty to block any transaction above the cap, whoever receives it. A recipient is the address that ends up with the funds, not the contract the transaction calls:- Native sends: the transaction’s
to - Token transfers: the address the token pays, not the token contract. On EVM and Tron that’s the
toof atransfer, or of atransferFrom - CCTP transfers (EVM): the mint recipient on the destination chain. A transfer to Solana mints to a token account rather than a wallet, so it doesn’t count toward EVM recipients
- Tron contract calls: TRX sent with a contract call counts toward the contract itself
T…).
Amounts add up across the whole transaction, so a batch of several calls (for example an Account Abstraction user operation) that each stay under the cap is still blocked when together they go over it.
Supported chains
- EVM chains — Ethereum, Sepolia, Polygon, Base, and Monad (mainnet and testnet) out of the box; amount extraction works on any
eip155chain - Solana — mainnet and devnet
- Tron — mainnet, Shasta, and Nile testnets
How enforcement behaves
All enabled policies in an environment are evaluated for every transaction. If any policy’s rule matches, the transaction is blocked; if none match, the transaction proceeds. There’s no allowlist mode in this version. Policies are purely additive blockers. When a policy blocks a transaction, the request fails with HTTP400 and no signature is ever produced. Both POST /v1/assets/send and POST /v1/sign on the Enclave MPC API return the same body:
POLICY_AMOUNT_LIMIT_EXCEEDED identifier rather than on the message text. Responses also carry a legacy numeric code, which is deprecated.
For Account Abstraction clients, policies also run when Portal builds the user operation. When one blocks it, build-user-operation returns HTTP 403 with the same identifier and the policy that blocked it:
403 with the id POLICY_VIOLATION instead.
Managing policies on the dashboard
Step 1: Click on “Policies” in the left sidebar, under Configuration. Step 2: Click “Create policy,” choose a chain and token, set your per-transaction cap, optionally add recipients, and save. Each policy holds one rule. Once created, a policy appears in your list with a toggle and a delete action:- Toggle — enable or disable the policy without deleting it. Disabled policies are not evaluated.
- Delete — permanently remove the policy.
Scope & caveats
Policy Engine v1 is intentionally scoped. A few things to keep in mind:- Per-transaction only. Limits are compared against a single transaction’s amount. Velocity or cumulative limits (e.g. “no more than $1,000 per day”) are on the roadmap but not yet available.
- Direct transfers are covered, not everything that moves value. Token limits inspect direct
transfer/transferFromcalls on EVM and Tron, and SPL transfers on Solana, bothTransferCheckedand plainTransfersent from a wallet’s associated token account. Value moved through arbitrary contract calls, approve-then-pull flows, or non-standard token accounts is not currently inspected. - Raw-signed payloads can’t be policy-checked. If your integration signs an opaque hash rather than a structured transaction, Portal has no transaction contents to evaluate against a policy, by design.