Skip to content

Commit 51193bf

Browse files
authored
Merge pull request #299 from geniusyinka/main
MetaMask NilDB Guide
2 parents 0944cfc + 5432d7c commit 51193bf

File tree

2 files changed

+249
-0
lines changed

2 files changed

+249
-0
lines changed
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
import CTABanner from '@site/src/components/CTABanner';
2+
3+
# Passwordless Authentication with MetaMask & Nillion
4+
5+
6+
## Introduction
7+
8+
This guide demonstrates how to build a passwordless authentication system using **MetaMask** for identity and **Nillion's Network User Credentials (NUC)** for secure, decentralized authentication. Instead of traditional passwords, users authenticate using their Ethereum wallet signatures.
9+
10+
11+
## MetaMask for Decentralized Identity (DID)
12+
13+
### What is a DID?
14+
15+
A **Decentralized Identifier (DID)** is a globally unique identifier that doesn't require a centralized authority. In our implementation, MetaMask wallet signatures are used to generate a DID that uniquely identifies users across the Nillion network.
16+
17+
### What are NUCs (Network User Credentials)?
18+
19+
**NUCs** are Nillion's cryptographic credentials that enable:
20+
- Passwordless authentication via wallet signatures
21+
- Secure access to Nillion's privacy-preserving infrastructure
22+
- Identity verification without storing passwords or sensitive data
23+
24+
The NUC SDK abstracts the complexity of cryptographic operations, providing a simple interface for Web3 authentication.
25+
26+
---
27+
Full code on github [Here](https://github.com/geniusyinka/nillion-mm-demo)
28+
29+
```
30+
cd nillion-mm-demo
31+
pnpm install
32+
pnpm dev
33+
```
34+
35+
36+
## Step By Step Implementation
37+
38+
### Prerequisites
39+
40+
41+
This guide assumes you have a nextjs app already set up. Otherwise install NextJS:
42+
```bash
43+
npx create-next-app@latest my-app --yes
44+
```
45+
46+
Install the required dependencies:
47+
48+
```bash
49+
npm install @nillion/nuc @nillion/secretvaults viem @tanstack/react-query
50+
```
51+
52+
# Active NilDB Subcription
53+
Head over to [subscription.nillion.com](https://subscription.nillion.com) and subscribe to Nildb.
54+
55+
---
56+
57+
### 1. Configure Nillion Network
58+
59+
Create a configuration file for Nillion network endpoints:
60+
61+
```typescript
62+
// src/config.ts
63+
export const NETWORK_CONFIG = {
64+
chainId: "nillion-chain-testnet-1",
65+
nilchain: "http://rpc.testnet.nilchain-rpc-proxy.nilogy.xyz",
66+
nilauth: "https://nilauth.sandbox.app-cluster.sandbox.nilogy.xyz",
67+
nildb: [
68+
"https://nildb-stg-n1.nillion.network",
69+
"https://nildb-stg-n2.nillion.network",
70+
"https://nildb-stg-n3.nillion.network",
71+
],
72+
};
73+
```
74+
75+
### 2. Connect MetaMask & Create NUC Signer
76+
77+
Set up the MetaMask connection and NUC signer:
78+
79+
```typescript
80+
// src/context/NillionContext.tsx
81+
import { Signer } from "@nillion/nuc";
82+
import { createWalletClient, custom } from "viem";
83+
import { mainnet } from "viem/chains";
84+
85+
const connectMetaMask = async () => {
86+
if (!window.ethereum) {
87+
throw new Error("MetaMask not installed");
88+
}
89+
90+
// Create wallet client with viem
91+
const walletClient = createWalletClient({
92+
chain: mainnet,
93+
transport: custom(window.ethereum),
94+
});
95+
96+
const [account] = await walletClient.requestAddresses();
97+
98+
// Create Nillion NUC Signer from MetaMask
99+
const nucSigner = Signer.fromWeb3({
100+
getAddress: async () => account,
101+
signTypedData: async (domain, types, message) => {
102+
return walletClient.signTypedData({
103+
account,
104+
domain,
105+
types,
106+
primaryType: Object.keys(types).find(k => k !== "EIP712Domain"),
107+
message,
108+
});
109+
},
110+
});
111+
112+
// Generate DID from signer
113+
const did = await nucSigner.getDid();
114+
console.log("User DID:", did.didString);
115+
116+
return { signer: nucSigner, did: did.didString, address: account };
117+
};
118+
```
119+
120+
### 3. Initialize Nillion Session
121+
122+
Use the NUC signer to authenticate with Nillion:
123+
124+
```typescript
125+
// src/hooks/useNillionClient.ts
126+
import { NillionClient } from "@nillion/secretvaults";
127+
import { NETWORK_CONFIG } from "@/config";
128+
129+
async function initializeSession(signer: Signer) {
130+
const client = new NillionClient({
131+
signer,
132+
nilchain: NETWORK_CONFIG.nilchain,
133+
nilauth: NETWORK_CONFIG.nilauth,
134+
nildb: NETWORK_CONFIG.nildb,
135+
});
136+
137+
// Initialize session - this authenticates the user
138+
await client.initialize();
139+
140+
return client;
141+
}
142+
```
143+
144+
### 4. Register & Subscribe User
145+
146+
Complete the authentication flow by registering the user:
147+
148+
```typescript
149+
// Register builder profile
150+
async function registerBuilder(client: NillionClient) {
151+
await client.registerBuilder({
152+
name: "User",
153+
description: "Authenticated via MetaMask",
154+
});
155+
}
156+
157+
// Subscribe to Nillion services
158+
async function subscribe(client: NillionClient) {
159+
await client.subscribe({
160+
name: "notes_subscription",
161+
subscriptionType: "free",
162+
});
163+
}
164+
```
165+
166+
### 5. Login Flow (Returning Users)
167+
168+
For returning users with stored sessions:
169+
170+
```typescript
171+
// src/hooks/useLoginMutation.ts
172+
async function login(signer: Signer, rootToken: string, nildbTokens: object) {
173+
const client = new NillionClient({
174+
signer,
175+
nilchain: NETWORK_CONFIG.nilchain,
176+
nilauth: NETWORK_CONFIG.nilauth,
177+
nildb: NETWORK_CONFIG.nildb,
178+
});
179+
180+
// Restore previous session
181+
await client.login({
182+
rootToken,
183+
nildbTokens,
184+
});
185+
186+
return client;
187+
}
188+
```
189+
190+
### 6. Complete Authentication Flow
191+
192+
Wire everything together:
193+
194+
```typescript
195+
// Simplified flow
196+
async function authenticateUser() {
197+
// 1. Connect MetaMask & get NUC signer
198+
const { signer, did } = await connectMetaMask();
199+
200+
// 2. Check if user has existing session
201+
const hasSession = checkLocalStorage();
202+
203+
if (hasSession) {
204+
// Login with existing session
205+
await login(signer, storedRootToken, storedNildbTokens);
206+
} else {
207+
// Initialize new session
208+
const client = await initializeSession(signer);
209+
210+
// Register and subscribe
211+
await registerBuilder(client);
212+
await subscribe(client);
213+
214+
// Store session tokens
215+
saveToLocalStorage(client.tokens);
216+
}
217+
218+
// User is now authenticated!
219+
return { did, authenticated: true };
220+
}
221+
```
222+
223+
---
224+
225+
226+
227+
228+
## Key Benefits
229+
230+
**No Password Storage** - Users authenticate with cryptographic signatures
231+
**Decentralized Identity** - DIDs are portable across applications
232+
**Enhanced Security** - Leverages battle-tested wallet security
233+
**Better UX** - One-click authentication for Web3 users
234+
**Privacy-First** - Built on Nillion's privacy-preserving infrastructure
235+
236+
---
237+
238+
## Conclusion
239+
240+
This implementation demonstrates how **MetaMask** and **Nillion's NUC SDK** enable passwordless authentication in Web3 applications. By leveraging wallet signatures and decentralized identifiers, you can build secure, user-friendly authentication without the risks of traditional password systems.
241+
242+
The NUC abstraction handles all cryptographic complexity, allowing developers to focus on building great user experiences while maintaining the highest security standards.
243+
244+

sidebar-build.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ const buildSidebar = [
8080
label: 'Collection Explorer Tool',
8181
id: 'build/private-storage/collection-explorer',
8282
},
83+
{
84+
type: "doc",
85+
label: "MetaMask Guide",
86+
id: "build/private-storage/metamask-guide",
87+
},
8388
{
8489
type: 'category',
8590
label: 'Secretvaults SDK',

0 commit comments

Comments
 (0)