authepy.
Dev Hub / Web3 & DApps

Stateless Web2.5 Bridging.

Don't build centralized honeypots. Authepy allows DApps to verify Web2 emails completely off-chain, cryptographically binding the volatile result to a SIWE (Sign-In with Ethereum) payload in your own database using zero-dependency REST.

EIP-4361 Ready
|
EVM & SVM
|
Zero On-Chain State
~ / web3-identity-stack
// 1. Install cryptographic primitives (No Authepy SDK needed)
~ npm install siwe ethers
added 2 packages in 1.2s
// 2. Verify EVM Provider connection
~ node scripts/test-rpc.js
✓ RPC Connected (Chain ID: 1)
✓ Stateless environment initialized
01

The EIP-4361 Handshake

Before executing any email logic, you must prove the user controls the cryptographic address they claim. We use the standard siwe (Sign-In with Ethereum) library to validate the signed message payload on your Node backend.

Architecture Note

  • Confirms private key custody
  • Prevents replay attacks via nonce
api/verify-wallet.ts Node.js
import { SiweMessage } from 'siwe';

export async function verifyWallet(req, res) {
  const { message, signature } = req.body;
  
  try {
    // 1. Reconstruct and verify the payload
    const siweMessage = new SiweMessage(message);
    const fields = await siweMessage.verify({ signature });
    
    // 2. Store the verified 0x address in a temporary secure session
    req.session.address = fields.data.address;
    req.session.siwe_verified = true;
    
    return res.json({ ok: true, address: fields.data.address });
  } catch (error) {
    return res.status(401).json({ error: "Invalid EIP-4361 signature." });
  }
}
02

The Cryptographic Bind

Once the wallet is confirmed, collect the Web2 email address. When the user submits the Authepy OTP code, verify it statelessly via our REST API. If it passes, you now have mathematical proof of both their wallet custody and their inbox access. Merge them into your DApp's database.

api/bind-email.ts Node.js
import db from '@/lib/database';

export async function bindIdentity(req, res) {
  // Passed from your frontend client
  const { email, requestId, code } = req.body;
  const walletAddress = req.session.address;

  if (!req.session.siwe_verified) {
    return res.status(401).json({ error: "Wallet not authenticated." });
  }

  // 1. Validate Email via Authepy Volatile Memory
  const response = await fetch('https://api.authepy.com/api/otp/verify', {
    method: 'POST',
    headers: { 
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.AUTHEPY_SECRET_KEY}`
    },
    body: JSON.stringify({ 
      requestId, 
      userGuess: code 
    })
  });

  const otpCheck = await response.json();
  if (!otpCheck.success) {
    return res.status(400).json({ error: otpCheck.error || "Invalid OTP token." });
  }

  // 2. Success! Cryptographically bind them in your Web2.5 DB
  await db.users.upsert({
    where: { address: walletAddress },
    update: { email: email, is_verified: true },
    create: { address: walletAddress, email: email, is_verified: true }
  });

  return res.json({ ok: true, message: "Identity bound." });
}

Zero Centralized Honeypots.

The danger of Web2 authentication platforms (like Auth0 or Firebase) in Web3 is that they force you to hand over your users' wallet addresses and emails to a centralized third party, creating a massive attack vector.

Sovereign Data Custody

Authepy never stores the linked wallet address or the user's email. Our verification execution is entirely ephemeral. Once the OTP hash is processed in volatile memory, it is destroyed. The only place the linked identity exists is securely in your DApp's own database.

Bridge Web2 safely.

Stop pushing Web3 users into bloated, centralized IAM suites just to capture an email address for notifications. Integrate stateless, off-chain verification today.