Server Verify
Backend SIWE verification for MOSS wallet signatures.
npm install @megaeth-labs/wallet-server-verifyHow It Works
Complete Express.js Example
import express from 'express';
import crypto from 'node:crypto';
import jwt from 'jsonwebtoken';
import {
getMessageToSign,
verifySignature,
Errors,
type MessageConfig,
type MessageToConfirm,
type MessageToSign,
} from '@megaeth-labs/wallet-server-verify';
const app = express();
app.use(express.json());
const config: MessageConfig = {
scheme: 'https',
domain: 'yourapp.com',
uri: 'https://yourapp.com',
chainId: 4326,
statement: 'Sign in to YourApp',
};
const challenges = new Map<string, MessageToSign>();
// POST /auth/challenge
app.post('/auth/challenge', (req, res) => {
const challenge = getMessageToSign(config, req.body.address);
const challengeId = crypto.randomUUID();
challenges.set(challengeId, challenge);
res.json({
challengeId,
...challenge,
});
});
// POST /auth/verify
app.post('/auth/verify', async (req, res) => {
const { challengeId, signature } = req.body;
const stored = challenges.get(challengeId);
if (!stored) {
return res.status(400).json({ error: 'UNKNOWN_OR_EXPIRED_CHALLENGE' });
}
const signedMessage: MessageToConfirm = {
...stored,
signature,
};
try {
await verifySignature(config, signedMessage);
challenges.delete(challengeId);
const token = jwt.sign(
{ address: stored.address },
process.env.JWT_SECRET as string,
{ expiresIn: '1h' },
);
res.json({ ok: true, token });
} catch (error) {
if (error instanceof Error) {
if (error.message === Errors.DIFFERENT_MESSAGE) {
return res.status(400).json({ error: Errors.DIFFERENT_MESSAGE });
}
if (error.message === Errors.INVALID_SIGNATURE) {
return res.status(401).json({ error: Errors.INVALID_SIGNATURE });
}
}
return res.status(500).json({ error: 'UNKNOWN_ERROR' });
}
});Error Handling
Error
Meaning
Typical action
Chain IDs Reference
Network
chainId
Exports and Types
Export
Purpose
Last updated