Skip to main content
In a React app, the signed-in user grants access in the Para Portal, and your server signs while they are away. useSigningDelegation from @getpara/react-sdk opens the grant page and returns the user’s decision.

What signing delegation does

A Request lets your app sign a kind of transaction without a prompt, but only while the user is signed in to your app. Signing delegation lets your server sign for a user after their session ends, for recurring buys, subscriptions or top-ups.
  • The user grants one version of one Request on one wallet, until an expiry they choose. The expiry cannot be later than the maximum you set on the Request, and the maximum cannot be more than 90 days.
  • While the grant is active, your backend signs with that wallet through the REST API and your secret API key. It stores no user session and shows no prompt.
  • Para checks every request against your active policies. A request signs only when a rule in the granted Request allows it. Para refuses every other request with 403 and the code SIGNING_GRANT_REQUIRED, and sends nothing to the user for review.
  • The user can revoke the grant at any time. The grant also ends at its expiry, and when that version of the Request stops being active.
A grant and a consent answer are separate. A grant covers only what your server signs with your secret API key, and the user’s consent answer still decides what your app signs in their session.

Before you start

Signing delegation needs Permissions on your API key, a wallet that can hold a grant, and a client app where the user is signed in.
  • Permissions must be on for your API key: it needs at least one active policy, and its app needs a project. Otherwise, signing on a user-owned wallet returns 403 FORBIDDEN.
  • The wallet must be created under your API key, and Para must hold its share. That is the case when Para keeps the user’s shares in its enclave, or when your app created the wallet, or migrated its share, through the REST API before a user claimed it. For any other wallet, the grant page shows Signing while you are away is not available for this wallet yet., and your app receives the error code SIGNING_GRANT_WALLET_NOT_ELIGIBLE.
  • The user grants access from a JavaScript client: the web SDKs, the React SDKs or the React Native SDK. The Swift and Flutter SDKs cannot open the grant page yet.
  • Your server signs with your secret API key, through the REST API.

Turn it on for a Request

Signing delegation is a setting on a Request. It is off by default. Turning it on lets users grant access, and does not give your server access by itself.
  1. On your Development key, open Permissions, select the Requests tab, and select Add or New Request.
  2. Write the Request as usual. On the policy step, turn on Allow signing while the user is away.
  3. In Maximum signing grant duration, enter a number and choose seconds, minutes, hours or days. Users can choose a shorter period. The maximum is 90 days.
  4. Select Review. The review shows Signing while away as Enabled, with the Maximum Grant Duration. Select Save Draft, then Activate on the draft.
A Request with signing delegation goes through the same production review as any other policy.
Activating an edited version of a Request, or turning the Request off, ends every grant on the old version at once. Your server cannot sign for those users until each of them grants the active version.Turning the Request back on does not bring the old grants back. Before you turn off a Request that allows signing delegation, the Developer Portal asks you to confirm with Turn off and stop grants.

How a grant works

The user grants access on a Para Portal page that your app opens. Para records one grant for the user, wallet, Request version and expiry, under the API key your app used. Only that API key’s secret can sign under the grant.

Expiry and renewal

The user sets the expiry on the grant page, and can extend it later without waiting for it to end.
  • The grant page suggests the Request’s maximum, or the requestedExpiresAt your app passes, capped at the maximum. The user can choose any time between now and the maximum.
  • The maximum counts from the moment of granting. With a 90-day maximum, a grant made on 1 March can last until 30 May.
  • Renew replaces an active grant with a new one, whose expiry counts from the renewal. Para marks the old grant superseded.
  • The user can reauthorize an expired grant with a new expiry, as long as the same Request version is still active.
  • A wallet holds at most one active grant for each Request. A user who already has one sees Continue with existing access and Renew signing access instead of a new grant.

When a grant ends

A grant ends when it expires, when the user revokes it, when its Request version stops being active, or when the user changes their adjustable values for that Request.
Para checks the grant again just before the wallet starts signing. A request that has not reached that check when the grant ends is refused. A request that has already passed it can still complete.
Your server has no route that lists a user’s grants. Store the expiresAt your app receives when the user grants access, and remind the user to renew before it. When signing returns 403 FORBIDDEN, treat the grant as ended.

What the user sees

Your app opens the grant page in the Para Portal. The user signs in to the Portal if they need to.
1

Review the access

The page asks Allow to act while you are away? and shows the wallet and your Request’s description. It explains: ” can request signatures without asking you to return or sign in again, but only for the authority shown below.” It lists any adjustable values, the Maximum duration and the Request’s rules under See Details.
2

Choose an expiry

The Allow access until field holds the suggested expiry. The user can move it earlier, but not past the maximum.
3

Decide

The user selects Allow signing while I am away or Not now. The page notes: “You can revoke this access at any time. Replacing or turning off the policy also stops it.”
The page changes when the user already has a grant for the Request: Under Your signing grants, the page lists the user’s other grants to your app on this wallet with their status. An active grant offers Renew and Revoke, and an expired one Reauthorize. To let users review or revoke access later, open the same page without a Request. It is titled Apps that can sign while you are away and lists only the grants. Give users a button for it in your app’s settings. Para hosts no other page where the user can revoke a grant.

How Para decides delegated requests

