Skip to main content
POST
/
v1
/
permit
Execute ERC-20 Permit
curl --request POST \
  --url https://api.mrdn.finance/v1/permit \
  --header 'Authorization: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "network": "base-sepolia",
  "owner": "0x742d35Cc6634C0532925a3b8D0c4E5e6C2aE7A3e",
  "spender": "0x8e633dBf31adCc7D41BE3e95B7c8DD3526B5235A",
  "value": "1000000",
  "deadline": "1893456000",
  "recipient": "0x742d35Cc6634C0532925a3b8D0c4E5e6C2aE7A3e",
  "tokenAddress": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
  "signature": "0x...",
  "v": 127,
  "r": "<string>",
  "s": "<string>"
}
'
{
  "success": true,
  "transaction": "<string>",
  "network": "<string>",
  "errorReason": "invalid_request"
}

Documentation Index

Fetch the complete documentation index at: https://docs.mrdn.finance/llms.txt

Use this file to discover all available pages before exploring further.

Execute a gasless ERC-20 token transfer using a signed EIP-2612 permit. The user signs off-chain; the facilitator pays the gas and settles on-chain.

Authentication

Requires an API key passed as Authorization: Bearer <api-key>.

Request Body

{
  "network": "base-sepolia",
  "tokenAddress": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
  "owner": "0x742d35Cc6634C0532925a3b8D0c4E5e6C2aE7A3e",
  "spender": "0x8e633dBf31adCc7D41BE3e95B7c8DD3526B5235A",
  "value": "1000000",
  "deadline": "1893456000",
  "v": 27,
  "r": "0x...",
  "s": "0x...",
  "recipient": "0x742d35Cc6634C0532925a3b8D0c4E5e6C2aE7A3e"
}
FieldRequiredNotes
networkyesEVM network identifier (e.g. base, base-sepolia, optimism, polygon, unichain, ink)
tokenAddressyesERC-20 token contract address
owneryesToken owner address; must have signed the EIP-2612 permit
spenderyesSpender address authorized in the permit signature
valueyesAmount in the token’s smallest unit as a decimal string (1000000 = 1 USDC)
deadlineyesUnix timestamp after which the permit expires, as a decimal string
vyes*Signature recovery byte (27 or 28). Provide v/r/s OR signature, not both.
ryes*32-byte hex signature component
syes*32-byte hex signature component
recipientyesAddress that receives the transferred tokens

Facilitator contract addresses

NetworkContract
base0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
base-sepolia0x8e633dBf31adCc7D41BE3e95B7c8DD3526B5235A
ethereum0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
avalanche0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
optimism0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
optimism-sepolia0x8e633dBf31adCc7D41BE3e95B7c8DD3526B5235A
arbitrum0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
polygon0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
unichain0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
ink0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
sonic0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
worldchain0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
sei0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
hyperevm0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
megaeth0x8E7769D440b3460b92159Dd9C6D17302b036e2d6
fluent-testnet0xB3Ac1B7871942bCdCD0bD6C65765272bBE70B8Da

Response

Success

{
  "success": true,
  "transaction": "0x1234567890abcdef...",
  "network": "base-sepolia"
}

Error

{
  "success": false,
  "transaction": "",
  "network": "base-sepolia",
  "errorReason": "invalid_request"
}

Error Codes

errorReasonHTTPDescription
invalid_request400Missing or malformed fields in the request body
unsupported_network400network is not a supported EVM network
network_not_configured400The facilitator has no private key configured for this network
invalid_signature400Could not resolve a valid v, r, s from the provided inputs
permit_execution_failed500On-chain transaction failed (RPC error, revert, bad permit, etc.)

Authorizations

Authorization
string
header
required

Body

application/json
network
string
required

EVM network identifier. Must be one of the SupportedEVMNetworks (e.g. base, base-sepolia, optimism, optimism-sepolia, polygon, unichain, ink, hyperevm, megaeth, fluent-testnet, etc.).

Example:

"base-sepolia"

owner
string
required

Token owner address (the signer of the EIP-2612 permit). Tokens are pulled from this address.

Pattern: ^0x[a-fA-F0-9]{40}$
Example:

"0x742d35Cc6634C0532925a3b8D0c4E5e6C2aE7A3e"

spender
string
required

Spender address authorized by the permit signature. Required by the request schema. The on-chain transferWithPermit call uses the facilitator contract as the spender; this field is forwarded for signing-side compatibility.

Pattern: ^0x[a-fA-F0-9]{40}$
Example:

"0x8e633dBf31adCc7D41BE3e95B7c8DD3526B5235A"

value
string
required

uint256 token amount as a decimal string in the token's smallest unit (e.g. 1000000 = 1 USDC at 6 decimals). Numbers and bigints are accepted and coerced to a decimal string.

Pattern: ^\d+$
Example:

"1000000"

deadline
string
required

uint256 permit deadline as a decimal Unix timestamp string. Numbers and bigints are accepted and coerced to a decimal string.

Pattern: ^\d+$
Example:

"1893456000"

recipient
string
required

Address that receives the transferred tokens after the permit is applied.

Pattern: ^0x[a-fA-F0-9]{40}$
Example:

"0x742d35Cc6634C0532925a3b8D0c4E5e6C2aE7A3e"

tokenAddress
string

ERC-20 token address. Documented as optional with a fallback to the network's USDC, but the actual transferWithPermit call uses this value directly. Provide it explicitly to avoid permit_execution_failed.

Pattern: ^0x[a-fA-F0-9]{40}$
Example:

"0x036CbD53842c5426634e7929541eC2318f3dCF7e"

signature
string

Optional 65-byte EIP-2612 permit signature, hex-encoded. Schema accepts ^0x[a-fA-F0-9]+$. WARNING: this field is broken at runtime in the current handler (viem returns r/s as 0x-prefixed and the assembler re-wraps them, producing malformed bytes); use the split (v, r, s) form instead. Provide this OR (v, r, s), but not both.

Pattern: ^0x[a-fA-F0-9]+$
Example:

"0x..."

v
integer

Optional v byte of the signature. The exclusivity check uses Boolean(data.v), so v = 0 is treated as missing; use 27 or 28.

Required range: 0 <= x <= 255
r
string

Optional r component. The schema accepts any string (no regex). In practice, send a 32-byte hex value (with or without leading 0x); only the first occurrence of 0x is stripped when assembling the final signature.

s
string

Optional s component. The schema accepts any string (no regex). In practice, send a 32-byte hex value (with or without leading 0x); only the first occurrence of 0x is stripped when assembling the final signature.

Response

Permit transaction submitted

success
boolean
required

true only when the on-chain transaction was submitted successfully.

transaction
string
required

Transaction hash on success. Empty string ("") on every error response.

network
string
required

Echoes the network from the request (or "" if the request body could not be parsed).

errorReason
enum<string>

Present on error responses only.

Available options:
invalid_request,
unsupported_network,
network_not_configured,
invalid_signature,
permit_execution_failed