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

# Transfer allowances

> Let small ETH transfers and a daily USDC budget sign from users' wallets without a prompt.

export const PermissionsCards = ({basePath, pages, cols = 2, horizontal = false}) => {
  const ImageCard = Card;
  const hrefOverrides = {
    "/v3/react/guides/permissions": {
      "conditional-approvals": "/v3/react/guides/conditional-approvals"
    },
    "/v3/rest/permissions": {
      "backend": "/v3/rest/permissions-administration"
    }
  };
  const guardrailBases = ["/v3/rest/permissions", "/v3/server/guides/permissions"];
  const ownership = guardrailBases.includes(basePath) ? 'guardrail' : 'request';
  const overviewImages = {
    "/v3/rest/permissions": {
      "imgUrl": "/images/v3/cards/rest-guardrails.png",
      "horizontalImgUrl": "/images/v3/cards/rest-guardrails-horizontal.png"
    },
    "/v3/server/guides/permissions": {
      "imgUrl": "/images/v3/cards/sdk-server-guardrail-signing.png",
      "horizontalImgUrl": "/images/v3/cards/sdk-server-guardrail-signing-horizontal.png"
    },
    "/v3/react/guides/permissions": {
      "imgUrl": "/images/v3/cards/sdk-get-policy-consent-url.png",
      "horizontalImgUrl": "/images/v3/cards/sdk-get-policy-consent-url-horizontal.png"
    },
    "/v3/react-native/guides/permissions": {
      "imgUrl": "/images/v3/cards/sdk-get-policy-consent-url.png",
      "horizontalImgUrl": "/images/v3/cards/sdk-get-policy-consent-url-horizontal.png"
    }
  };
  const registry = {
    overview: {
      title: "Permissions overview",
      description: "Return to the start of the Permissions path.",
      ...overviewImages[basePath]
    },
    "developer-portal": {
      title: "Create policies in the Developer Portal",
      description: "Build a policy with the Portal forms and activate it on a beta key.",
      imgUrl: "/images/v3/cards/developer-portal-policy-form.png",
      horizontalImgUrl: "/images/v3/cards/developer-portal-policy-form-horizontal.png"
    },
    "json": {
      title: "Write policy JSON",
      description: "Move to JSON for policies the forms cannot express.",
      imgUrl: "/images/v3/cards/developer-portal-policy-json.png",
      horizontalImgUrl: "/images/v3/cards/developer-portal-policy-json-horizontal.png"
    },
    "testing": {
      title: "Test your policies",
      description: "Exercise every rule on beta before you ship.",
      imgUrl: "/images/v3/cards/concept-policy-testing.png",
      horizontalImgUrl: "/images/v3/cards/concept-policy-testing-horizontal.png"
    },
    "production": {
      title: "Go to production",
      description: "Request a production review and publish your policy.",
      imgUrl: "/images/v3/cards/concept-policy-publication.png",
      horizontalImgUrl: "/images/v3/cards/concept-policy-publication-horizontal.png"
    },
    "conditional-approvals": {
      title: "Conditional approvals",
      description: "Require people to approve a request before it signs.",
      imgUrl: "/images/v3/cards/portal-conditional-approval-case.png",
      horizontalImgUrl: "/images/v3/cards/portal-conditional-approval-case-horizontal.png"
    },
    "approval-signatures": {
      title: "Collect approval signatures",
      description: "Collect signatures from approvers for multisig workflows.",
      imgUrl: "/images/v3/cards/sdk-get-approval-signatures.png",
      horizontalImgUrl: "/images/v3/cards/sdk-get-approval-signatures-horizontal.png"
    },
    "adjustable-parameters": {
      title: "Adjustable parameters",
      description: "Let users set their own limits and managers adjust approval settings.",
      imgUrl: "/images/v3/cards/portal-user-policy-limits.png",
      horizontalImgUrl: "/images/v3/cards/portal-user-policy-limits-horizontal.png"
    },
    "lifecycle": {
      title: "Manage the policy lifecycle",
      description: "Version, activate, replace and retire policies.",
      imgUrl: "/images/v3/cards/developer-portal-policy-versions.png",
      horizontalImgUrl: "/images/v3/cards/developer-portal-policy-versions-horizontal.png"
    },
    "backend": {
      title: "Manage permissions from your backend",
      description: "Assign approvers and read policy state with your server secret.",
      imgUrl: "/images/v3/cards/rest-permissions-administration.png",
      horizontalImgUrl: "/images/v3/cards/rest-permissions-administration-horizontal.png"
    },
    templates: ownership === "guardrail" ? {
      title: "Guardrail templates",
      description: "Start from a tested Guardrail policy.",
      imgUrl: "/images/v3/cards/concept-guardrail-templates.png",
      horizontalImgUrl: "/images/v3/cards/concept-guardrail-templates-horizontal.png"
    } : {
      title: "Request templates",
      description: "Start from a tested Request policy.",
      imgUrl: "/images/v3/cards/concept-request-templates.png",
      horizontalImgUrl: "/images/v3/cards/concept-request-templates-horizontal.png"
    },
    "guardrail:templates/spending-caps": {
      title: "Spending caps",
      description: "Cap native and token transfers per transaction or per day.",
      imgUrl: "/images/v3/cards/concept-spending-limits.png",
      horizontalImgUrl: "/images/v3/cards/concept-spending-limits-horizontal.png"
    },
    "guardrail:templates/allowlists": {
      title: "Recipient and contract allowlists",
      description: "Limit transfers and contract calls to addresses you know.",
      imgUrl: "/images/v3/cards/concept-recipient-allowlists.png",
      horizontalImgUrl: "/images/v3/cards/concept-recipient-allowlists-horizontal.png"
    },
    "guardrail:templates/approval-tiers": {
      title: "Approval thresholds and tiers",
      description: "Hold large transfers for approval, or deny the largest.",
      imgUrl: "/images/v3/cards/concept-approval-tiers.png",
      horizontalImgUrl: "/images/v3/cards/concept-approval-tiers-horizontal.png"
    },
    "guardrail:templates/treasury": {
      title: "Treasury approvals",
      description: "Deny unplanned actions and approve wallet or Safe payouts in stages.",
      imgUrl: "/images/v3/cards/concept-treasury-approvals.png",
      horizontalImgUrl: "/images/v3/cards/concept-treasury-approvals-horizontal.png"
    },
    "guardrail:templates/message-signing": {
      title: "Message and raw signing",
      description: "Block or hold raw signatures, and block permits.",
      imgUrl: "/images/v3/cards/concept-signing-actions.png",
      horizontalImgUrl: "/images/v3/cards/concept-signing-actions-horizontal.png"
    },
    "request:templates/allowances": {
      title: "Transfer allowances",
      description: "Let small transfers and a daily budget sign without a prompt.",
      imgUrl: "/images/v3/cards/concept-spending-limits.png",
      horizontalImgUrl: "/images/v3/cards/concept-spending-limits-horizontal.png"
    },
    "request:templates/recipients-and-contracts": {
      title: "Known recipients and app contracts",
      description: "Cover transfers to known addresses and your contract's calls.",
      imgUrl: "/images/v3/cards/concept-recipient-allowlists.png",
      horizontalImgUrl: "/images/v3/cards/concept-recipient-allowlists-horizontal.png"
    },
    "request:templates/cosigner-approval": {
      title: "Co-signer approval",
      description: "Send large transfers to a co-signer for approval.",
      imgUrl: "/images/v3/cards/portal-conditional-approval-case.png",
      horizontalImgUrl: "/images/v3/cards/portal-conditional-approval-case-horizontal.png"
    },
    "request:templates/adjustable-limits": {
      title: "User-adjustable limits",
      description: "Let each user choose their own spending limits.",
      imgUrl: "/images/v3/cards/portal-user-policy-limits.png",
      horizontalImgUrl: "/images/v3/cards/portal-user-policy-limits-horizontal.png"
    },
    "request:templates/message-signing": {
      title: "Message signing",
      description: "Sign messages from users' wallets without a prompt.",
      imgUrl: "/images/v3/cards/concept-signing-actions.png",
      horizontalImgUrl: "/images/v3/cards/concept-signing-actions-horizontal.png"
    }
  };
  const entryFor = slug => registry[slug] || registry[`${ownership}:${slug}`];
  const hrefFor = slug => {
    if (slug === 'overview') return basePath;
    const overrides = hrefOverrides[basePath] || ({});
    return overrides[slug] || `${basePath}/${slug}`;
  };
  return <CardGroup cols={cols}>
      {pages.map(slug => {
    const entry = entryFor(slug);
    return <ImageCard key={slug} title={entry.title} description={entry.description} href={hrefFor(slug)} imgUrl={horizontal ? entry.horizontalImgUrl : entry.imgUrl} horizontal={horizontal} />;
  })}
    </CardGroup>;
};