When your server signs a user-owned wallet with your secret API key, Para evaluates the request against your active policies, as for any other request. The result decides the response:

Considerations for your other policies

A delegated request goes through the same evaluation as any other request, with a few differences that affect how you write your policies.
  • Only the granted Request authorizes a delegated request. Other Requests the user accepted in your app, including with standing access, do not let your server sign, and their rules, including approval rules, do not apply. Put every limit you rely on in the granted Request.
  • A matching approval rule in the granted Request refuses the request instead of opening an approval. Keep approval tiers in Requests that users sign in your app.
  • A transaction that performs several actions, such as a Safe batch, signs only when one granted Request allows each of them.
  • Para’s defaults still apply. Para refuses a request it cannot read, or one that a rule cannot be checked against. Para skips a rule that depends on a detail it cannot decode, so that rule cannot allow the request either.
  • Guardrails govern app-owned wallets, so they do not apply to a granted wallet, which belongs to a user.
  • A wallet.spend.* budget belongs to the wallet and your API key. Transfers the user signs in your app and transfers your server signs under the grant count toward the same total.
  • A grant records the values the user had set for the Request’s adjustable parameters. When the user changes them, the grant ends and the user grants again.
While grants are active, your secret API key can sign for those users’ wallets within the granted Requests. Keep it on your server, and limit where it works with an IP allowlist.

Scenarios

Each automation pairs Request rules that cap what your server signs with a maximum duration that fits how often the user should renew.

Recurring investing

A user agrees to invest 50 USDC a week. Each week, your backend places an order with your broker for them. The user grants access once and renews at most every 90 days. Which rule you write depends on how the broker takes payment.

The broker takes an ERC-2612 permit

Many brokers take each order as a USDC permit that lets their order contract pull the payment. Para reads the permit’s token, amount and spender, so a Request can allow permits only to that contract, up to 50 USDC each and 50 USDC a week:
request-weekly-permit-investing.json
Para reads a permit only when it is an ERC-2612 Permit signed as typed data: primaryType is Permit, the type lists exactly owner and spender as address, then value, nonce and deadline as uint256, and the domain sets chainId and the token as verifyingContract. Para counts a permit toward the budget only when owner is the signing wallet.Other permit formats, such as DAI-style permits and Permit2, have no request.token.* facts, so this rule does not allow them. The budget counts the permit’s value when your server signs it, not what the spender later pulls, so include the broker’s fees in the amount.
A signed permit stays usable on-chain until its deadline, even after the user revokes the grant. A Request rule cannot limit the deadline, so set a short one when your server signs.

The broker takes a transfer

If the broker funds orders from a deposit address instead, allow USDC transfers to that address:
request-weekly-usdc-investing.json
The 168h window resets every Thursday at 00:00 UTC. Schedule the job so it runs once in each window.

Ask the user for access

Ask for access to one active Request version. Read the version and hash with useApplicablePolicy, then call requestSigningDelegationAsync. appId is your API key’s project ID, from para.partnerRecord.projectId.
Call requestSigningDelegationAsync from a click handler. The browser blocks a popup opened at any other time.
SigningAccessButton.tsx
The call resolves when the user finishes on the grant page or closes it: Pass requestedExpiresAt as an ISO 8601 timestamp to suggest a shorter expiry, such as the end of a promotion. The user can still change it, and the page caps it at the Request’s maximum.

Let users manage access

Call the same method with only appId and walletId to open the page that lists the user’s grants to your app, where they can renew or revoke each one:
On this page, renewing or revoking keeps the window open, so the call resolves with cancelled when the user closes it. Do not read a change from that result. Your server learns about a revocation from the 403 FORBIDDEN on its next signing request.

Without React

ParaWeb from @getpara/web-sdk has the same method. Call para.requestSigningDelegation(params) from a click handler; it takes the same parameters and resolves with the same outcome.

Sign from your server

Once the user has granted access, your backend signs with their wallet ID and your secret API key, through the same REST routes as for app-owned wallets: sign-transaction, sign-message, sign-typed-data, sign-raw, sign-authorization and transfer. You do not pass a grant ID. Para finds the active grant for the wallet on each request.
weekly-buy.ts
Handle each refusal in your job:
Send an Idempotency-Key with every scheduled request, built from the schedule and the period, so a retried job cannot sign the same payment twice.
Gas sponsorship (sponsoredGas), automatic retries (autoRetry) and estimate-fee work only with app-owned wallets. On a user-owned wallet they return 403, even with an active grant.

Sign a permit

For a broker that takes permits, sign each order’s permit with signTypedData and send the signature to the broker. Para reads the permit’s token, amount and spender from the typed data:
order-permit.ts
Read nonce from the token’s nonces(owner) before you sign, and keep deadline short. A permit outside the grant throws a ParaRestError with the code SIGNING_GRANT_REQUIRED.

Sign with viem

createParaDelegatedViemAccount from @getpara/rest-sdk/viem returns a viem account that signs messages and typed data through the REST API with your secret key. To reuse a client you already created, pass client instead of apiKey and env.
delegated-account.ts
The viem account sends no Idempotency-Key, so sign scheduled payments with the REST client instead. On Base and other OP Stack chains, viem passes the chain’s own transaction serializer, which the account rejects. Send transactions on those chains with the REST client’s transfer or signTransaction.