> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Rule examples

> Copyable policy rules for transaction limits, spend limits, destinations, tokens, networks, wallet actions, approvals, and whole layers.

> [!NOTE]
>
> Declarative rules are in **early access** and are not enabled by default. [Talk to us](https://www.dynamic.xyz/talk-to-us) if you'd like to participate.

Each example below is one rule, ready to copy and adjust. For what each field means, see [Rule anatomy](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/rule-anatomy.md), and for how rules combine, read [Declarative rules](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/declarative-rules.md). The JSON is what the rule templates in the Dynamic demo produce. Before you save one:

* Replace the `ruleId` with your own UUID. The ones here are placeholders.
* Amounts are strings in the token's smallest unit. USDC has 6 decimals, so 100 USDC is `"100000000"`. ETH has 18 decimals, so 5 ETH is `"5000000000000000000"`.
* Token addresses are per network. The examples use Ethereum mainnet: USDC is `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` and USDT is `0xdAC17F958D2ee523a2206206994597C13D831ec7`.

## Limit per transaction

Deny any transaction on an EVM chain that moves more than 5 ETH. The comparison is `gt`, so exactly 5 ETH still goes through.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000001",
  "name": "Cap at 5 ETH",
  "phase": "transaction",
  "then": "DENY",
  "when": {
    "all": [
      { "field": "operation.chain", "op": "eq", "value": "EVM" },
      {
        "exists": {
          "in": "outgoingAssets",
          "where": {
            "all": [
              { "field": "asset.isNative", "op": "eq", "value": true },
              { "field": "totalRawValue", "op": "gt", "value": "5000000000000000000" }
            ]
          }
        }
      }
    ]
  }
}
```

## Spend limit over time

Deny a transaction on an EVM chain once the wallet has moved more than 5,000 USDC in the last day. The window's total already includes the transaction being checked. Durations are written like `1.day`, `2.hours`, `90.seconds`, or `1.month`, and a month is 30 days.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000003",
  "name": "Daily USDC cap",
  "phase": "transaction",
  "then": "DENY",
  "when": {
    "all": [
      { "field": "operation.chain", "op": "eq", "value": "EVM" },
      {
        "exists": {
          "in": "spendWindows",
          "where": {
            "all": [
              { "field": "type", "op": "eq", "value": "rolling" },
              { "field": "duration", "op": "eq", "value": "1.day" },
              { "field": "asset.address", "op": "eq", "value": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
              { "field": "totalRawValue", "op": "gt", "value": "5000000000" }
            ]
          }
        }
      }
    ]
  }
}
```

## Control where money can go

Block one address. This reads `counterparties`, which is every address the transaction touches, so it also catches the address when it is the contract being called or a spender being approved.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000004",
  "name": "Blocked address",
  "phase": "transaction",
  "then": "DENY",
  "when": {
    "all": [
      { "field": "operation.chain", "op": "eq", "value": "EVM" },
      {
        "exists": {
          "in": "counterparties",
          "where": { "field": "address", "op": "in", "value": ["0x0000000000000000000000000000000000000bad"] }
        }
      }
    ]
  }
}
```

Only pay approved vendors. `nin` means "is not one of", so this denies a transaction that touches any address outside the list. It reads `effectiveCounterparties`, which leaves out gas infrastructure you did not choose, such as a bundler or paymaster.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000005",
  "name": "Approved vendors only",
  "phase": "transaction",
  "then": "DENY",
  "when": {
    "all": [
      { "field": "operation.chain", "op": "eq", "value": "EVM" },
      {
        "exists": {
          "in": "effectiveCounterparties",
          "where": { "field": "address", "op": "nin", "value": ["0x5f09B2caaafD345EaE7B711A32CcBdf59befB4bB"] }
        }
      }
    ]
  }
}
```

> [!WARNING]
>
> A token transfer also touches the token contract. To let USDC reach a vendor through this rule, add the USDC contract and its implementation to the list too. See [Destinations and tokens](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/advanced-conditions.md#destinations-and-tokens).

## Control which tokens move

Deny a transaction on an EVM chain that moves anything other than USDC, USDT, or ETH. The `asset.isNative` comparison keeps the network's own coin permitted.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000006",
  "name": "Approved assets only",
  "phase": "transaction",
  "then": "DENY",
  "when": {
    "all": [
      { "field": "operation.chain", "op": "eq", "value": "EVM" },
      {
        "exists": {
          "in": "outgoingAssets",
          "where": {
            "all": [
              { "field": "asset.isNative", "op": "eq", "value": false },
              {
                "field": "asset.address",
                "op": "nin",
                "value": ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xdAC17F958D2ee523a2206206994597C13D831ec7"]
              }
            ]
          }
        }
      }
    ]
  }
}
```

## Restrict by chain or network

Require one admin's approval for every transaction on Ethereum mainnet. Approval fields are described in [Rule anatomy](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/rule-anatomy.md#approval-requirements).

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000007",
  "name": "Mainnet needs approval",
  "phase": "transaction",
  "then": "REQUIRE_APPROVAL",
  "when": {
    "all": [
      { "field": "operation.chain", "op": "eq", "value": "EVM" },
      { "field": "chain.id", "op": "in", "value": [1] }
    ]
  },
  "approvalRequirements": [
    { "id": "approval-1", "v": 1, "requiredApprovals": 1, "eligibleApproverRoles": ["admin"] }
  ]
}
```