export const Card = ({imgUrl, compactImgUrl, title, description, href, horizontal = false, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  const handleClick = e => {
    e.preventDefault();
    if (newTab) {
      window.open(href, '_blank', 'noopener,noreferrer');
    } else {
      window.location.href = href;
    }
  };
  return <div className={`not-prose relative my-2 p-[1px] rounded-xl transition-all duration-300 ${isHovered && href ? 'bg-gradient-to-r from-[#FF4E00] to-[#874AE3]' : 'bg-gray-200'}`} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      <a href={href} onClick={href ? handleClick : undefined} className={`not-prose flex ${horizontal ? 'flex-row' : 'flex-col'} font-normal h-full bg-white overflow-hidden w-full ${href ? 'cursor-pointer' : 'cursor-default'} rounded-[11px] no-underline`}>
        {imgUrl && <div className={`relative overflow-hidden flex-shrink-0 ${horizontal ? 'w-[30%] rounded-l-[11px]' : 'w-full'}`} onClick={e => e.stopPropagation()}>
            <picture style={{
    display: 'contents'
  }}>
              {compactImgUrl && <source media="(max-width: 639px)" srcSet={compactImgUrl} />}
              <img src={imgUrl} alt={title} className="w-full h-full object-cover pointer-events-none select-none" draggable="false" />
            </picture>
            <div className="absolute inset-0 pointer-events-none" />
          </div>}
        <div className={`flex-grow px-6 py-5 ${horizontal ? 'w-[70%]' : 'w-full'} flex flex-col ${horizontal && imgUrl ? 'justify-center' : 'justify-start'}`}>
          {title && <h2 className="font-semibold text-base text-gray-800 m-0">{title}</h2>}
          {description && <div className={`font-normal text-gray-500 re leading-6 ${horizontal || !imgUrl ? 'mt-0' : 'mt-1'}`}>
              <p className="m-0 text-xs">{description}</p>
            </div>}
        </div>
      </a>
    </div>;
};

An allowance lets your app spend small amounts from a user's wallet without a prompt for every transfer. The user approves the allowance once, and anything above it still goes to them for review.

<Note>
  Native limits count positive native value: on EVM from any transaction, contract calls included, and on Solana, Cosmos, Stellar and Sui from native transfers. Token limits count ERC-20 `transfer` calls on EVM, including ERC-20 transfers sent through Para gas sponsorship, and token transfers on Solana, Cosmos and Stellar. Sui has no token limits. Gas and fees never count. Apart from those sponsored transfers, smart account user operations do not count toward EVM limits. A token limit that names an asset counts only that asset. Each network, asset and window has its own budget, so a limit of 1 ETH per day on Ethereum and Base allows 1 ETH per day on each network. Payments a Safe makes count only toward the Safe limits, `safe.spend.native` and `safe.spend.erc20`, which keep one budget per Safe. See [Metered facts](/v3/references/permissions/facts#metered-facts) for the full rules.
</Note>

## Allow small ETH transfers

Use this for frequent, low-value payments, such as tips or in-game purchases. ETH transfers on Base of up to 0.01 ETH sign without a prompt once the user approves.

<Tabs>
  <Tab title="Developer Portal">
    1. On your **Development** key, open **Permissions**, select the **Requests** tab, and select **Add** or **New Request**.
    2. In **User consent request language**, enter `Send up to 0.01 ETH per transfer on Base`. In **Networks**, clear **Ethereum (1)**, select **Base (8453)**, and select **Continue**.
    3. Select **Transfer ETH**. Select **Add Condition**, change the condition to **Transaction amount**, keep **is at most** and **per transaction**, and enter `0.01` with the unit set to **ETH**.
    4. Select **Review**, then **Save Draft**, then **Activate** on the draft.
  </Tab>

  <Tab title="JSON">
    ```json request-small-native-transfers.json theme={null}
    {
      "id": "base-small-native-transfers",
      "schemaVersion": "permissions.policy.v1",
      "version": "1",
      "selector": {
        "walletType": "EVM",
        "chainId": "8453"
      },
      "rules": [
        {
          "id": "allow-small-native-transfers",
          "effect": "allow",
          "actions": ["transfer_native"],
          "when": {
            "kind": "all",
            "of": [
              { "kind": "compare", "fact": "request.classification", "op": "eq", "value": "native_transfer" },
              { "kind": "compare", "fact": "request.value.baseUnits", "op": "lte", "value": "10000000000000000" }
            ]
          }
        }
      ],
      "metadata": {
        "productMode": "delegation",
        "description": "Send up to 0.01 ETH per transfer on Base"
      }
    }
    ```
  </Tab>
</Tabs>

| Signing request | Result |
| - | - |
| Send 0.005 ETH after the user approved the allowance | Signs without a prompt |
| Send 0.05 ETH | Goes to the user for review |
| Send 0.005 ETH after the user chose **Manually approve each transaction instead** | Goes to the user for review |
| A token transfer or contract call | Goes to the user for review, because this policy does not cover it |

<Check>
  Test it on your Development key: send 0.005 ETH from a test user's wallet and approve the consent screen, then the transfer. Send 0.005 ETH again and it signs without a prompt. A 0.05 ETH transfer still opens a review.
</Check>

## Allow a daily USDC budget

Use this when the user should set aside a fixed amount of USDC per day for your app, such as for subscriptions or automated payments. USDC transfers on Base sign without a prompt until the day's total would pass 100 USDC. USDC has 6 decimals, so the budget is `100000000`.

<Tabs>
  <Tab title="Developer Portal">
    The form saves the same allowance without the `asset` field. Its rule already pins the USDC contract, so only USDC counts toward the budget either way.

    1. On your **Development** key, open **Permissions**, select the **Requests** tab, and select **Add** or **New Request**.
    2. In **User consent request language**, enter `Send up to 100 USDC per day on Base`. In **Networks**, clear **Ethereum (1)**, select **Base (8453)**, and select **Continue**.
    3. Select **Transfer tokens** and enter `0x833589fcd6edb6e08f4c7c32d4f71b54bda02913` in **Contract Address**. **Function Name** is fixed to `transfer`.
    4. Select **Add Condition**, change the condition to **Transaction amount**, choose **per time window** with `24` **hours**, keep **is at most**, and enter `100000000` token base units.
    5. Select **Review**, then **Save Draft**, then **Activate** on the draft.
  </Tab>

  <Tab title="JSON">
    ```json request-daily-usdc-allowance.json theme={null}
    {
      "id": "base-usdc-daily-allowance",
      "schemaVersion": "permissions.policy.v1",
      "version": "1",
      "selector": {
        "walletType": "EVM",
        "chainId": "8453"
      },
      "rules": [
        {
          "id": "allow-daily-usdc",
          "effect": "allow",
          "actions": ["transfer_tokens"],
          "when": {
            "kind": "all",
            "of": [
              { "kind": "compare", "fact": "request.classification", "op": "eq", "value": "erc20_transfer" },
              {
                "kind": "compare",
                "fact": "request.contract.address",
                "op": "eq",
                "value": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"
              },
              { "kind": "compare", "fact": "request.method", "op": "eq", "value": "transfer" },
              {
                "kind": "aggregate",
                "fact": "wallet.spend.erc20",
                "op": "lte",
                "value": "100000000",
                "window": "24h",
                "asset": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"
              }
            ]
          }
        }
      ],
      "metadata": {
        "productMode": "delegation",
        "description": "Send up to 100 USDC per day on Base"
      }
    }
    ```
  </Tab>
</Tabs>

The budget resets at 00:00 UTC. It belongs to the wallet, not the policy, so two policies that meter USDC on Base over the same window share one daily total.

| Signing request | Result |
| - | - |
| Transfer 30 USDC with 50 USDC sent today | Signs without a prompt |
| Transfer 30 USDC with 80 USDC sent today | Goes to the user for review |
| Transfer another ERC-20 token | Goes to the user for review |

To show what is left today, read the policy's usage with `getUserPolicyUsage`. Each meter returns `usedBaseUnits`, `remainingBaseUnits` and `resetAt`.

<Check>
  Test it on Base Sepolia with a lower budget: set `chainId` to `84532`, change both USDC addresses to `0x036cbd53842c5426634e7929541ec2318f3dcf7e`, and set the budget to `1000000` (1 USDC). After consent, a 0.6 USDC transfer signs without a prompt and a second one opens a review.
</Check>

## Publish your allowances

The consent screen shows your **User consent request language** and each rule, so check that both read well before you request a production review. Production is a separate environment, so production users see the consent screen there the first time a matching request arrives.

<CardGroup cols={1}>
  <Card title="Spend facts and windows" description="Which transfers each spend fact counts, and how budgets are shared." href="/v3/references/permissions/facts" imgUrl="/images/v3/cards/concept-policy-facts-horizontal.png" horizontal />
</CardGroup>

<PermissionsCards basePath="/v3/react-native/guides/permissions" pages={["testing", "templates/adjustable-limits", "production"]} cols={3} />


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