shogun-button-react 6.7.3 → 6.8.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 CHANGED
@@ -1,769 +1,769 @@
1
- # Shogun Button React
2
-
3
- A comprehensive React component library for seamless integration of Shogun authentication into your applications. This library provides a simple yet powerful way to add multi-method authentication, account management, and real-time data synchronization to your React applications.
4
-
5
- > **Version 5.0.0** - Compatible with shogun-core ^2.0.0
6
-
7
- ## ✨ Features
8
-
9
- - 🚀 **Easy Integration** - Simple setup with minimal configuration
10
- - 🎨 **Customizable UI** - Modern, responsive design with dark mode support
11
- - 🔒 **Multi-Authentication** - Support for Password, MetaMask, WebAuthn, Nostr, and ZK-Proof
12
- - 🛡️ **WebAuthn Recovery** - Restore hardware credentials on new devices with saved seed phrases
13
- - 🔑 **Account Management** - Export/import Gun pairs for account backup and recovery
14
- - 🕵️ **ZK-Proof Trapdoor Handoff** - Display and copy the generated trapdoor during signup to keep anonymous identities portable
15
- - 📱 **Responsive Design** - Works seamlessly across all device sizes
16
- - 🌍 **TypeScript Support** - Full type safety and IntelliSense support
17
- - 🔌 **Plugin System** - Advanced Gun operations with custom hooks
18
- - 📊 **Real-time Data** - Reactive data synchronization with RxJS observables
19
- - ✅ **Robust Foundation** - Built on shogun-core v5.0.0 with 99.86% test coverage
20
- - 🗄️ **Flexible Storage** - Support for GunDB, SQLite, PostgreSQL, MongoDB via TransportLayer
21
-
22
- ## 📦 Requirements
23
-
24
- - **React**: ^18.0.0
25
- - **shogun-core**: ^2.0.0
26
- - **Node.js**: ≥18
27
-
28
- ## 🚀 Quick Start
29
-
30
- ### Installation
31
-
32
- ```bash
33
- npm install shogun-button-react shogun-core
34
- # or
35
- yarn add shogun-button-react shogun-core
36
- ```
37
-
38
- ### Updating from 3.x
39
-
40
- If you're upgrading from version 3.x:
41
-
42
- ```bash
43
- yarn upgrade shogun-button-react shogun-core
44
- # or
45
- npm update shogun-button-react shogun-core
46
- ```
47
-
48
- ### Basic Usage
49
-
50
- ```tsx
51
- import React from "react";
52
- import { ShogunButton, ShogunButtonProvider, shogunConnector } from "shogun-button-react";
53
- import "shogun-button-react/styles.css";
54
-
55
- function App() {
56
- const { core, options } = shogunConnector({
57
- appName: "My Awesome App",
58
- // Enable specific authentication methods
59
- showMetamask: true,
60
- showWebauthn: true,
61
- showNostr: true,
62
- showZkProof: true,
63
- // Optional peers
64
- peers: [
65
- "https://gun-manhattan.herokuapp.com/gun"
66
- ],
67
- });
68
-
69
- return (
70
- <ShogunButtonProvider
71
- core={core}
72
- options={options}
73
- onLoginSuccess={(data) => {
74
- console.log("Login successful!", data);
75
- }}
76
- onSignupSuccess={(data) => {
77
- console.log("Account created successfully!", data);
78
- }}
79
- onError={(error) => {
80
- console.error("Authentication error:", error);
81
- }}
82
- >
83
- <div className="app">
84
- <header>
85
- <h1>Welcome to My Awesome App</h1>
86
- <ShogunButton />
87
- </header>
88
- <main>{/* Your app content */}</main>
89
- </div>
90
- </ShogunButtonProvider>
91
- );
92
- }
93
-
94
- export default App;
95
- ```
96
-
97
- ## 🔧 Advanced Configuration
98
-
99
- ### Custom Authentication Options
100
-
101
- ```tsx
102
- const { core, options } = shogunConnector({
103
- appName: "My App",
104
-
105
- // Toggle authentication methods in the UI
106
- showMetamask: true,
107
- showWebauthn: true,
108
- showNostr: true,
109
- showZkProof: true,
110
-
111
- // Network configuration (backward compatible)
112
- peers: [
113
- "https://gun-manhattan.herokuapp.com/gun"
114
- ],
115
-
116
- // ZK-Proof configuration
117
- zkproof: {
118
- enabled: true,
119
- defaultGroupId: "my-app-users",
120
- },
121
-
122
- // Gun Advanced Plugin configuration
123
- enableGunDebug: true,
124
- enableConnectionMonitoring: true,
125
- defaultPageSize: 20,
126
- connectionTimeout: 10000,
127
- });
128
- ```
129
-
130
- ### Advanced Transport Layer Configuration (New in v5.0.0)
131
-
132
- ```tsx
133
- const { core, options } = shogunConnector({
134
- appName: "My App",
135
-
136
- // Use new transport layer system
137
- transport: {
138
- type: "gun", // or "sqlite", "postgresql", "mongodb", "custom"
139
- options: {
140
- peers: ["https://gun-manhattan.herokuapp.com/gun"],
141
- // Additional transport-specific options
142
- }
143
- },
144
-
145
- // Alternative: Use SQLite for local development
146
- transport: {
147
- type: "sqlite",
148
- options: {
149
- filename: "./my-app.db",
150
- // SQLite-specific options
151
- }
152
- },
153
-
154
- // Alternative: Use PostgreSQL for production
155
- transport: {
156
- type: "postgresql",
157
- options: {
158
- host: "localhost",
159
- port: 5432,
160
- database: "myapp",
161
- username: "user",
162
- password: "password",
163
- // PostgreSQL-specific options
164
- }
165
- },
166
-
167
- // Authentication methods
168
- showMetamask: true,
169
- showWebauthn: true,
170
- showNostr: true,
171
- showZkProof: true,
172
- });
173
- ```
174
-
175
- ## 🔑 Recovery Flows
176
-
177
- ### WebAuthn Multi-Device Restore
178
-
179
- - Users now see a **Restore with Recovery Code** option when choosing WebAuthn login.
180
- - Enter the username plus the stored seed phrase to recreate the credential on a new browser.
181
- - The button calls `webauthnPlugin.signUp(username, { seedPhrase, generateSeedPhrase: false })` behind the scenes, leveraging the core plugin’s `importFromSeed` flow.
182
- - After a successful restore the seed phrase is shown one more time so the user can double-check or re-copy it before the modal closes.
183
-
184
- ### ZK-Proof Trapdoor Delivery
185
-
186
- - Upon successful `zkproof` signup, the modal switches to a confirmation screen that displays the generated trapdoor (also returned as `seedPhrase`).
187
- - A **Copy Trapdoor** helper copies the phrase to the clipboard, with inline feedback when the copy succeeds.
188
- - The user must acknowledge with **I Saved My Trapdoor** before returning to the main UI, reducing the risk of losing the anonymous identity.
189
-
190
- ## 🎯 API Reference
191
-
192
- ### ShogunButtonProvider
193
-
194
- The provider component that supplies Shogun context to your application.
195
-
196
- #### Props
197
-
198
- | Name | Type | Description | Required |
199
- |------|------|-------------|----------|
200
- | `core` | `ShogunCore` | Shogun SDK instance created by `shogunConnector` | ✅ |
201
- | `options` | `ShogunConnectorOptions` | Configuration options | ✅ |
202
- | `onLoginSuccess` | `(data: AuthData) => void` | Callback fired on successful login | ❌ |
203
- | `onSignupSuccess` | `(data: AuthData) => void` | Callback fired on successful signup | ❌ |
204
- | `onError` | `(error: string) => void` | Callback fired when an error occurs | ❌ |
205
-
206
- #### AuthData Interface
207
-
208
- ```typescript
209
- interface AuthData {
210
- userPub: string; // User's public key
211
- username: string; // Display name
212
- password?: string; // Password (if applicable)
213
- seedPhrase?: string; // Seed phrase/trapdoor (for ZK-Proof)
214
- authMethod?: "password" | "web3" | "webauthn" | "nostr" | "zkproof" | "pair";
215
- }
216
- ```
217
-
218
- ### ShogunButton
219
-
220
- The main button component that provides a complete authentication UI with modal dialogs for login, signup, and account management.
221
-
222
- **Features:**
223
- - Multi-method authentication selection
224
- - Password-based login/signup with recovery
225
- - Gun pair export/import for account backup
226
- - Responsive modal design
227
- - Error handling and user feedback
228
-
229
- ### useShogun Hook
230
-
231
- A comprehensive hook to access Shogun authentication state and functions.
232
-
233
- ```tsx
234
- import React, { useEffect } from "react";
235
- import { useShogun } from "shogun-button-react";
236
-
237
- function UserProfile() {
238
- const {
239
- // Authentication state
240
- isLoggedIn,
241
- userPub,
242
- username,
243
-
244
- // Authentication methods
245
- login,
246
- signUp,
247
- logout,
248
-
249
- // Plugin management
250
- hasPlugin,
251
- getPlugin,
252
-
253
- // Account management
254
- exportGunPair,
255
- importGunPair,
256
-
257
- // Data operations
258
- observe,
259
- put,
260
- get,
261
- remove,
262
-
263
- // Advanced Gun hooks
264
- useGunState,
265
- useGunCollection,
266
- useGunConnection,
267
- useGunDebug,
268
- useGunRealtime,
269
- } = useShogun();
270
-
271
- // Example: Login with different methods
272
- const handlePasswordLogin = async () => {
273
- try {
274
- const result = await login("password", "username", "password");
275
- if (result.success) {
276
- console.log("Password login successful!");
277
- }
278
- } catch (error) {
279
- console.error("Login failed:", error);
280
- }
281
- };
282
-
283
- const handleMetaMaskLogin = async () => {
284
- try {
285
- const result = await login("web3");
286
- if (result.success) {
287
- console.log("MetaMask login successful!");
288
- }
289
- } catch (error) {
290
- console.error("MetaMask login failed:", error);
291
- }
292
- };
293
-
294
- const handleWebAuthnLogin = async () => {
295
- try {
296
- const result = await login("webauthn", "username");
297
- if (result.success) {
298
- console.log("WebAuthn login successful!");
299
- }
300
- } catch (error) {
301
- console.error("WebAuthn login failed:", error);
302
- }
303
- };
304
-
305
- const handleZkProofSignup = async () => {
306
- try {
307
- const result = await signUp("zkproof");
308
- if (result.success && result.seedPhrase) {
309
- console.log("ZK-Proof signup successful!");
310
- console.log("SAVE THIS TRAPDOOR:", result.seedPhrase);
311
- // CRITICAL: User must save the trapdoor for account recovery
312
- }
313
- } catch (error) {
314
- console.error("ZK-Proof signup failed:", error);
315
- }
316
- };
317
-
318
- const handleZkProofLogin = async () => {
319
- try {
320
- const trapdoor = "user-saved-trapdoor-here";
321
- const result = await login("zkproof", trapdoor);
322
- if (result.success) {
323
- console.log("ZK-Proof anonymous login successful!");
324
- }
325
- } catch (error) {
326
- console.error("ZK-Proof login failed:", error);
327
- }
328
- };
329
-
330
- // Example: Account backup and recovery
331
- const handleExportAccount = async () => {
332
- try {
333
- const pairData = await exportGunPair("my-secure-password");
334
- console.log("Account exported successfully!");
335
-
336
- // Save to file or copy to clipboard
337
- if (navigator.clipboard) {
338
- await navigator.clipboard.writeText(pairData);
339
- alert("Account data copied to clipboard!");
340
- }
341
- } catch (error) {
342
- console.error("Export failed:", error);
343
- }
344
- };
345
-
346
- const handleImportAccount = async (pairData: string, password?: string) => {
347
- try {
348
- const success = await importGunPair(pairData, password);
349
- if (success) {
350
- console.log("Account imported successfully!");
351
- }
352
- } catch (error) {
353
- console.error("Import failed:", error);
354
- }
355
- };
356
-
357
- // Example: Real-time data observation
358
- useEffect(() => {
359
- if (isLoggedIn) {
360
- const subscription = observe<any>('user/profile').subscribe(data => {
361
- console.log('Profile updated:', data);
362
- });
363
-
364
- return () => subscription.unsubscribe();
365
- }
366
- }, [isLoggedIn, observe]);
367
-
368
- if (!isLoggedIn) {
369
- return <div>Please log in to view your profile</div>;
370
- }
371
-
372
- return (
373
- <div className="user-profile">
374
- <h2>Welcome, {username}!</h2>
375
- <div className="profile-info">
376
- <p><strong>Public Key:</strong> {userPub}</p>
377
- <p><strong>Authentication Method:</strong> {authMethod}</p>
378
- </div>
379
-
380
- <div className="actions">
381
- <button onClick={handleExportAccount}>Export Account</button>
382
- <button onClick={logout}>Logout</button>
383
- </div>
384
- </div>
385
- );
386
- }
387
- ```
388
-
389
- ## 🔌 Advanced Gun Plugin Usage
390
-
391
- ### Using Gun State Hooks
392
-
393
- ```tsx
394
- function UserSettings() {
395
- const { useGunState, useGunCollection } = useShogun();
396
-
397
- // Single value state
398
- const profile = useGunState('user/profile', {
399
- name: '',
400
- email: '',
401
- preferences: {}
402
- });
403
-
404
- // Collection management
405
- const posts = useGunCollection('user/posts', {
406
- pageSize: 10,
407
- sortBy: 'createdAt',
408
- sortOrder: 'desc',
409
- filter: (post) => post.isPublished
410
- });
411
-
412
- const updateProfile = async () => {
413
- await profile.update({
414
- name: 'New Name',
415
- preferences: { theme: 'dark' }
416
- });
417
- };
418
-
419
- const addPost = async () => {
420
- await posts.addItem({
421
- title: 'New Post',
422
- content: 'Post content...',
423
- createdAt: Date.now(),
424
- isPublished: true
425
- });
426
- };
427
-
428
- return (
429
- <div>
430
- <h3>Profile Settings</h3>
431
- {profile.isLoading ? (
432
- <p>Loading...</p>
433
- ) : profile.error ? (
434
- <p>Error: {profile.error}</p>
435
- ) : (
436
- <div>
437
- <input
438
- value={profile.data?.name || ''}
439
- onChange={(e) => profile.update({ name: e.target.value })}
440
- placeholder="Name"
441
- />
442
- <button onClick={updateProfile}>Save Changes</button>
443
- </div>
444
- )}
445
-
446
- <h3>Your Posts ({posts.items.length})</h3>
447
- {posts.isLoading ? (
448
- <p>Loading posts...</p>
449
- ) : (
450
- <div>
451
- {posts.items.map((post, index) => (
452
- <div key={index}>
453
- <h4>{post.title}</h4>
454
- <p>{post.content}</p>
455
- </div>
456
- ))}
457
-
458
- <div className="pagination">
459
- {posts.hasPrevPage && (
460
- <button onClick={posts.prevPage}>Previous</button>
461
- )}
462
- <span>Page {posts.currentPage + 1} of {posts.totalPages}</span>
463
- {posts.hasNextPage && (
464
- <button onClick={posts.nextPage}>Next</button>
465
- )}
466
- </div>
467
- </div>
468
- )}
469
- </div>
470
- );
471
- }
472
- ```
473
-
474
- ### ZK-Proof Anonymous Authentication
475
-
476
- ZK-Proof (Zero-Knowledge Proof) authentication provides complete anonymity using Semaphore protocol. Users can authenticate without revealing their identity.
477
-
478
- ```tsx
479
- function ZkProofExample() {
480
- const { login, signUp } = useShogun();
481
- const [trapdoor, setTrapdoor] = useState("");
482
-
483
- // Signup: Creates anonymous identity and returns trapdoor
484
- const handleSignup = async () => {
485
- try {
486
- const result = await signUp("zkproof");
487
-
488
- if (result.success && result.seedPhrase) {
489
- // CRITICAL: User MUST save this trapdoor!
490
- // It's the ONLY way to recover the anonymous account
491
- console.log("Your trapdoor (save securely):", result.seedPhrase);
492
-
493
- // Recommend user to:
494
- // 1. Write it down on paper
495
- // 2. Store in password manager
496
- // 3. Keep multiple secure copies
497
- alert(`Save this trapdoor securely:\n\n${result.seedPhrase}\n\nYou'll need it to login on other devices!`);
498
- }
499
- } catch (error) {
500
- console.error("ZK-Proof signup failed:", error);
501
- }
502
- };
503
-
504
- // Login: Use saved trapdoor to restore anonymous identity
505
- const handleLogin = async () => {
506
- try {
507
- const result = await login("zkproof", trapdoor);
508
-
509
- if (result.success) {
510
- console.log("Logged in anonymously!");
511
- console.log("Identity commitment:", result.userPub);
512
- }
513
- } catch (error) {
514
- console.error("ZK-Proof login failed:", error);
515
- }
516
- };
517
-
518
- return (
519
- <div>
520
- <h3>Anonymous Authentication with ZK-Proof</h3>
521
-
522
- <div>
523
- <button onClick={handleSignup}>
524
- Create Anonymous Identity
525
- </button>
526
- </div>
527
-
528
- <div>
529
- <input
530
- type="text"
531
- value={trapdoor}
532
- onChange={(e) => setTrapdoor(e.target.value)}
533
- placeholder="Enter your trapdoor to login"
534
- />
535
- <button onClick={handleLogin}>
536
- Login Anonymously
537
- </button>
538
- </div>
539
- </div>
540
- );
541
- }
542
- ```
543
-
544
- **Important Notes about ZK-Proof:**
545
-
546
- - **Trapdoor is Critical**: The trapdoor is like a master password - without it, the account is permanently lost
547
- - **No Recovery**: Unlike traditional auth, there's no "forgot password" - trapdoor loss means permanent account loss
548
- - **Complete Anonymity**: Your identity remains private even from the application
549
- - **Multi-Device Support**: Use the same trapdoor on different devices
550
- - **Privacy-Preserving**: Uses Semaphore protocol for zero-knowledge proofs
551
-
552
- ### Connection Monitoring
553
-
554
- ```tsx
555
- function ConnectionStatus() {
556
- const { useGunConnection, useGunDebug } = useShogun();
557
-
558
- // Monitor connection status
559
- const connection = useGunConnection('user/data');
560
-
561
- // Enable debug logging
562
- useGunDebug('user/data', true);
563
-
564
- return (
565
- <div className="connection-status">
566
- <div className={`status-indicator ${connection.isConnected ? 'connected' : 'disconnected'}`}>
567
- {connection.isConnected ? '🟢 Connected' : '🔴 Disconnected'}
568
- </div>
569
-
570
- {connection.lastSeen && (
571
- <p>Last seen: {connection.lastSeen.toLocaleTimeString()}</p>
572
- )}
573
-
574
- {connection.error && (
575
- <p className="error">Error: {connection.error}</p>
576
- )}
577
- </div>
578
- );
579
- }
580
- ```
581
-
582
- ## 🎨 Customization
583
-
584
- ### CSS Variables
585
-
586
- Customize the appearance using CSS variables:
587
-
588
- ```css
589
- :root {
590
- /* Primary colors */
591
- --shogun-primary: #3b82f6;
592
- --shogun-primary-hover: #2563eb;
593
-
594
- /* Background colors */
595
- --shogun-bg: #ffffff;
596
- --shogun-bg-secondary: #f3f4f6;
597
-
598
- /* Text colors */
599
- --shogun-text: #1f2937;
600
- --shogun-text-secondary: #6b7280;
601
-
602
- /* Border and shadow */
603
- --shogun-border: #e5e7eb;
604
- --shogun-border-radius: 12px;
605
- --shogun-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
606
-
607
- /* Transitions */
608
- --shogun-transition: all 0.2s ease;
609
- }
610
-
611
- /* Dark mode overrides */
612
- @media (prefers-color-scheme: dark) {
613
- :root {
614
- --shogun-bg: #1f2937;
615
- --shogun-bg-secondary: #374151;
616
- --shogun-text: #f3f4f6;
617
- --shogun-text-secondary: #9ca3af;
618
- --shogun-border: #4b5563;
619
- }
620
- }
621
- ```
622
-
623
- ### Custom Styling
624
-
625
- ```css
626
- /* Custom button styles */
627
- .shogun-connect-button {
628
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
629
- border-radius: 25px;
630
- font-weight: 700;
631
- text-transform: uppercase;
632
- letter-spacing: 1px;
633
- }
634
-
635
- /* Custom modal styles */
636
- .shogun-modal {
637
- border-radius: 20px;
638
- box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
639
- }
640
-
641
- /* Custom form styles */
642
- .shogun-form-group input {
643
- border-radius: 10px;
644
- border: 2px solid transparent;
645
- transition: border-color 0.3s ease;
646
- }
647
-
648
- .shogun-form-group input:focus {
649
- border-color: var(--shogun-primary);
650
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
651
- }
652
- ```
653
-
654
- ## 🔧 Configuration Options
655
-
656
- ### Complete Configuration Interface
657
-
658
- ```typescript
659
- interface ShogunConnectorOptions {
660
- // App information
661
- appName: string;
662
-
663
- // Feature toggles
664
- showMetamask?: boolean;
665
- showWebauthn?: boolean;
666
- showNostr?: boolean;
667
- darkMode?: boolean;
668
-
669
- // Network configuration (backward compatible)
670
- peers?: string[];
671
- authToken?: string;
672
- gunInstance?: IGunInstance<any>;
673
- gunOptions?: any;
674
-
675
- // Transport layer configuration (new in v5.0.0)
676
- transport?: {
677
- type: "gun" | "sqlite" | "postgresql" | "mongodb" | "custom";
678
- options?: any;
679
- customTransport?: any;
680
- };
681
-
682
- // Timeouts and provider configs
683
- timeouts?: {
684
- login?: number;
685
- signup?: number;
686
- operation?: number;
687
- };
688
-
689
- // Gun Advanced Plugin configuration
690
- enableGunDebug?: boolean;
691
- enableConnectionMonitoring?: boolean;
692
- defaultPageSize?: number;
693
- connectionTimeout?: number;
694
- debounceInterval?: number;
695
- }
696
- ```
697
-
698
- ### Connector Result
699
-
700
- ```typescript
701
- interface ShogunConnectorResult {
702
- core: ShogunCore;
703
- options: ShogunConnectorOptions;
704
- setProvider: (provider: any) => boolean;
705
- getCurrentProviderUrl: () => string | null;
706
- registerPlugin: (plugin: any) => boolean;
707
- hasPlugin: (name: string) => boolean;
708
- gunPlugin: null;
709
- }
710
- ```
711
-
712
- ## 🌐 Browser Support
713
-
714
- - **Chrome** ≥ 60
715
- - **Firefox** ≥ 60
716
- - **Safari** ≥ 12
717
- - **Edge** ≥ 79
718
-
719
- ## 📱 Mobile Support
720
-
721
- The library is fully responsive and works seamlessly on mobile devices. All authentication methods are optimized for touch interfaces.
722
-
723
- ## 🔒 Security Features
724
-
725
- - **Encrypted Storage**: Gun pairs can be encrypted with passwords
726
- - **Secure Authentication**: Multiple secure authentication methods
727
- - **Session Management**: Automatic session handling and cleanup
728
- - **Error Handling**: Comprehensive error handling and user feedback
729
-
730
- ## 🚀 Performance
731
-
732
- - **Lazy Loading**: Components load only when needed
733
- - **Optimized Rendering**: Efficient React rendering with proper memoization
734
- - **Connection Pooling**: Smart connection management for optimal performance
735
- - **Debounced Updates**: Prevents excessive re-renders during rapid data changes
736
-
737
- ## 🤝 Contributing
738
-
739
- We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
740
-
741
- ### Development Setup
742
-
743
- ```bash
744
- # Clone the repository
745
- git clone https://github.com/shogun/shogun-button-react.git
746
-
747
- # Install dependencies
748
- yarn install
749
-
750
- # Start development server
751
- yarn dev
752
-
753
- # Build the library
754
- yarn build
755
-
756
- # Run tests
757
- yarn test
758
- ```
759
-
760
- ## 📄 License
761
-
762
- MIT © [Shogun](https://github.com/shogun)
763
-
764
- ## 🆘 Support
765
-
766
- - **Documentation**: [Full API Reference](https://docs.shogun.dev)
767
- - **Issues**: [GitHub Issues](https://github.com/shogun/shogun-button-react/issues)
768
- - **Discussions**: [GitHub Discussions](https://github.com/shogun/shogun-button-react/discussions)
769
- - **Discord**: [Join our community](https://discord.gg/shogun)
1
+ # Shogun Button React
2
+
3
+ A comprehensive React component library for seamless integration of Shogun authentication into your applications. This library provides a simple yet powerful way to add multi-method authentication, account management, and real-time data synchronization to your React applications.
4
+
5
+ > **Version 5.0.0** - Compatible with shogun-core ^2.0.0
6
+
7
+ ## ✨ Features
8
+
9
+ - 🚀 **Easy Integration** - Simple setup with minimal configuration
10
+ - 🎨 **Customizable UI** - Modern, responsive design with dark mode support
11
+ - 🔒 **Multi-Authentication** - Support for Password, MetaMask, WebAuthn, Nostr, and ZK-Proof
12
+ - 🛡️ **WebAuthn Recovery** - Restore hardware credentials on new devices with saved seed phrases
13
+ - 🔑 **Account Management** - Export/import Gun pairs for account backup and recovery
14
+ - 🕵️ **ZK-Proof Trapdoor Handoff** - Display and copy the generated trapdoor during signup to keep anonymous identities portable
15
+ - 📱 **Responsive Design** - Works seamlessly across all device sizes
16
+ - 🌍 **TypeScript Support** - Full type safety and IntelliSense support
17
+ - 🔌 **Plugin System** - Advanced Gun operations with custom hooks
18
+ - 📊 **Real-time Data** - Reactive data synchronization with RxJS observables
19
+ - ✅ **Robust Foundation** - Built on shogun-core v5.0.0 with 99.86% test coverage
20
+ - 🗄️ **Flexible Storage** - Support for GunDB, SQLite, PostgreSQL, MongoDB via TransportLayer
21
+
22
+ ## 📦 Requirements
23
+
24
+ - **React**: ^18.0.0
25
+ - **shogun-core**: ^2.0.0
26
+ - **Node.js**: ≥18
27
+
28
+ ## 🚀 Quick Start
29
+
30
+ ### Installation
31
+
32
+ ```bash
33
+ npm install shogun-button-react shogun-core
34
+ # or
35
+ yarn add shogun-button-react shogun-core
36
+ ```
37
+
38
+ ### Updating from 3.x
39
+
40
+ If you're upgrading from version 3.x:
41
+
42
+ ```bash
43
+ yarn upgrade shogun-button-react shogun-core
44
+ # or
45
+ npm update shogun-button-react shogun-core
46
+ ```
47
+
48
+ ### Basic Usage
49
+
50
+ ```tsx
51
+ import React from "react";
52
+ import { ShogunButton, ShogunButtonProvider, shogunConnector } from "shogun-button-react";
53
+ import "shogun-button-react/styles.css";
54
+
55
+ function App() {
56
+ const { core, options } = shogunConnector({
57
+ appName: "My Awesome App",
58
+ // Enable specific authentication methods
59
+ showMetamask: true,
60
+ showWebauthn: true,
61
+ showNostr: true,
62
+ showZkProof: true,
63
+ // Optional peers
64
+ peers: [
65
+ "https://gun-manhattan.herokuapp.com/gun"
66
+ ],
67
+ });
68
+
69
+ return (
70
+ <ShogunButtonProvider
71
+ core={core}
72
+ options={options}
73
+ onLoginSuccess={(data) => {
74
+ console.log("Login successful!", data);
75
+ }}
76
+ onSignupSuccess={(data) => {
77
+ console.log("Account created successfully!", data);
78
+ }}
79
+ onError={(error) => {
80
+ console.error("Authentication error:", error);
81
+ }}
82
+ >
83
+ <div className="app">
84
+ <header>
85
+ <h1>Welcome to My Awesome App</h1>
86
+ <ShogunButton />
87
+ </header>
88
+ <main>{/* Your app content */}</main>
89
+ </div>
90
+ </ShogunButtonProvider>
91
+ );
92
+ }
93
+
94
+ export default App;
95
+ ```
96
+
97
+ ## 🔧 Advanced Configuration
98
+
99
+ ### Custom Authentication Options
100
+
101
+ ```tsx
102
+ const { core, options } = shogunConnector({
103
+ appName: "My App",
104
+
105
+ // Toggle authentication methods in the UI
106
+ showMetamask: true,
107
+ showWebauthn: true,
108
+ showNostr: true,
109
+ showZkProof: true,
110
+
111
+ // Network configuration (backward compatible)
112
+ peers: [
113
+ "https://gun-manhattan.herokuapp.com/gun"
114
+ ],
115
+
116
+ // ZK-Proof configuration
117
+ zkproof: {
118
+ enabled: true,
119
+ defaultGroupId: "my-app-users",
120
+ },
121
+
122
+ // Gun Advanced Plugin configuration
123
+ enableGunDebug: true,
124
+ enableConnectionMonitoring: true,
125
+ defaultPageSize: 20,
126
+ connectionTimeout: 10000,
127
+ });
128
+ ```
129
+
130
+ ### Advanced Transport Layer Configuration (New in v5.0.0)
131
+
132
+ ```tsx
133
+ const { core, options } = shogunConnector({
134
+ appName: "My App",
135
+
136
+ // Use new transport layer system
137
+ transport: {
138
+ type: "gun", // or "sqlite", "postgresql", "mongodb", "custom"
139
+ options: {
140
+ peers: ["https://gun-manhattan.herokuapp.com/gun"],
141
+ // Additional transport-specific options
142
+ }
143
+ },
144
+
145
+ // Alternative: Use SQLite for local development
146
+ transport: {
147
+ type: "sqlite",
148
+ options: {
149
+ filename: "./my-app.db",
150
+ // SQLite-specific options
151
+ }
152
+ },
153
+
154
+ // Alternative: Use PostgreSQL for production
155
+ transport: {
156
+ type: "postgresql",
157
+ options: {
158
+ host: "localhost",
159
+ port: 5432,
160
+ database: "myapp",
161
+ username: "user",
162
+ password: "password",
163
+ // PostgreSQL-specific options
164
+ }
165
+ },
166
+
167
+ // Authentication methods
168
+ showMetamask: true,
169
+ showWebauthn: true,
170
+ showNostr: true,
171
+ showZkProof: true,
172
+ });
173
+ ```
174
+
175
+ ## 🔑 Recovery Flows
176
+
177
+ ### WebAuthn Multi-Device Restore
178
+
179
+ - Users now see a **Restore with Recovery Code** option when choosing WebAuthn login.
180
+ - Enter the username plus the stored seed phrase to recreate the credential on a new browser.
181
+ - The button calls `webauthnPlugin.signUp(username, { seedPhrase, generateSeedPhrase: false })` behind the scenes, leveraging the core plugin’s `importFromSeed` flow.
182
+ - After a successful restore the seed phrase is shown one more time so the user can double-check or re-copy it before the modal closes.
183
+
184
+ ### ZK-Proof Trapdoor Delivery
185
+
186
+ - Upon successful `zkproof` signup, the modal switches to a confirmation screen that displays the generated trapdoor (also returned as `seedPhrase`).
187
+ - A **Copy Trapdoor** helper copies the phrase to the clipboard, with inline feedback when the copy succeeds.
188
+ - The user must acknowledge with **I Saved My Trapdoor** before returning to the main UI, reducing the risk of losing the anonymous identity.
189
+
190
+ ## 🎯 API Reference
191
+
192
+ ### ShogunButtonProvider
193
+
194
+ The provider component that supplies Shogun context to your application.
195
+
196
+ #### Props
197
+
198
+ | Name | Type | Description | Required |
199
+ |------|------|-------------|----------|
200
+ | `core` | `ShogunCore` | Shogun SDK instance created by `shogunConnector` | ✅ |
201
+ | `options` | `ShogunConnectorOptions` | Configuration options | ✅ |
202
+ | `onLoginSuccess` | `(data: AuthData) => void` | Callback fired on successful login | ❌ |
203
+ | `onSignupSuccess` | `(data: AuthData) => void` | Callback fired on successful signup | ❌ |
204
+ | `onError` | `(error: string) => void` | Callback fired when an error occurs | ❌ |
205
+
206
+ #### AuthData Interface
207
+
208
+ ```typescript
209
+ interface AuthData {
210
+ userPub: string; // User's public key
211
+ username: string; // Display name
212
+ password?: string; // Password (if applicable)
213
+ seedPhrase?: string; // Seed phrase/trapdoor (for ZK-Proof)
214
+ authMethod?: "password" | "web3" | "webauthn" | "nostr" | "zkproof" | "pair";
215
+ }
216
+ ```
217
+
218
+ ### ShogunButton
219
+
220
+ The main button component that provides a complete authentication UI with modal dialogs for login, signup, and account management.
221
+
222
+ **Features:**
223
+ - Multi-method authentication selection
224
+ - Password-based login/signup with recovery
225
+ - Gun pair export/import for account backup
226
+ - Responsive modal design
227
+ - Error handling and user feedback
228
+
229
+ ### useShogun Hook
230
+
231
+ A comprehensive hook to access Shogun authentication state and functions.
232
+
233
+ ```tsx
234
+ import React, { useEffect } from "react";
235
+ import { useShogun } from "shogun-button-react";
236
+
237
+ function UserProfile() {
238
+ const {
239
+ // Authentication state
240
+ isLoggedIn,
241
+ userPub,
242
+ username,
243
+
244
+ // Authentication methods
245
+ login,
246
+ signUp,
247
+ logout,
248
+
249
+ // Plugin management
250
+ hasPlugin,
251
+ getPlugin,
252
+
253
+ // Account management
254
+ exportGunPair,
255
+ importGunPair,
256
+
257
+ // Data operations
258
+ observe,
259
+ put,
260
+ get,
261
+ remove,
262
+
263
+ // Advanced Gun hooks
264
+ useGunState,
265
+ useGunCollection,
266
+ useGunConnection,
267
+ useGunDebug,
268
+ useGunRealtime,
269
+ } = useShogun();
270
+
271
+ // Example: Login with different methods
272
+ const handlePasswordLogin = async () => {
273
+ try {
274
+ const result = await login("password", "username", "password");
275
+ if (result.success) {
276
+ console.log("Password login successful!");
277
+ }
278
+ } catch (error) {
279
+ console.error("Login failed:", error);
280
+ }
281
+ };
282
+
283
+ const handleMetaMaskLogin = async () => {
284
+ try {
285
+ const result = await login("web3");
286
+ if (result.success) {
287
+ console.log("MetaMask login successful!");
288
+ }
289
+ } catch (error) {
290
+ console.error("MetaMask login failed:", error);
291
+ }
292
+ };
293
+
294
+ const handleWebAuthnLogin = async () => {
295
+ try {
296
+ const result = await login("webauthn", "username");
297
+ if (result.success) {
298
+ console.log("WebAuthn login successful!");
299
+ }
300
+ } catch (error) {
301
+ console.error("WebAuthn login failed:", error);
302
+ }
303
+ };
304
+
305
+ const handleZkProofSignup = async () => {
306
+ try {
307
+ const result = await signUp("zkproof");
308
+ if (result.success && result.seedPhrase) {
309
+ console.log("ZK-Proof signup successful!");
310
+ console.log("SAVE THIS TRAPDOOR:", result.seedPhrase);
311
+ // CRITICAL: User must save the trapdoor for account recovery
312
+ }
313
+ } catch (error) {
314
+ console.error("ZK-Proof signup failed:", error);
315
+ }
316
+ };
317
+
318
+ const handleZkProofLogin = async () => {
319
+ try {
320
+ const trapdoor = "user-saved-trapdoor-here";
321
+ const result = await login("zkproof", trapdoor);
322
+ if (result.success) {
323
+ console.log("ZK-Proof anonymous login successful!");
324
+ }
325
+ } catch (error) {
326
+ console.error("ZK-Proof login failed:", error);
327
+ }
328
+ };
329
+
330
+ // Example: Account backup and recovery
331
+ const handleExportAccount = async () => {
332
+ try {
333
+ const pairData = await exportGunPair("my-secure-password");
334
+ console.log("Account exported successfully!");
335
+
336
+ // Save to file or copy to clipboard
337
+ if (navigator.clipboard) {
338
+ await navigator.clipboard.writeText(pairData);
339
+ alert("Account data copied to clipboard!");
340
+ }
341
+ } catch (error) {
342
+ console.error("Export failed:", error);
343
+ }
344
+ };
345
+
346
+ const handleImportAccount = async (pairData: string, password?: string) => {
347
+ try {
348
+ const success = await importGunPair(pairData, password);
349
+ if (success) {
350
+ console.log("Account imported successfully!");
351
+ }
352
+ } catch (error) {
353
+ console.error("Import failed:", error);
354
+ }
355
+ };
356
+
357
+ // Example: Real-time data observation
358
+ useEffect(() => {
359
+ if (isLoggedIn) {
360
+ const subscription = observe<any>('user/profile').subscribe(data => {
361
+ console.log('Profile updated:', data);
362
+ });
363
+
364
+ return () => subscription.unsubscribe();
365
+ }
366
+ }, [isLoggedIn, observe]);
367
+
368
+ if (!isLoggedIn) {
369
+ return <div>Please log in to view your profile</div>;
370
+ }
371
+
372
+ return (
373
+ <div className="user-profile">
374
+ <h2>Welcome, {username}!</h2>
375
+ <div className="profile-info">
376
+ <p><strong>Public Key:</strong> {userPub}</p>
377
+ <p><strong>Authentication Method:</strong> {authMethod}</p>
378
+ </div>
379
+
380
+ <div className="actions">
381
+ <button onClick={handleExportAccount}>Export Account</button>
382
+ <button onClick={logout}>Logout</button>
383
+ </div>
384
+ </div>
385
+ );
386
+ }
387
+ ```
388
+
389
+ ## 🔌 Advanced Gun Plugin Usage
390
+
391
+ ### Using Gun State Hooks
392
+
393
+ ```tsx
394
+ function UserSettings() {
395
+ const { useGunState, useGunCollection } = useShogun();
396
+
397
+ // Single value state
398
+ const profile = useGunState('user/profile', {
399
+ name: '',
400
+ email: '',
401
+ preferences: {}
402
+ });
403
+
404
+ // Collection management
405
+ const posts = useGunCollection('user/posts', {
406
+ pageSize: 10,
407
+ sortBy: 'createdAt',
408
+ sortOrder: 'desc',
409
+ filter: (post) => post.isPublished
410
+ });
411
+
412
+ const updateProfile = async () => {
413
+ await profile.update({
414
+ name: 'New Name',
415
+ preferences: { theme: 'dark' }
416
+ });
417
+ };
418
+
419
+ const addPost = async () => {
420
+ await posts.addItem({
421
+ title: 'New Post',
422
+ content: 'Post content...',
423
+ createdAt: Date.now(),
424
+ isPublished: true
425
+ });
426
+ };
427
+
428
+ return (
429
+ <div>
430
+ <h3>Profile Settings</h3>
431
+ {profile.isLoading ? (
432
+ <p>Loading...</p>
433
+ ) : profile.error ? (
434
+ <p>Error: {profile.error}</p>
435
+ ) : (
436
+ <div>
437
+ <input
438
+ value={profile.data?.name || ''}
439
+ onChange={(e) => profile.update({ name: e.target.value })}
440
+ placeholder="Name"
441
+ />
442
+ <button onClick={updateProfile}>Save Changes</button>
443
+ </div>
444
+ )}
445
+
446
+ <h3>Your Posts ({posts.items.length})</h3>
447
+ {posts.isLoading ? (
448
+ <p>Loading posts...</p>
449
+ ) : (
450
+ <div>
451
+ {posts.items.map((post, index) => (
452
+ <div key={index}>
453
+ <h4>{post.title}</h4>
454
+ <p>{post.content}</p>
455
+ </div>
456
+ ))}
457
+
458
+ <div className="pagination">
459
+ {posts.hasPrevPage && (
460
+ <button onClick={posts.prevPage}>Previous</button>
461
+ )}
462
+ <span>Page {posts.currentPage + 1} of {posts.totalPages}</span>
463
+ {posts.hasNextPage && (
464
+ <button onClick={posts.nextPage}>Next</button>
465
+ )}
466
+ </div>
467
+ </div>
468
+ )}
469
+ </div>
470
+ );
471
+ }
472
+ ```
473
+
474
+ ### ZK-Proof Anonymous Authentication
475
+
476
+ ZK-Proof (Zero-Knowledge Proof) authentication provides complete anonymity using Semaphore protocol. Users can authenticate without revealing their identity.
477
+
478
+ ```tsx
479
+ function ZkProofExample() {
480
+ const { login, signUp } = useShogun();
481
+ const [trapdoor, setTrapdoor] = useState("");
482
+
483
+ // Signup: Creates anonymous identity and returns trapdoor
484
+ const handleSignup = async () => {
485
+ try {
486
+ const result = await signUp("zkproof");
487
+
488
+ if (result.success && result.seedPhrase) {
489
+ // CRITICAL: User MUST save this trapdoor!
490
+ // It's the ONLY way to recover the anonymous account
491
+ console.log("Your trapdoor (save securely):", result.seedPhrase);
492
+
493
+ // Recommend user to:
494
+ // 1. Write it down on paper
495
+ // 2. Store in password manager
496
+ // 3. Keep multiple secure copies
497
+ alert(`Save this trapdoor securely:\n\n${result.seedPhrase}\n\nYou'll need it to login on other devices!`);
498
+ }
499
+ } catch (error) {
500
+ console.error("ZK-Proof signup failed:", error);
501
+ }
502
+ };
503
+
504
+ // Login: Use saved trapdoor to restore anonymous identity
505
+ const handleLogin = async () => {
506
+ try {
507
+ const result = await login("zkproof", trapdoor);
508
+
509
+ if (result.success) {
510
+ console.log("Logged in anonymously!");
511
+ console.log("Identity commitment:", result.userPub);
512
+ }
513
+ } catch (error) {
514
+ console.error("ZK-Proof login failed:", error);
515
+ }
516
+ };
517
+
518
+ return (
519
+ <div>
520
+ <h3>Anonymous Authentication with ZK-Proof</h3>
521
+
522
+ <div>
523
+ <button onClick={handleSignup}>
524
+ Create Anonymous Identity
525
+ </button>
526
+ </div>
527
+
528
+ <div>
529
+ <input
530
+ type="text"
531
+ value={trapdoor}
532
+ onChange={(e) => setTrapdoor(e.target.value)}
533
+ placeholder="Enter your trapdoor to login"
534
+ />
535
+ <button onClick={handleLogin}>
536
+ Login Anonymously
537
+ </button>
538
+ </div>
539
+ </div>
540
+ );
541
+ }
542
+ ```
543
+
544
+ **Important Notes about ZK-Proof:**
545
+
546
+ - **Trapdoor is Critical**: The trapdoor is like a master password - without it, the account is permanently lost
547
+ - **No Recovery**: Unlike traditional auth, there's no "forgot password" - trapdoor loss means permanent account loss
548
+ - **Complete Anonymity**: Your identity remains private even from the application
549
+ - **Multi-Device Support**: Use the same trapdoor on different devices
550
+ - **Privacy-Preserving**: Uses Semaphore protocol for zero-knowledge proofs
551
+
552
+ ### Connection Monitoring
553
+
554
+ ```tsx
555
+ function ConnectionStatus() {
556
+ const { useGunConnection, useGunDebug } = useShogun();
557
+
558
+ // Monitor connection status
559
+ const connection = useGunConnection('user/data');
560
+
561
+ // Enable debug logging
562
+ useGunDebug('user/data', true);
563
+
564
+ return (
565
+ <div className="connection-status">
566
+ <div className={`status-indicator ${connection.isConnected ? 'connected' : 'disconnected'}`}>
567
+ {connection.isConnected ? '🟢 Connected' : '🔴 Disconnected'}
568
+ </div>
569
+
570
+ {connection.lastSeen && (
571
+ <p>Last seen: {connection.lastSeen.toLocaleTimeString()}</p>
572
+ )}
573
+
574
+ {connection.error && (
575
+ <p className="error">Error: {connection.error}</p>
576
+ )}
577
+ </div>
578
+ );
579
+ }
580
+ ```
581
+
582
+ ## 🎨 Customization
583
+
584
+ ### CSS Variables
585
+
586
+ Customize the appearance using CSS variables:
587
+
588
+ ```css
589
+ :root {
590
+ /* Primary colors */
591
+ --shogun-primary: #3b82f6;
592
+ --shogun-primary-hover: #2563eb;
593
+
594
+ /* Background colors */
595
+ --shogun-bg: #ffffff;
596
+ --shogun-bg-secondary: #f3f4f6;
597
+
598
+ /* Text colors */
599
+ --shogun-text: #1f2937;
600
+ --shogun-text-secondary: #6b7280;
601
+
602
+ /* Border and shadow */
603
+ --shogun-border: #e5e7eb;
604
+ --shogun-border-radius: 12px;
605
+ --shogun-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
606
+
607
+ /* Transitions */
608
+ --shogun-transition: all 0.2s ease;
609
+ }
610
+
611
+ /* Dark mode overrides */
612
+ @media (prefers-color-scheme: dark) {
613
+ :root {
614
+ --shogun-bg: #1f2937;
615
+ --shogun-bg-secondary: #374151;
616
+ --shogun-text: #f3f4f6;
617
+ --shogun-text-secondary: #9ca3af;
618
+ --shogun-border: #4b5563;
619
+ }
620
+ }
621
+ ```
622
+
623
+ ### Custom Styling
624
+
625
+ ```css
626
+ /* Custom button styles */
627
+ .shogun-connect-button {
628
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
629
+ border-radius: 25px;
630
+ font-weight: 700;
631
+ text-transform: uppercase;
632
+ letter-spacing: 1px;
633
+ }
634
+
635
+ /* Custom modal styles */
636
+ .shogun-modal {
637
+ border-radius: 20px;
638
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
639
+ }
640
+
641
+ /* Custom form styles */
642
+ .shogun-form-group input {
643
+ border-radius: 10px;
644
+ border: 2px solid transparent;
645
+ transition: border-color 0.3s ease;
646
+ }
647
+
648
+ .shogun-form-group input:focus {
649
+ border-color: var(--shogun-primary);
650
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
651
+ }
652
+ ```
653
+
654
+ ## 🔧 Configuration Options
655
+
656
+ ### Complete Configuration Interface
657
+
658
+ ```typescript
659
+ interface ShogunConnectorOptions {
660
+ // App information
661
+ appName: string;
662
+
663
+ // Feature toggles
664
+ showMetamask?: boolean;
665
+ showWebauthn?: boolean;
666
+ showNostr?: boolean;
667
+ darkMode?: boolean;
668
+
669
+ // Network configuration (backward compatible)
670
+ peers?: string[];
671
+ authToken?: string;
672
+ gunInstance?: IGunInstance<any>;
673
+ gunOptions?: any;
674
+
675
+ // Transport layer configuration (new in v5.0.0)
676
+ transport?: {
677
+ type: "gun" | "sqlite" | "postgresql" | "mongodb" | "custom";
678
+ options?: any;
679
+ customTransport?: any;
680
+ };
681
+
682
+ // Timeouts and provider configs
683
+ timeouts?: {
684
+ login?: number;
685
+ signup?: number;
686
+ operation?: number;
687
+ };
688
+
689
+ // Gun Advanced Plugin configuration
690
+ enableGunDebug?: boolean;
691
+ enableConnectionMonitoring?: boolean;
692
+ defaultPageSize?: number;
693
+ connectionTimeout?: number;
694
+ debounceInterval?: number;
695
+ }
696
+ ```
697
+
698
+ ### Connector Result
699
+
700
+ ```typescript
701
+ interface ShogunConnectorResult {
702
+ core: ShogunCore;
703
+ options: ShogunConnectorOptions;
704
+ setProvider: (provider: any) => boolean;
705
+ getCurrentProviderUrl: () => string | null;
706
+ registerPlugin: (plugin: any) => boolean;
707
+ hasPlugin: (name: string) => boolean;
708
+ gunPlugin: null;
709
+ }
710
+ ```
711
+
712
+ ## 🌐 Browser Support
713
+
714
+ - **Chrome** ≥ 60
715
+ - **Firefox** ≥ 60
716
+ - **Safari** ≥ 12
717
+ - **Edge** ≥ 79
718
+
719
+ ## 📱 Mobile Support
720
+
721
+ The library is fully responsive and works seamlessly on mobile devices. All authentication methods are optimized for touch interfaces.
722
+
723
+ ## 🔒 Security Features
724
+
725
+ - **Encrypted Storage**: Gun pairs can be encrypted with passwords
726
+ - **Secure Authentication**: Multiple secure authentication methods
727
+ - **Session Management**: Automatic session handling and cleanup
728
+ - **Error Handling**: Comprehensive error handling and user feedback
729
+
730
+ ## 🚀 Performance
731
+
732
+ - **Lazy Loading**: Components load only when needed
733
+ - **Optimized Rendering**: Efficient React rendering with proper memoization
734
+ - **Connection Pooling**: Smart connection management for optimal performance
735
+ - **Debounced Updates**: Prevents excessive re-renders during rapid data changes
736
+
737
+ ## 🤝 Contributing
738
+
739
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
740
+
741
+ ### Development Setup
742
+
743
+ ```bash
744
+ # Clone the repository
745
+ git clone https://github.com/shogun/shogun-button-react.git
746
+
747
+ # Install dependencies
748
+ yarn install
749
+
750
+ # Start development server
751
+ yarn dev
752
+
753
+ # Build the library
754
+ yarn build
755
+
756
+ # Run tests
757
+ yarn test
758
+ ```
759
+
760
+ ## 📄 License
761
+
762
+ MIT © [Shogun](https://github.com/shogun)
763
+
764
+ ## 🆘 Support
765
+
766
+ - **Documentation**: [Full API Reference](https://docs.shogun.dev)
767
+ - **Issues**: [GitHub Issues](https://github.com/shogun/shogun-button-react/issues)
768
+ - **Discussions**: [GitHub Discussions](https://github.com/shogun/shogun-button-react/discussions)
769
+ - **Discord**: [Join our community](https://discord.gg/shogun)