Token permits
Read EIP-2612 permit metadata, relay signed permit approvals, and inspect permit replay history for DALP asset tokens.
Token permits let a holder approve a spender with an EIP-2612 signature instead of sending an on-chain approval transaction from the holder wallet. DALP exposes one read endpoint for permit metadata and one mutation endpoint that relays a signed permit through the transaction queue.
Use this API for allowance-based flows where the holder should not submit a separate approve() transaction. The holder signature authorizes the allowance. A caller with the token's custodian role relays the signed permit on the holder's behalf, and the caller's sender wallet pays for the queued transaction. A permit only sets an allowance. Any later transfer still runs through the token's normal compliance and transfer checks.
Prerequisites
- A deployed token address with the permit feature attached.
- A holder wallet that can sign an EIP-2612 permit message for that token.
- The spender address, token amount, deadline, and signature parts (
v,r,s). - API authentication for the caller that submits the relay request.
- The token's
custodianrole on the caller's executing wallet. - A caller participant with a sender wallet that DALP can use for the queued transaction.
walletVerificationfor user-session relay requests. API-key requests authenticate the sender through the API key and do not send wallet verification fields.
Permission boundary
The permit mutation requires the token's custodian role. The EIP-2612 signature authorizes the allowance, but relaying that signature on the holder's behalf is a custodial action, so DALP gates it the same way it gates forcedTransfer and address freezing. The API authenticates the caller, checks the custodian role on the executing wallet, and resolves the sender wallet for the queued transaction. User-session requests without valid wallet verification fail before DALP queues the call.
The on-chain effect stays narrow. The permit does not move tokens, bypass transfer restrictions, or approve a transfer authority. DALP writes the holder-approved allowance only when the signature, nonce, deadline, and EIP-712 domain pass the permit feature checks.
Read permit metadata
Call GET /api/v2/tokens/{tokenAddress}/permit-info before building the EIP-712 message. Pass owner when you need the holder's current nonce.
curl -X GET "$DAPI_URL/api/v2/tokens/0x1111111111111111111111111111111111111111/permit-info?owner=0x2222222222222222222222222222222222222222" \
-H "X-Api-Key: $DALP_API_TOKEN"When the token has an attached permit feature, the response contains the feature address, EIP-712 domain separator, permit type hash, and the requested holder nonce. DALP reads the domain separator and optional nonce from the live permit feature in one multicall.
{
"data": {
"featureAddress": "0x3333333333333333333333333333333333333333",
"owner": "0x2222222222222222222222222222222222222222",
"nonce": "7",
"domainSeparator": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"permitTypeHash": "0x6e71edae12b1b97f4d1f60370fef10178563ef29188d1232f565f79b8f6aad8c"
},
"links": {
"self": "/v2/tokens/0x1111111111111111111111111111111111111111/permit-info"
}
}If the token exists but has no attached permit feature, data is null. If you omit owner, DALP still returns the domain fields, but owner and nonce are null. If the token cannot be found in the tenant-scoped index, the API returns a token-not-found error. If the live permit feature cannot return its metadata, the API returns a token-features-unavailable error instead of guessing the domain values.
When you build the EIP-712 typed data, use the returned featureAddress as the verifying contract. The permit feature uses the token name, version 1, the current chain ID, and the permit feature address to build its domain separator.
Relay a signed permit
After the holder signs the EIP-2612 message, call POST /api/v2/tokens/{tokenAddress}/permits with the signed approval fields.
curl -X POST "$DAPI_URL/api/v2/tokens/0x1111111111111111111111111111111111111111/permits" \
-H "X-Api-Key: $DALP_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"owner": "0x2222222222222222222222222222222222222222",
"spender": "0x4444444444444444444444444444444444444444",
"value": "1000000000000000000",
"deadline": "1893456000",
"v": 27,
"r": "0x1111111111111111111111111111111111111111111111111111111111111111",
"s": "0x2222222222222222222222222222222222222222222222222222222222222222"
}'DALP encodes the feature contract's permit(owner, spender, value, deadline, v, r, s) call and submits it through the transaction queue. The caller's selected sender wallet pays for and tracks the queued execution. Synchronous completions return the updated token read-back. Queued completions return transaction tracking data.
Request fields
| Field | Required | Description |
|---|---|---|
owner | Yes | Token holder that signed the permit. |
spender | Yes | Address approved to spend the holder's tokens. |
value | Yes | Approved amount in the token's smallest units. The value must fit within uint256. |
deadline | Yes | Unix timestamp in seconds after which the signature is no longer valid. The value must fit within uint256. |
v | Yes | ECDSA recovery id. DALP accepts 27 or 28. |
r | Yes | ECDSA r value as a 32-byte hex string. |
s | Yes | ECDSA s value as a 32-byte hex string. |
walletVerification | For user sessions | Wallet verification payload for the sender wallet when the caller uses a user session. API-key requests omit this field. |
Read permit replay history
Call GET /api/v2/tokens/{tokenAddress}/permit/replay-history to list indexed permit() calls for a token. The endpoint returns permit usage across all holders by default. Add filter[owner] when you only need one holder's history.
curl --globoff -X GET "$DAPI_URL/api/v2/tokens/0x1111111111111111111111111111111111111111/permit/replay-history?filter[owner]=0x2222222222222222222222222222222222222222" \
-H "X-Api-Key: $DALP_API_TOKEN"Each row identifies the holder, the permit sequence number for that holder, the transaction hash, the block number, and the block timestamp. The endpoint is scoped to the tenant's indexed token view, so the audit trail only includes permit rows visible inside the caller's tenant boundary. The endpoint uses the standard collection response shape, so integrations can use limit, offset, sortBy=blockTime, sortDirection, and the pagination links in the response.
{
"data": [
{
"owner": "0x2222222222222222222222222222222222222222",
"nonce": "7",
"txHash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"blockNumber": "12345678",
"blockTime": "2026-06-06T12:00:00.000Z"
}
],
"meta": { "total": 1, "facets": {} },
"links": {
"self": "/v2/tokens/0x1111111111111111111111111111111111111111/permit/replay-history?filter[owner]=0x2222222222222222222222222222222222222222",
"first": "/v2/tokens/0x1111111111111111111111111111111111111111/permit/replay-history?filter[owner]=0x2222222222222222222222222222222222222222&page[offset]=0&page[limit]=50",
"prev": null,
"next": null,
"last": "/v2/tokens/0x1111111111111111111111111111111111111111/permit/replay-history?filter[owner]=0x2222222222222222222222222222222222222222&page[offset]=0&page[limit]=50"
}
}Use this history for operator audit and reconciliation. The endpoint is a forensic read model, not a live nonce check. DALP returns permit calls covered by its permit-originated approval index for that token, including wrapped smart-wallet calls when the index can identify the nested permit call. It does not backfill permits submitted before that indexing coverage existed. Use permit-info when you need the holder's current nonce before signing a new permit.
Behaviour and failure cases
- The permit feature must be attached to the token before the mutation can queue a permit call.
- DALP reads permit metadata from the tenant-scoped token index and the live permit feature contract.
- The caller must hold the token's
custodianrole on the executing wallet. Callers without that role are rejected before the transaction is queued. User-session requests without validwalletVerificationare rejected before the transaction is queued. API-key requests use the API key to authenticate the sender. - The permit call only succeeds when the signed owner, spender, value, nonce, deadline, and domain match the permit feature's checks.
- A successful permit emits the standard ERC-20
Approval(owner, spender, value)event. The subsequent token transfer still goes through the token's normal compliance and transfer checks. - Expired deadlines, stale nonces, wrong domains, malformed signatures, missing permit features, and unavailable live permit metadata fail before the allowance changes.
- Permit replay history is available as an indexed audit view. It can return prior rows even after the permit feature is detached from the token.
Inspect permit replay history
Call GET /api/v2/tokens/{tokenAddress}/permit/replay-history when you need an audit view of direct EIP-2612 permit() calls that DALP can identify from indexed chain events. The endpoint returns paginated rows for the token. Add filter[owner] to inspect one holder, or omit the filter to review relayed permits across holders for the token.
curl --globoff -X GET "$DAPI_URL/api/v2/tokens/0x1111111111111111111111111111111111111111/permit/replay-history?filter[owner]=0x2222222222222222222222222222222222222222" \
-H "X-Api-Key: $DALP_API_TOKEN"Each row identifies the holder, the per-holder permit counter, the transaction hash, the block number, and the block time.
{
"data": [
{
"owner": "0x2222222222222222222222222222222222222222",
"nonce": "7",
"txHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"blockNumber": "12345678",
"blockTime": "2026-06-06T10:15:30.000Z"
}
],
"meta": {
"total": 1,
"facets": {}
},
"links": {
"self": "/v2/tokens/0x1111111111111111111111111111111111111111/permit/replay-history?filter[owner]=0x2222222222222222222222222222222222222222"
}
}Replay history is forensic context, not the live allowance state. Use it to trace permit submissions that the indexer can identify from a direct permit() call or a decoded smart-wallet wrapper. Do not use it as a replacement for the permit metadata endpoint or the token's allowance checks.
Smart-wallet and account-abstraction submissions appear only when DALP can decode the nested permit call and bind it to the token's permit feature. Exotic wrapper shapes that cannot be decoded may be absent from this view.
Prior replay-history rows remain queryable even if the permit feature is later detached and reattached to the token. Sort by blockTime when you need chronological review.