Skip to main content

Delegated Attestation API

The Delegated Attestation API enables gas-subsidized attestations on EAS. The attester signs an EIP-712 typed message in their wallet, then the server submits the transaction on their behalf, paying gas from a server-side delegate wallet.

This lets users create attestations without holding native tokens for gas.

How It Works

  1. The client fetches the attester's current EAS nonce via GET /api/eas/nonce
  2. The client builds an EIP-712 typed data structure and prompts the user to sign it
  3. The client sends the signed data to POST /api/eas/delegated-attest
  4. The server verifies the signature, checks schema eligibility, and submits the transaction via attestByDelegation on the EAS contract
  5. The server returns the attestation UID and transaction hash

Endpoints

GET /api/eas/nonce

Returns the current EAS nonce for a given attester address. The nonce is required to build the EIP-712 typed data for signing.

Request

ParameterLocationTypeRequiredDescription
attesterquerystringYesEthereum address (0x-prefixed, 20 bytes)

Example Request

curl "https://reputation.omatrust.org/api/eas/nonce?attester=0x1234567890abcdef1234567890abcdef12345678"

Response (Success)

{
"nonce": "0",
"chain": "OMAchain Testnet",
"chainId": 66238,
"easAddress": "0x7946127D2f517c8584FdBF801b82F54436EC6FC7",
"elapsed": "120ms"
}
FieldTypeDescription
noncestringCurrent EAS nonce for the attester (stringified integer)
chainstringHuman-readable chain name
chainIdnumberChain ID
easAddressstringEAS contract address on this chain
elapsedstringRequest duration

Errors

HTTP StatusDescription
400Missing or invalid attester parameter
500EAS not configured or RPC failure

POST /api/eas/delegated-attest

Submits a signed delegated attestation to EAS. The server pays gas on behalf of the attester.

Request

FieldTypeRequiredDescription
attesterstringYesEthereum address of the signer (0x-prefixed, 20 bytes)
signaturestringYesEIP-712 signature from the attester's wallet
delegatedobjectYesThe attestation data that was signed (see below)
delegated object
FieldTypeDescription
schemastringSchema UID (0x-prefixed, 32 bytes)
recipientstringAttestation recipient address (0x-prefixed, 20 bytes)
expirationTimenumberUnix timestamp for expiration (0 for no expiration)
revocablebooleanWhether the attestation can be revoked
refUIDstringReferenced attestation UID (0x000...000 for none)
datastringABI-encoded attestation data (0x-prefixed)
deadlinenumberUnix timestamp after which the signature is invalid

Example Request

curl -X POST https://reputation.omatrust.org/api/eas/delegated-attest \
-H "Content-Type: application/json" \
-d '{
"attester": "0x1234567890abcdef1234567890abcdef12345678",
"signature": "0xabc123...signature...",
"delegated": {
"schema": "0x807b38ce9aa23fdde4457de01db9c5e8d6ec7c8feebee242e52be70847b7b966",
"recipient": "0x0000000000000000000000000000000000000000",
"expirationTime": 0,
"revocable": true,
"refUID": "0x0000000000000000000000000000000000000000000000000000000000000000",
"data": "0x...",
"deadline": 1739000000
}
}'

Response (Success)

{
"success": true,
"txHash": "0x...",
"uid": "0x...",
"blockNumber": 12345,
"chain": "OMAchain Testnet",
"elapsed": "3200ms"
}
FieldTypeDescription
successbooleantrue
txHashstringTransaction hash
uidstring | nullEAS attestation UID (parsed from the Attested event log)
blockNumbernumberBlock number where the transaction was confirmed
chainstringHuman-readable chain name
elapsedstringRequest duration

Error Codes

HTTP StatusCodeDescription
400Missing required fields (delegated, signature, attester)
400SIGNATURE_EXPIREDThe deadline has passed
400INVALID_SIGNATURESignature format is invalid or cannot be verified
400ATTESTER_MISMATCHRecovered signer does not match the attester field
403SCHEMA_NOT_SUBSIDIZEDSchema is not eligible for gas subsidy
409DUPLICATEThis exact signature was already submitted (replay protection)
500NO_DELEGATE_KEYServer-side delegate wallet key is not configured
500RPC failure, gas estimation failure, or transaction revert
501MAINNET_NOT_SUPPORTEDMainnet delegated attestations are not yet enabled

EIP-712 Typed Data

The attester signs an EIP-712 message with the following structure:

Domain

FieldValue
nameEAS
version1.0.0
chainIdTarget chain ID (e.g., 66238)
verifyingContractEAS contract address

Types

Attest(
address attester,
bytes32 schema,
address recipient,
uint64 expirationTime,
bool revocable,
bytes32 refUID,
bytes data,
uint256 value,
uint256 nonce,
uint64 deadline
)

The nonce is fetched from the EAS contract via the nonce endpoint. The value is always 0 (no ETH attached).

Schema Eligibility

Only schemas on the subsidized allowlist are eligible for gas-subsidized delegated attestation. Submitting a non-subsidized schema returns 403 SCHEMA_NOT_SUBSIDIZED.

The active chain is determined by the NEXT_PUBLIC_ACTIVE_CHAIN environment variable on the server (omachain-testnet or omachain-mainnet).

Typical Integration Flow

┌──────────┐     ┌──────────────┐     ┌─────┐
│ Client │ │ Reputation │ │ EAS │
│ (browser) │ │ Server │ │ │
└─────┬─────┘ └──────┬───────┘ └──┬──┘
│ │ │
│ GET /api/eas/ │ │
│ nonce?attester= │ │
│─────────────────>│ │
│ │ getNonce() │
│ │───────────────>│
│ │<───────────────│
│ { nonce } │ │
│<─────────────────│ │
│ │ │
│ (build EIP-712 │ │
│ typed data, │ │
│ prompt wallet │ │
│ signature) │ │
│ │ │
│ POST /api/eas/ │ │
│ delegated-attest │ │
│─────────────────>│ │
│ │ verify sig │
│ │ check schema │
│ │ │
│ │ attestByDelegation()
│ │───────────────>│
│ │<───────────────│
│ │ │
│ { uid, txHash } │ │
│<─────────────────│ │