On all chains, require one admin's approval for every transaction. A condition of `{ "always": true }` matches everything, so, like the fallback, this rule must be last in the list, and it cannot share a layer with a `DENY` fallback. To allow or deny every transaction instead, use the fallback.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000008",
  "name": "Everything needs approval",
  "phase": "transaction",
  "then": "REQUIRE_APPROVAL",
  "when": { "always": true },
  "approvalRequirements": [
    { "id": "approval-1", "v": 1, "requiredApprovals": 1, "eligibleApproverRoles": ["admin"] }
  ]
}
```

## Wallet actions

Require one admin's approval before the private key is exported.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000009",
  "name": "Export needs approval",
  "phase": "operation",
  "then": "REQUIRE_APPROVAL",
  "when": { "field": "operation.type", "op": "eq", "value": "exportPrivateKey" },
  "approvalRequirements": [
    { "id": "approval-1", "v": 1, "requiredApprovals": 1, "eligibleApproverRoles": ["admin"] }
  ]
}
```

Protect delegated access from being revoked.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000012",
  "name": "No revoking access",
  "phase": "operation",
  "then": "DENY",
  "when": { "field": "operation.type", "op": "eq", "value": "revocation" }
}
```

Stop signing from the client.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000010",
  "name": "No client signing",
  "phase": "operation",
  "then": "DENY",
  "when": { "field": "operation.type", "op": "eq", "value": "clientSigning" }
}
```

## Require approval for large transfers

Hold any transaction that moves more than 10,000 USDC on an EVM chain until two people with the `admin` or `cfo` role approve it within 24 hours.

```json theme={"system"}
{
  "ruleId": "00000000-0000-4000-8000-000000000002",
  "name": "Large USDC needs approval",
  "phase": "transaction",
  "then": "REQUIRE_APPROVAL",
  "when": {
    "all": [
      { "field": "operation.chain", "op": "eq", "value": "EVM" },
      {
        "exists": {
          "in": "outgoingAssets",
          "where": {
            "all": [
              { "field": "asset.address", "op": "eq", "value": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
              { "field": "totalRawValue", "op": "gt", "value": "10000000000" }
            ]
          }
        }
      }
    ]
  },
  "approvalRequirements": [
    {
      "id": "approval-1",
      "v": 1,
      "requiredApprovals": 2,
      "eligibleApproverRoles": ["admin", "cfo"],
      "completeWithinSeconds": 86400
    }
  ]
}
```

## A whole layer in deny style

Block one address and cap transactions at 5 ETH. There is no fallback, so everything else goes through.

```json theme={"system"}
[
  {
    "ruleId": "00000000-0000-4000-8000-000000000004",
    "name": "Blocked address",
    "phase": "transaction",
    "then": "DENY",
    "when": {
      "exists": {
        "in": "counterparties",
        "where": { "field": "address", "op": "in", "value": ["0x0000000000000000000000000000000000000bad"] }
      }
    }
  },
  {
    "ruleId": "00000000-0000-4000-8000-000000000001",
    "name": "Cap at 5 ETH",
    "phase": "transaction",
    "then": "DENY",
    "when": {
      "exists": {
        "in": "outgoingAssets",
        "where": {
          "all": [
            { "field": "asset.isNative", "op": "eq", "value": true },
            { "field": "totalRawValue", "op": "gt", "value": "5000000000000000000" }
          ]
        }
      }
    }
  }
]
```

## A whole layer in allow style

Allow transactions on an EVM chain that move at most 100 USDC, and refuse everything else with the `DENY` fallback.

```json theme={"system"}
[
  {
    "ruleId": "00000000-0000-4000-8000-000000000011",
    "name": "Up to 100 USDC",
    "phase": "transaction",
    "then": "ALLOW",
    "when": {
      "all": [
        { "field": "operation.chain", "op": "eq", "value": "EVM" },
        {
          "exists": {
            "in": "outgoingAssets",
            "where": {
              "all": [
                { "field": "asset.address", "op": "eq", "value": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
                { "field": "totalRawValue", "op": "lte", "value": "100000000" }
              ]
            }
          }
        }
      ]
    }
  },
  {
    "ruleId": "00000000-0000-4000-8000-000000000099",
    "phase": "transaction",
    "then": "DENY",
    "when": { "always": true }
  }
]
```

This allow rule matches when any one asset in the transaction is 100 USDC or less, and it says nothing about destinations. To require that every asset qualifies, use the `not exists` pattern in [Matching every item](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/advanced-conditions.md#matching-every-item).

## Next steps

> **[Advanced conditions](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/advanced-conditions.md)**
>
> Operators, lists, matching every item, and combined flows.

> **[Rule anatomy](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/rule-anatomy.md)**
>
> Rule fields, the fallback rule, and approval requirements.

> **[Declarative rules](https://www.dynamic.xyz/docs/embedded-wallets/mpc/policies/declarative-rules.md)**
>
> How rules, the fallback, and the allow and deny styles work.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.