Quick Start
TypeScript
1// 1. Detect wallet
2const wallet = window.midnight?.['1am'];
3
4// 2. Connect
5const api = await wallet.connect('preview');
6
7// 3. Sign a message
8const result = await api.signData('Sign in to MyApp: 1234567890', {
9 encoding: 'text',
10 keyType: 'unshielded',
11});
12
13console.log(result);
14// {
15// data: "Sign in to MyApp: 1234567890",
16// signature: "a1b2c3d4...", // hex-encoded Ed25519 signature
17// verifyingKey: "e5f6a7b8..." // hex-encoded public key
18// }API Reference
api.signData(data, options)— Signs arbitrary data with the wallet's unshielded key.
PARAMETERS
| Param | Type | Description |
|---|---|---|
| data | string | The message to sign |
| options.encoding | 'text' | 'hex' | 'base64' | How data is encoded |
| options.keyType | 'unshielded' | Key to sign with |
RETURNS
TypeScript
1{
2 data: string; // Original message
3 signature: string; // Hex-encoded Ed25519 signature
4 verifyingKey: string; // Hex-encoded public key
5}ENCODING OPTIONS
| Encoding | Use Case | Example |
|---|---|---|
| text | Auth challenges, human-readable | "Sign in: abc123" |
| hex | Binary data as hex | "48656c6c6f" |
| base64 | Binary data as base64 | "SGVsbG8=" |
Authentication Flow
1
Challenge
Backend generates a random nonce
2
Sign
DApp calls api.signData(nonce, { encoding: 'text', keyType: 'unshielded' })
3
Approve
User sees wallet popup and approves the signature
4
Verify
DApp sends { signature, verifyingKey } to backend
5
Validate
Backend verifies Ed25519 signature against verifyingKey
6
Auth
User is authenticated — no gas, no sync, no seed phrase
Frontend — Prove Wallet Ownership
TypeScript
1async function authenticate(challenge: string) {
2 const wallet = window.midnight?.['1am'];
3 if (!wallet) throw new Error('1AM wallet not installed');
4
5 const api = await wallet.connect('preview');
6 const { signature, verifyingKey } = await api.signData(challenge, {
7 encoding: 'text',
8 keyType: 'unshielded',
9 });
10
11 // Send to your backend for verification
12 const response = await fetch('/api/auth/verify', {
13 method: 'POST',
14 headers: { 'Content-Type': 'application/json' },
15 body: JSON.stringify({ challenge, signature, verifyingKey }),
16 });
17
18 return response.json();
19}Backend Verification (Node.js)
TypeScript
1import { ed25519 } from '@noble/curves/ed25519';
2
3function verifySignature(
4 challenge: string,
5 signature: string,
6 verifyingKey: string
7): boolean {
8 const messageBytes = new TextEncoder().encode(challenge);
9 const sigBytes = Buffer.from(signature, 'hex');
10 const pubKeyBytes = Buffer.from(verifyingKey, 'hex');
11
12 return ed25519.verify(sigBytes, messageBytes, pubKeyBytes);
13}Install: npm install @noble/curves
Key Details
Algorithm
Ed25519 (same as Midnight unshielded key)
No sync required
Works immediately after wallet creation
No gas/dust
Signing is local — no transaction needed
User approval
Wallet shows signing prompt — user must approve