> For the complete documentation index, see [llms.txt](https://docs.dothype.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dothype.io/architecture/how-it-all-works/registration-mechanics/signature-validation-eip-712.md).

# Signature Validation (EIP-712)

dotHYPE uses off-chain signatures verified on-chain to secure mints, prevent front-running, and lock pricing. This page explains how the system works for users and developers.

Signature-based minting enables secure, gas-efficient registrations while giving users confidence that prices can’t be manipulated between signing and minting.

### 🔒 Why Signatures Matter

When public mints are open, smart contracts are vulnerable to bots or MEV frontrunners:

* A user submits a transaction
* A bot sees it in the mempool
* The bot re-submits the transaction with higher gas to claim the name first

To prevent this, dotHYPE uses **EIP-712 typed data signatures**. These allow us to:

* Pre-authorize name mints with fixed pricing
* Let users sign intent off-chain before paying gas
* Limit signature usage to one-time only via nonces

### 🧾 Signature Structure

All signatures must match this typed data structure:

```
struct SignatureData {
  string name;         // Name to register
  address owner;       // Recipient of the NFT
  uint256 duration;    // Registration period (in seconds)
  uint256 maxPrice;    // Max price user is willing to pay
  uint256 deadline;    // Expiry time for the signature
  uint256 nonce;       // Prevents reuse
}
```

> This structure ensures signatures can’t be reused, expire after a window, and guarantee pricing.

### 🔁 Signature Minting Flow

```
function registerWithSignature(
  string calldata name,
  address owner,
  uint256 duration,
  uint256 maxPrice,
  uint256 deadline,
  uint256 nonce,
  bytes calldata signature
) external payable returns (uint256 tokenId, uint256 expiresAt);
```

The flow:

1. An authorized signer generates the EIP-712 payload with mint parameters
2. User submits the signature in the mint UI
3. Controller contract verifies:
   * Signature is valid
   * It hasn’t expired
   * Nonce hasn’t been used
   * Price is <= `maxPrice`
4. If valid, the Controller proceeds to register the name and mint

### 🔄 Nonce Management

Each user has a nonce that increments with every successful mint:

```
mapping(address => uint256) public nonces;
function getNextNonce(address owner) external view returns (uint256);
```

This prevents replay attacks and ensures signatures are single-use only.

### 🔐 Security Guarantees

Signature-based minting protects users by:

* Enforcing a **maximum price** set during signing
* Expiring signatures with a **deadline** timestamp
* Locking out re-use via **per-user nonce**

> If any of these checks fail, the transaction is rejected without consuming gas beyond call overhead.

### ⚙️ Setting the Signer

Only the protocol owner can set or change the authorized signer address:

```
function setSigner(address _signer) external onlyOwner;
```

This signer is used to validate all signature-based registration requests.

### 🛡 Best Practices

If you’re building or operating the signature system:

* Always generate EIP-712 payloads client-side or in secure backend infra
* Use `getNextNonce()` before generating a signature
* Set tight `deadline` windows to minimize signature misuse

> Never share the private key of the signer, and rotate regularly if compromised.

### 🧠 For Developers

If you’re integrating:

* Use our SDK or libraries to generate the proper EIP-712 payload
* Submit via `registerWithSignature()` in the Controller
* Always check availability before generating the signature

Want to learn how signature minting fits into the broader system? See the[ Minting Flow →](/architecture/how-it-all-works/minting-flow.md) overview.
