@lumiapassport/ui-kit 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +456 -0
- package/dist/iframe/main.js +1251 -2
- package/dist/iframe/main.js.map +1 -1
- package/dist/index.cjs +1154 -750
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +1213 -810
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# @lumiapassport/ui-kit
|
|
2
|
+
|
|
3
|
+
React UI components and hooks for Lumia Passport - a secure, user-friendly authentication and Account Abstraction wallet solution with MPC (Multi-Party Computation) key management.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔐 **Secure Authentication** - Multiple auth methods: Email, Passkey, Telegram, Wallet connect
|
|
8
|
+
- 🔑 **MPC Key Management** - Distributed key generation with iframe isolation
|
|
9
|
+
- 💼 **Account Abstraction** - ERC-4337 compliant smart contract wallets
|
|
10
|
+
- 🎨 **Pre-built UI Components** - Ready-to-use React components with customizable themes
|
|
11
|
+
- ⚡ **Easy Integration** - Just wrap your app with `LumiaPassportProvider`
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @lumiapassport/ui-kit @lumiapassport/core
|
|
17
|
+
# or
|
|
18
|
+
pnpm add @lumiapassport/ui-kit @lumiapassport/core
|
|
19
|
+
# or
|
|
20
|
+
yarn add @lumiapassport/ui-kit @lumiapassport/core
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Peer Dependencies
|
|
24
|
+
|
|
25
|
+
The following packages are required as peer dependencies:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install react react-dom viem wagmi @tanstack/react-query
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### 1. Wrap your app with `LumiaPassportProvider`
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { LumiaPassportProvider } from '@lumiapassport/ui-kit';
|
|
37
|
+
import '@lumiapassport/ui-kit/dist/styles.css';
|
|
38
|
+
|
|
39
|
+
function App() {
|
|
40
|
+
return (
|
|
41
|
+
<LumiaPassportProvider
|
|
42
|
+
config={{
|
|
43
|
+
projectId: 'your-project-id', // Get from Lumia Passport Dashboard
|
|
44
|
+
services: {
|
|
45
|
+
tssUrl: 'https://api.lumiapassport.com/tss',
|
|
46
|
+
bundlerUrl: 'https://api.lumiapassport.com/rundler',
|
|
47
|
+
shareVaultUrl: 'https://api.lumiapassport.com/vault',
|
|
48
|
+
}
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
<YourApp />
|
|
52
|
+
</LumiaPassportProvider>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 2. Add the Connect Button
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { ConnectWalletButton } from '@lumiapassport/ui-kit';
|
|
61
|
+
|
|
62
|
+
function YourApp() {
|
|
63
|
+
return (
|
|
64
|
+
<div>
|
|
65
|
+
<h1>My App</h1>
|
|
66
|
+
<ConnectWalletButton />
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
That's it! The `ConnectWalletButton` provides a complete authentication UI with wallet management.
|
|
73
|
+
|
|
74
|
+
## Configuration Options
|
|
75
|
+
|
|
76
|
+
### Basic Configuration
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
<LumiaPassportProvider
|
|
80
|
+
config={{
|
|
81
|
+
projectId: 'your-project-id', // Required
|
|
82
|
+
|
|
83
|
+
// Optional: Service URLs (defaults to production)
|
|
84
|
+
services: {
|
|
85
|
+
tssUrl: 'https://api.lumiapassport.com/tss',
|
|
86
|
+
bundlerUrl: 'https://api.lumiapassport.com/rundler',
|
|
87
|
+
shareVaultUrl: 'https://api.lumiapassport.com/vault',
|
|
88
|
+
iframeUrl: 'https://auth.lumiapassport.com',
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Optional: Custom RPC and network
|
|
92
|
+
rpcUrl: 'https://beam-rpc.lumia.org',
|
|
93
|
+
explorerUrl: 'https://beam-explorer.lumia.org',
|
|
94
|
+
|
|
95
|
+
// Optional: Custom smart contract addresses
|
|
96
|
+
aaFactoryAddress: '0x...',
|
|
97
|
+
paymasterAddress: '0x...',
|
|
98
|
+
}}
|
|
99
|
+
>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Advanced Configuration
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
<LumiaPassportProvider
|
|
106
|
+
config={{
|
|
107
|
+
projectId: 'your-project-id',
|
|
108
|
+
|
|
109
|
+
// Authentication providers
|
|
110
|
+
authProviders: {
|
|
111
|
+
email: true, // Email OTP
|
|
112
|
+
passkey: true, // Passkey/WebAuthn
|
|
113
|
+
telegram: true, // Telegram Mini App
|
|
114
|
+
wallet: true, // External wallet connection
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// UI customization
|
|
118
|
+
theme: {
|
|
119
|
+
mode: 'dark', // 'light' | 'dark' | 'auto'
|
|
120
|
+
primaryColor: '#6366f1', // Custom brand color
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
// Features
|
|
124
|
+
features: {
|
|
125
|
+
backup: true, // Enable key backup/recovery
|
|
126
|
+
mpcSecurity: true, // Enable MPC iframe isolation
|
|
127
|
+
},
|
|
128
|
+
}}
|
|
129
|
+
>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Using Hooks
|
|
133
|
+
|
|
134
|
+
### useAuth - Authentication State
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { useAuth } from '@lumiapassport/ui-kit';
|
|
138
|
+
|
|
139
|
+
function MyComponent() {
|
|
140
|
+
const {
|
|
141
|
+
user, // Current user info
|
|
142
|
+
isAuthenticated, // Auth status
|
|
143
|
+
login, // Login function
|
|
144
|
+
logout, // Logout function
|
|
145
|
+
loading, // Loading state
|
|
146
|
+
} = useAuth();
|
|
147
|
+
|
|
148
|
+
if (loading) return <div>Loading...</div>;
|
|
149
|
+
|
|
150
|
+
if (!isAuthenticated) {
|
|
151
|
+
return <button onClick={() => login()}>Sign In</button>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<div>
|
|
156
|
+
<p>Welcome, {user.userId}</p>
|
|
157
|
+
<button onClick={() => logout()}>Sign Out</button>
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### useWallet - Wallet Operations
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
import { useWallet } from '@lumiapassport/ui-kit';
|
|
167
|
+
|
|
168
|
+
function SendTransaction() {
|
|
169
|
+
const { address, sendTransaction, balance } = useWallet();
|
|
170
|
+
|
|
171
|
+
const handleSend = async () => {
|
|
172
|
+
const hash = await sendTransaction({
|
|
173
|
+
to: '0x...',
|
|
174
|
+
value: '0.1', // ETH amount
|
|
175
|
+
});
|
|
176
|
+
console.log('Transaction hash:', hash);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div>
|
|
181
|
+
<p>Address: {address}</p>
|
|
182
|
+
<p>Balance: {balance} ETH</p>
|
|
183
|
+
<button onClick={handleSend}>Send Transaction</button>
|
|
184
|
+
</div>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### useSendTransaction - Send Transactions
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
import { useSendTransaction } from '@lumiapassport/ui-kit';
|
|
193
|
+
|
|
194
|
+
function TransactionExample() {
|
|
195
|
+
const { sendTransaction, isPending } = useSendTransaction();
|
|
196
|
+
|
|
197
|
+
const handleSend = async () => {
|
|
198
|
+
try {
|
|
199
|
+
const userOpHash = await sendTransaction({
|
|
200
|
+
to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
|
|
201
|
+
value: '1000000000000000000', // 1 ETH in wei
|
|
202
|
+
data: '0x', // Optional contract call data
|
|
203
|
+
});
|
|
204
|
+
console.log('UserOp hash:', userOpHash);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.error('Transaction failed:', error);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
return (
|
|
211
|
+
<div>
|
|
212
|
+
<button onClick={handleSend} disabled={isPending}>
|
|
213
|
+
{isPending ? 'Sending...' : 'Send Transaction'}
|
|
214
|
+
</button>
|
|
215
|
+
</div>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### prepareUserOperation - Prepare for Backend Submission
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import { prepareUserOperation, useLumiaSession } from '@lumiapassport/ui-kit';
|
|
224
|
+
|
|
225
|
+
function BackendSubmissionExample() {
|
|
226
|
+
const { session } = useLumiaSession();
|
|
227
|
+
|
|
228
|
+
const handlePrepare = async () => {
|
|
229
|
+
if (!session) return;
|
|
230
|
+
|
|
231
|
+
// Prepare and sign UserOp without sending to bundler
|
|
232
|
+
const { userOp, userOpHash } = await prepareUserOperation(
|
|
233
|
+
session,
|
|
234
|
+
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', // to
|
|
235
|
+
'1000000000000000000', // 1 ETH in wei
|
|
236
|
+
'0x', // data
|
|
237
|
+
'standard', // fee type: 'economy' | 'standard' | 'fast'
|
|
238
|
+
'v0.7' // EntryPoint version
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
// Send to backend for validation and submission
|
|
242
|
+
await fetch('/api/submit-transaction', {
|
|
243
|
+
method: 'POST',
|
|
244
|
+
headers: { 'Content-Type': 'application/json' },
|
|
245
|
+
body: JSON.stringify({
|
|
246
|
+
userOp,
|
|
247
|
+
userOpHash,
|
|
248
|
+
ownerAddress: session.ownerAddress // for signature verification
|
|
249
|
+
}),
|
|
250
|
+
});
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
return (
|
|
254
|
+
<button onClick={handlePrepare}>
|
|
255
|
+
Prepare & Send to Backend
|
|
256
|
+
</button>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Backend example (using @lumiapassport/core):**
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { sendUserOperationRaw, getUserOperationReceipt } from '@lumiapassport/core';
|
|
265
|
+
import { recoverAddress } from 'viem';
|
|
266
|
+
|
|
267
|
+
// Receive from frontend
|
|
268
|
+
const { userOp, userOpHash, ownerAddress } = await request.json();
|
|
269
|
+
|
|
270
|
+
// Verify signature
|
|
271
|
+
const recoveredAddress = await recoverAddress({
|
|
272
|
+
hash: userOpHash,
|
|
273
|
+
signature: userOp.signature,
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
if (recoveredAddress.toLowerCase() !== ownerAddress.toLowerCase()) {
|
|
277
|
+
throw new Error('Invalid signature');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Submit to bundler - returns userOpHash
|
|
281
|
+
const submittedUserOpHash = await sendUserOperationRaw(userOp);
|
|
282
|
+
|
|
283
|
+
// Poll for receipt to get transaction hash and status
|
|
284
|
+
const waitForReceipt = async (userOpHash: string, maxAttempts = 60, delayMs = 1000) => {
|
|
285
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
286
|
+
const receipt = await getUserOperationReceipt(userOpHash as `0x${string}`);
|
|
287
|
+
if (receipt) {
|
|
288
|
+
return {
|
|
289
|
+
success: receipt.success,
|
|
290
|
+
transactionHash: receipt.receipt?.transactionHash,
|
|
291
|
+
blockNumber: receipt.receipt?.blockNumber,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
295
|
+
}
|
|
296
|
+
throw new Error('Transaction timeout');
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const result = await waitForReceipt(submittedUserOpHash);
|
|
300
|
+
return {
|
|
301
|
+
success: result.success,
|
|
302
|
+
transactionHash: result.transactionHash,
|
|
303
|
+
blockNumber: result.blockNumber
|
|
304
|
+
};
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Components
|
|
308
|
+
|
|
309
|
+
### ConnectWalletButton
|
|
310
|
+
|
|
311
|
+
Pre-built button with authentication modal.
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
<ConnectWalletButton
|
|
315
|
+
className="custom-class"
|
|
316
|
+
onConnect={(user) => console.log('Connected:', user)}
|
|
317
|
+
onDisconnect={() => console.log('Disconnected')}
|
|
318
|
+
/>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Custom Authentication Flow
|
|
322
|
+
|
|
323
|
+
```tsx
|
|
324
|
+
import { AuthModal, useAuthModal } from '@lumiapassport/ui-kit';
|
|
325
|
+
|
|
326
|
+
function CustomAuth() {
|
|
327
|
+
const { openAuth } = useAuthModal();
|
|
328
|
+
|
|
329
|
+
return (
|
|
330
|
+
<div>
|
|
331
|
+
<button onClick={() => openAuth()}>
|
|
332
|
+
Custom Sign In
|
|
333
|
+
</button>
|
|
334
|
+
<AuthModal />
|
|
335
|
+
</div>
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Authentication Methods
|
|
341
|
+
|
|
342
|
+
### Email OTP
|
|
343
|
+
|
|
344
|
+
Users receive a one-time code via email.
|
|
345
|
+
|
|
346
|
+
```tsx
|
|
347
|
+
// Configured by default, no additional setup needed
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Passkey (WebAuthn)
|
|
351
|
+
|
|
352
|
+
Secure biometric authentication with device passkeys.
|
|
353
|
+
|
|
354
|
+
```tsx
|
|
355
|
+
// Configured by default
|
|
356
|
+
// Users can register passkey after initial login
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Telegram Mini App
|
|
360
|
+
|
|
361
|
+
Authentication via Telegram for mini apps.
|
|
362
|
+
|
|
363
|
+
```tsx
|
|
364
|
+
// Requires Telegram bot configuration
|
|
365
|
+
// Set in config:
|
|
366
|
+
config={{
|
|
367
|
+
telegram: {
|
|
368
|
+
botName: 'your_bot_name',
|
|
369
|
+
}
|
|
370
|
+
}}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### External Wallet
|
|
374
|
+
|
|
375
|
+
Connect existing wallets (MetaMask, WalletConnect, etc.).
|
|
376
|
+
|
|
377
|
+
```tsx
|
|
378
|
+
// Configured by default
|
|
379
|
+
// Uses RainbowKit for wallet connections
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## Styling
|
|
383
|
+
|
|
384
|
+
### Using Built-in Themes
|
|
385
|
+
|
|
386
|
+
```tsx
|
|
387
|
+
import '@lumiapassport/ui-kit/dist/styles.css';
|
|
388
|
+
|
|
389
|
+
<LumiaPassportProvider
|
|
390
|
+
config={{
|
|
391
|
+
projectId: 'your-project-id',
|
|
392
|
+
theme: {
|
|
393
|
+
mode: 'dark', // or 'light', 'auto'
|
|
394
|
+
}
|
|
395
|
+
}}
|
|
396
|
+
>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Custom Styling
|
|
400
|
+
|
|
401
|
+
Override CSS variables for custom branding:
|
|
402
|
+
|
|
403
|
+
```css
|
|
404
|
+
.lumia-scope {
|
|
405
|
+
--lumia-primary: #6366f1;
|
|
406
|
+
--lumia-background: #0f172a;
|
|
407
|
+
--lumia-surface: #1e293b;
|
|
408
|
+
--lumia-text-primary: #f8fafc;
|
|
409
|
+
--lumia-text-secondary: #cbd5e1;
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## TypeScript Support
|
|
414
|
+
|
|
415
|
+
Full TypeScript support with exported types:
|
|
416
|
+
|
|
417
|
+
```tsx
|
|
418
|
+
import type {
|
|
419
|
+
LumiaPassportConfig,
|
|
420
|
+
User,
|
|
421
|
+
AuthProvider,
|
|
422
|
+
WalletInfo,
|
|
423
|
+
} from '@lumiapassport/ui-kit';
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
## Examples
|
|
427
|
+
|
|
428
|
+
Check out the `/examples` directory for complete working examples:
|
|
429
|
+
|
|
430
|
+
- **React + Vite** - Modern React setup with Vite
|
|
431
|
+
- **Next.js** - Next.js App Router integration
|
|
432
|
+
- **React + TypeScript** - Full TypeScript example
|
|
433
|
+
|
|
434
|
+
## Security
|
|
435
|
+
|
|
436
|
+
- 🔒 **MPC Key Management** - Keys are split between client and server using threshold cryptography
|
|
437
|
+
- 🏝️ **Iframe Isolation** - Sensitive operations run in isolated iframe context
|
|
438
|
+
- 🔐 **No Private Key Exposure** - Private keys never exist in complete form on client
|
|
439
|
+
- ✅ **Non-custodial** - Users maintain full control of their accounts
|
|
440
|
+
|
|
441
|
+
## Need Help?
|
|
442
|
+
|
|
443
|
+
- 📖 [Documentation](https://docs.lumiapassport.com)
|
|
444
|
+
- 💬 [Discord Community](https://discord.gg/lumia)
|
|
445
|
+
- 🐛 [Report Issues](https://github.com/lumiachain/lumia-passport-sdk/issues)
|
|
446
|
+
- 📧 [Email Support](mailto:support@lumia.org)
|
|
447
|
+
|
|
448
|
+
## License
|
|
449
|
+
|
|
450
|
+
MIT License - see LICENSE file for details.
|
|
451
|
+
|
|
452
|
+
## Links
|
|
453
|
+
|
|
454
|
+
- [Website](https://lumiapassport.com)
|
|
455
|
+
- [GitHub](https://github.com/lumiachain/lumia-passport-sdk)
|
|
456
|
+
- [NPM Package](https://www.npmjs.com/package/@lumiapassport/ui-kit)
|