User approval
Before your builder can charge a user, the user must approve it. The approval sets the maximum fee rate your builder may charge them. One approval covers both perpetuals and options.
The approval is signed by the user's wallet (the account owner), not by an API signing key. Your app can't create it for them.
There are two ways to get the approval:
In your app (recommended for web apps): the user signs one wallet prompt inside your app. No Aevo page and no Aevo API key are needed.
Approval link: send the user to a page on the Aevo app, optionally with a link back to your app.
Option 1: Sign in your app
If your app has the user's wallet connected, ask the wallet to sign the ApproveBuilder typed data and submit the signature to POST /builder/approve, together with the user's account. The wallet signature authorises the approval on its own, so you don't need an API key for the user.
With the TypeScript SDK and a browser wallet (viem / wagmi):
import { AevoClient, getApproveBuilderTypedData } from "@aevo/sdk";
const typedData = getApproveBuilderTypedData({
env: "mainnet",
account, // the user's address (checksum)
builderId: "builder_0123456789abcdef",
maxFeeBps: "5",
});
const signature = await walletClient.signTypedData({ account, ...typedData });
await new AevoClient({ env: "mainnet" }).submitApproveBuilder({
builderId: "builder_0123456789abcdef",
maxFeeRate: "0.0005",
nonce: typedData.message.nonce,
signature,
account,
});Or with an ethers signer: await client.approveBuilderWithSigner(signer, { builderId, maxFeeBps: "5" }).
The rest of this section describes the typed data and request, if you build them yourself.
EIP-712 domain
name
Aevo Mainnet
Aevo Testnet
version
1
1
chainId
1
11155111
The domain has no verifyingContract. It is the same domain used for other Aevo account signatures.
Type
account
The user's account address
builderId
Your builder_id, for example builder_0123456789abcdef
maxFeeRate
Raw 6-decimal integer: 0.0005 (5 bps) → 500
nonce
Current Unix time in milliseconds
Submit
POST /builder/approve, with the wallet signature and the user's account. No API key is needed.
If you do send the user's API key (AEVO-KEY / AEVO-SECRET), account is optional; if you send both, they must be the same account.
max_fee_rate is the decimal string in the request body, and the raw integer (500) in the signed message. account must be in EIP-55 checksum form.
Rules:
max_fee_ratemust be at or belowmax_fee_rate_perpsfromGET /builder-config, which is 5 bps (0.0005). Anything higher is rejected withBUILDER_FEE_EXCEEDS_AEVO_LIMIT.noncemust be the current time: no more than 5 minutes old and no more than 30 seconds in the future. It must also be greater than any earlier approval or revocation for this user and builder. Sign it right before submitting.The builder must be
ACTIVE.
To change the maximum, the user signs a new approval with a new nonce. It replaces the old one.
Option 2: Approval link
Send the user to the Aevo app. They review your builder's name and the maximum fee, and sign with their wallet:
On testnet, use
https://testnet.aevo.xyz.max_fee_rateis a decimal fraction, for example0.0005for 5 bps.You can copy a ready-made link (and QR code) from Settings → Builders → Builder Dashboard → Get users to approve you.
redirect_uriis optional and must be anhttps://URL (http://localhostfor development). Percent-encode the whole value (for example withencodeURIComponent), or any&,?or#in your URL will break the link:The approval page shows the user where they'll return, and sends them back only when they click. Aevo adds the result to the query string:
builder_approval=approved&builder_id=<builder_id>builder_approval=cancelledbuilder_approval=error&error=<code>, where<code>is a stable code:USER_REJECTED(the user declined the wallet prompt),UNKNOWN_BUILDER,BUILDER_NOT_ACTIVE,INVALID_FEE_RATEorINVALID_REQUEST(bad link parameters), an Aevo API error such asBUILDER_NOT_ACTIVEorBUILDER_INVALID_NONCE,WALLET_ERROR_<n>for other wallet errors, orUNKNOWN.
Treat the query string as a hint only. To confirm, check
GET /builder/approval.
Revoke
Users can revoke at any time: in the app under Settings → Builders → Connected Builders, or with the API.
After a revocation, new orders with your builder are rejected for that user, and fills of their resting builder orders charge a builder fee of 0.
Check approvals
A user's own approvals:
Each entry includes builder_id, builder_name and max_fee_rate.
A builder can check whether a given user has approved it, authenticated with the fee account's API key. account must be in checksum form.
The same check is available as Check user approval on the builder dashboard.
Errors
BUILDER_INVALID_SIGNATURE
The signature doesn't recover to account. Check the domain, the raw maxFeeRate and the nonce.
BUILDER_INVALID_NONCE
The nonce isn't current Unix milliseconds, or isn't greater than the last one.
BUILDER_INVALID_FEE_RATE
max_fee_rate isn't a decimal with at most 6 decimals.
BUILDER_FEE_EXCEEDS_AEVO_LIMIT
max_fee_rate is above the protocol cap.
BUILDER_NOT_ACTIVE
The builder is suspended or disabled.
BUILDER_NOT_FOUND
Unknown builder_id.
BUILDER_NOT_APPROVED
Revoke was called but there is no approval.
Last updated
Was this helpful?

