Skip to content

Policies

Stendar exposes two complementary public policy surfaces:

  • a Policy v2 decision contract in @stendar/policy-contracts
  • a PolicyEngine execution policy layer in @stendar/core for raw runtime users

Policy v2 lives in @stendar/policy-contracts and defines the shared decision semantics used by public runtime policy adapters.

Each evaluation returns one of:

  • allow
  • deny
  • review_required
  • approval_required
  • blocked_until_evidence

Fail-closed behavior means unknown, malformed, or out-of-policy evaluations must not auto-allow money-affecting execution.

Legacy local selectors/adapters are retained as compatibility inputs into Policy v2 evidence and normalization. They are not a separate product policy identity.

PolicyEngine and PolicyRule in @stendar/core remain the execution-engine policy layer for direct DeFiRuntime usage.

Rule order matters. Any deny short-circuits immediately.

  • spending_limit: cap per-transaction and/or daily USD amount
  • require_approval: gate intents above threshold
  • rate_limit: max transaction count in rolling window
  • protocol_allowlist: permit only selected providers/protocol IDs
  • token_allowlist: permit only selected token identifiers
  • max_slippage: reject quotes above slippage threshold
  • max_drawdown: reject when drawdown exceeds configured percent
  • portfolio_exposure: cap token or protocol concentration
  • time_window: allow only specific UTC days/hours
import type { PolicyRule } from '@stendar/core';
const policies: PolicyRule[] = [
{
id: 'daily-usd-cap',
type: 'spending_limit',
enabled: true,
maxDaily: 5000,
currency: 'USD',
},
{
id: 'max-slippage',
type: 'max_slippage',
enabled: true,
maxSlippageBps: 100,
},
{
id: 'core-hours',
type: 'time_window',
enabled: true,
allowedWindows: [
{ daysOfWeek: [1, 2, 3, 4, 5], startHourUTC: 12, endHourUTC: 22 },
],
},
];
import type { PolicyRule } from '@stendar/core';
const advancedPolicies: PolicyRule[] = [
{
id: 'manual-approval-large',
type: 'require_approval',
enabled: true,
aboveAmount: 2_000,
currency: 'USD',
},
{
id: 'burst-limit',
type: 'rate_limit',
enabled: true,
maxTransactions: 5,
windowMs: 60_000,
},
{
id: 'protocol-allowlist',
type: 'protocol_allowlist',
enabled: true,
allowedProtocols: ['jupiter', 'kamino', 'lifi'],
},
{
id: 'protocol-exposure-cap',
type: 'portfolio_exposure',
enabled: true,
scope: 'protocol',
maxExposurePercent: 40,
},
{
id: 'drawdown-circuit-breaker',
type: 'max_drawdown',
enabled: true,
maxDrawdownPercent: 15,
},
];

Attach these to runtime config:

const runtime = new DeFiRuntime({ chains, providers, wallet, policies });

Subscribe to policy:decision events to capture allow/deny reasons and feed Notifications.

  • Public runtime adapters can evaluate against Policy v2 decision contracts.
  • Raw runtime paths enforce PolicyRule[] through PolicyEngine.
  • Compatibility adapters bridge legacy selector inputs into Policy v2 and runtime evidence while APIs stabilize.