Skip to main content
Apps can use Privy policies to restrict which Earn actions a wallet or signer can take. For Earn, Privy evaluates policies against the original request body sent to the deposit and withdraw endpoints before it prepares the underlying approval and vault transactions. That means Earn rules should match request-body fields like vault_id, amount, and raw_amount.

Supported methods

Earn policies currently support these rule methods:
  • earn_deposit
  • earn_withdraw
If a wallet policy only allows eth_sendTransaction, Earn requests will still be denied. Wallets that call the Earn endpoints need explicit earn_deposit and/or earn_withdraw rules.

Supported conditions

Earn rules support action_request_body conditions for the fields below:
Field sourceFieldSupported operatorsNotes
action_request_bodyvault_ideq, in, in_condition_setMatches the Privy vault ID from the Dashboard.
action_request_bodyamounteq, gt, gte, lt, lteValue must be a positive decimal string, such as “1.5”.
action_request_bodyraw_amounteq, gt, gte, lt, lteValue must be an integer string in base units, such as “1500000”.
Earn rules also support shared system conditions, such as current_unix_timestamp, for time-based controls.
Earn policies use chain_type: "ethereum". For Earn methods, the policy engine only accepts action_request_body and system conditions.

Choose amount or raw_amount

Use amount if your app sends human-readable decimal values like "1.5". Use raw_amount if your app sends base-unit values like "1500000".
A single rule cannot condition on both amount and raw_amount. An Earn request includes one or the other, never both.
This also affects runtime matching:
  • A rule using amount will not match a request that only sends raw_amount.
  • A rule using raw_amount will not match a request that only sends amount.
Keep your policy format aligned with the request format your application actually sends.

Example

The example below allows:
  • deposits into one approved vault up to 1000 units of the asset
  • withdrawals from that same vault
After creating the policy, apply it to the wallet with policy_ids. For signer-specific Earn permissions, attach the policy as an override policy on a signer instead.
const policy = await privy.policies().create({
  name: 'Approved earn vault policy',
  version: '1.0',
  chain_type: 'ethereum',
  rules: [
    {
      name: 'Allow deposits up to 1000 into approved vault',
      method: 'earn_deposit',
      action: 'ALLOW',
      conditions: [
        {
          field_source: 'action_request_body',
          field: 'vault_id',
          operator: 'eq',
          value: '<your-vault-id>',
        },
        {
          field_source: 'action_request_body',
          field: 'amount',
          operator: 'lte',
          value: '1000.0',
        },
      ],
    },
    {
      name: 'Allow withdrawals from approved vault',
      method: 'earn_withdraw',
      action: 'ALLOW',
      conditions: [
        {
          field_source: 'action_request_body',
          field: 'vault_id',
          operator: 'eq',
          value: '<your-vault-id>',
        },
      ],
    },
  ],
});

await privy.wallets().update('<wallet-id>', {
  policy_ids: [policy.id],
});
If the wallet has an owner_id, the wallet update must be authorized by that owner.

Common patterns

  • Restrict deposits to one vault by matching vault_id.
  • Reuse one rule across many vaults with vault_id: in or vault_id: in_condition_set.
  • Enforce maximum deposit or withdrawal size with amount or raw_amount.
  • Add time-based controls with system.current_unix_timestamp.

Next steps

Create a policy

Learn more about creating and managing policy objects.

Conditional policies per signer

Apply different Earn permissions to different signers on the same wallet.