> ## 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.

# Known recipients and app contracts

> Ask users for standing access to transfers to known addresses and calls to your app's contract.

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>;
};

These templates ask the user for standing access to addresses your app already knows: the recipients it pays and the contract it calls. Anything outside the list still goes to the user for review. Replace the placeholder addresses with your own before you publish.

## Send ETH to known recipients

Use this when your app pays a fixed set of addresses, such as your own payout or escrow wallets. ETH transfers on Base to a listed address 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 ETH on Base to approved recipients`. In **Networks**, clear **Ethereum (1)**, select **Base (8453)**, and select **Continue**.
    3. Select **Transfer ETH**, then **Add Condition**. Keep **Recipient address**, choose **is one of**, and enter the addresses separated by commas.
    4. Select **Review**, then **Save Draft**, then **Activate** on the draft.
  </Tab>

  <Tab title="JSON">
    ```json request-known-recipients.json theme={null}
    {
      "id": "base-known-recipients",
      "schemaVersion": "permissions.policy.v1",
      "version": "1",
      "selector": {
        "walletType": "EVM",
        "chainId": "8453"
      },
      "rules": [
        {
          "id": "allow-known-recipients",
          "effect": "allow",
          "actions": ["transfer_native"],
          "when": {
            "kind": "all",
            "of": [
              { "kind": "compare", "fact": "request.classification", "op": "eq", "value": "native_transfer" },
              {
                "kind": "compare",
                "fact": "request.to",
                "op": "in",
                "value": ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
              }
            ]
          }
        }
      ],
      "metadata": {
        "productMode": "delegation",
        "description": "Send ETH on Base to approved recipients"
      }
    }
    ```
  </Tab>
</Tabs>

| Signing request | Result |
| - | - |
| Send ETH to `0x1111…1111` after the user approved | Signs without a prompt |
| Send ETH to an address outside the list | Goes to the user for review |

The rule sets no amount limit, so the user grants access to any amount sent to these addresses. To cap it, add a **Transaction amount** condition to the same action. A Request action holds up to 8 conditions, and a transfer must meet all of them.

<Check>
  Test it on your Development key: after the test user approves the consent screen, send ETH to a listed address and it signs without a prompt. A transfer to an unlisted address opens a review.
</Check>

## Call your app's contract

Use this when your app calls one function on its own contract for the user, such as minting an item. Calls to `mint` on the listed contract on Base 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 `Mint items from our contract on Base`. In **Networks**, clear **Ethereum (1)**, select **Base (8453)**, and select **Continue**.
    3. Select **Call a contract**. Enter the contract in **Contract Address** and `mint` in **Function Name**.
    4. Select **Review**. The Review step warns that no conditions are set, but the contract and function still limit the rule, as the **Normalized policy JSON** shows. Select **Save Draft**, then **Activate** on the draft.
  </Tab>

  <Tab title="JSON">
    ```json request-app-contract-calls.json theme={null}
    {
      "id": "base-app-contract-calls",
      "schemaVersion": "permissions.policy.v1",
      "version": "1",
      "selector": {
        "walletType": "EVM",
        "chainId": "8453"
      },
      "rules": [
        {
          "id": "allow-app-mint",
          "effect": "allow",
          "actions": ["call_contract"],
          "when": {
            "kind": "all",
            "of": [
              { "kind": "compare", "fact": "request.classification", "op": "eq", "value": "decoded_contract_call" },
              {
                "kind": "compare",
                "fact": "request.contract.address",
                "op": "eq",
                "value": "0x3333333333333333333333333333333333333333"
              },
              { "kind": "compare", "fact": "request.method", "op": "eq", "value": "mint" }
            ]
          }
        }
      ],
      "metadata": {
        "productMode": "delegation",
        "description": "Mint items from our contract on Base"
      }
    }
    ```
  </Tab>
</Tabs>

| Signing request | Result |
| - | - |
| Call `mint` on `0x3333…3333` after the user approved | Signs without a prompt |
| Call another function on the contract | Goes to the user for review |
| A call Para cannot decode | Goes to the user for review |

Para reads the function only from calls it can decode. The rule's `request.classification` check means a call Para cannot decode never matches, so it goes to the user for review instead of signing.

<Check>
  Test it on your Development key: after the test user approves, call `mint` and it signs without a prompt. A call to another function opens a review.
</Check>

<Tip>
  Each Request policy has its own consent screen, and the user sees one at a time. To ask once for both templates, put them in one policy: in the Developer Portal, select **Add Action** to add the second action, or combine both rules in one JSON policy.
</Tip>

## Publish your lists

Test recipients and contracts are often not the ones you use in production. Para applies the policies active on your Development key to production after a production review, so update the lists to your production addresses before you request it.

<PermissionsCards basePath="/v3/react/guides/permissions" pages={["templates/allowances", "testing"]} cols={2} />


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