logo

EIP-712 Signing

Prepare and sign Namefi EIP-712 requests using the live helper endpoints

The Namefi API uses EIP-712 typed data signatures for sensitive operations such as DNS updates, parking, and domain registration.

The source of truth for EIP-712 signing metadata is the live helper endpoints, not copied type tables in docs or local cached skill data.

Live helper endpoints

EndpointPurpose
GET /v-next/eip712/domain?chain=1Returns the signing domain
GET /v-next/eip712/typesReturns the full EIP-712 type registry
GET /v-next/eip712/types-for-method?method=toggleDomainParkingReturns accepted primary types and the type map for one operation

EIP-712 domain

Fetch the current domain from the API:

const domain = await fetch(
  'https://api.namefi.io/v-next/eip712/domain?chain=1',
).then((r) => r.json());

console.log(domain);
// { name: 'Namefi', version: '1' }

The endpoint accepts chain for forward compatibility, but the current Namefi signing domain is chain-agnostic and omits chainId.

Per-method types

Fetch the accepted primary types and type map for one operation:

const methodTypes = await fetch(
  'https://api.namefi.io/v-next/eip712/types-for-method?method=toggleDomainParking',
).then((r) => r.json());

console.log(methodTypes);
/*
{
  found: true,
  acceptedPrimaryTypes: ['ToggleDomainParkingEnvelope'],
  types: {
    ToggleDomainParking: [
      { name: 'normalizedDomainName', type: 'string' },
      { name: 'enableParking', type: 'bool' },
      { name: 'overrideExistingRecords', type: 'bool' }
    ],
    ToggleDomainParkingEnvelope: [
      { name: 'payloadType', type: 'string' },
      { name: 'payload', type: 'ToggleDomainParking' },
      { name: 'timestamp', type: 'uint256' },
      { name: 'nonce', type: 'string' }
    ]
  }
}
*/

When found is false, the response includes availableMethods so you can discover valid EIP-712 operation IDs.

Envelope structure

Every EIP-712 request signs a standard envelope:

{
  payloadType: string;
  payload: Record<string, unknown>;
  timestamp: number;
  nonce: string;
}

The primaryType is always an envelope type such as ToggleDomainParkingEnvelope. The inner payloadType is derived by removing the Envelope suffix.

Manual signing flow

import { toHex } from 'viem';

const payload = {
  normalizedDomainName: 'example.com',
  enableParking: true,
  overrideExistingRecords: false,
};

const domain = await fetch(
  'https://api.namefi.io/v-next/eip712/domain?chain=1',
).then((r) => r.json());

const methodTypes = await fetch(
  'https://api.namefi.io/v-next/eip712/types-for-method?method=toggleDomainParking',
).then((r) => r.json());

if (!methodTypes.found) {
  throw new Error('Method is not registered for EIP-712');
}

const primaryType = methodTypes.acceptedPrimaryTypes[0];
const payloadType = primaryType.replace(/Envelope$/, '');

const envelope = {
  payloadType,
  payload,
  timestamp: Math.trunc(Date.now() / 1000),
  nonce: toHex(crypto.getRandomValues(new Uint8Array(32))),
};

const typedData = {
  domain,
  types: methodTypes.types,
  primaryType,
  message: envelope,
};

const signature = await externalSigner.signTypedData(typedData);

const preparedRequest = {
  method: 'PUT',
  url: '<use the resolved operation URL here>',
  headers: {
    'content-type': 'application/json',
    'x-namefi-signer': externalSigner.address,
    'x-namefi-signature': signature,
    'x-namefi-eip712-type': primaryType,
  },
  body: envelope,
};

await fetch(preparedRequest.url, {
  method: preparedRequest.method,
  headers: preparedRequest.headers,
  body: JSON.stringify(preparedRequest.body),
});

Request headers

HeaderValue
x-namefi-signerSigner address
x-namefi-signatureHex-encoded EIP-712 signature
x-namefi-eip712-typeSelected primary type

Using the skill helpers

If you use the public namefi-skills repo, the canonical flow is:

bun .rulesync/skills/namefi-api/scripts/prepare-auth-request.ts \
  --env dev \
  --operationId toggleDomainParking \
  --payload '{"normalizedDomainName":"march1104.gl","enableParking":true,"overrideExistingRecords":false}'

That script returns:

  • the live EIP-712 domain
  • accepted primary types
  • the selected primary type
  • the type map
  • the signed envelope body
  • a header template for x-namefi-signer, x-namefi-signature, and x-namefi-eip712-type

You then hand the returned typedData object to any external signer or MCP.

For the combined operation-aware entrypoint that also handles SIWE and no-auth cases, see Prepare Auth Requests.

Notes

  • Prefer GET /eip712/types-for-method over copying static type definitions into your app.
  • timestamp uses Unix seconds, not milliseconds.
  • nonce should be unique per request.
  • Some operations accept more than one primary type. Choose the one that matches the payload shape you are sending.

On this page