shogun-button-react 1.3.11 → 1.3.13

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,19 +1,29 @@
1
1
  # Shogun Button React
2
2
 
3
- A React component library for seamless integration of Shogun authentication into your applications. This library provides a simple yet powerful way to add Shogun authentication to your React applications.
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
4
 
5
- ## Features
5
+ ## Features
6
6
 
7
- - 🚀 Easy to integrate
8
- - 🎨 Customizable UI components
9
- - 🔒 Secure authentication flow
10
- - 🌓 Dark mode support
11
- - 🔌 Multiple authentication methods (Username/Password, MetaMask, WebAuthn, Nostr, OAuth)
12
- - 🔑 Account backup and recovery (Gun pair export/import)
13
- - 📱 Responsive design
14
- - 🌍 TypeScript support
7
+ - 🚀 **Easy Integration** - Simple setup with minimal configuration
8
+ - 🎨 **Customizable UI** - Modern, responsive design with dark mode support
9
+ - 🔒 **Multi-Authentication** - Support for Password, MetaMask, WebAuthn, Nostr, and OAuth
10
+ - 🔑 **Account Management** - Export/import Gun pairs for account backup and recovery
11
+ - 📱 **Responsive Design** - Works seamlessly across all device sizes
12
+ - 🌍 **TypeScript Support** - Full type safety and IntelliSense support
13
+ - 🔌 **Plugin System** - Advanced Gun operations with custom hooks
14
+ - 📊 **Real-time Data** - Reactive data synchronization with RxJS observables
15
15
 
16
- ## Quick Start
16
+ ## 🚀 Quick Start
17
+
18
+ ### Installation
19
+
20
+ ```bash
21
+ npm install shogun-button-react
22
+ # or
23
+ yarn add shogun-button-react
24
+ ```
25
+
26
+ ### Basic Usage
17
27
 
18
28
  ```tsx
19
29
  import React from "react";
@@ -25,11 +35,16 @@ import {
25
35
  import "shogun-button-react/styles.css";
26
36
 
27
37
  function App() {
28
- const { sdk, options, setProvider } = shogunConnector({
29
- appName: "My App",
30
- appDescription: "An awesome app with Shogun authentication",
38
+ const { sdk, options } = shogunConnector({
39
+ appName: "My Awesome App",
40
+ appDescription: "A decentralized application with Shogun authentication",
31
41
  appUrl: "https://myapp.com",
32
42
  appIcon: "https://myapp.com/icon.png",
43
+ // Enable specific authentication methods
44
+ showMetamask: true,
45
+ showWebauthn: true,
46
+ showNostr: true,
47
+ showOauth: true,
33
48
  });
34
49
 
35
50
  return (
@@ -37,18 +52,33 @@ function App() {
37
52
  sdk={sdk}
38
53
  options={options}
39
54
  onLoginSuccess={(data) => {
40
- console.log("Login successful!", data);
55
+ console.log("🎉 Login successful!", data);
56
+ // Handle successful login
57
+ // data.userPub - User's public key
58
+ // data.username - Display name
59
+ // data.authMethod - Authentication method used
41
60
  }}
42
61
  onSignupSuccess={(data) => {
43
- console.log("Signup successful!", data);
62
+ console.log("🎊 Account created successfully!", data);
63
+ // Handle successful account creation
44
64
  }}
45
65
  onError={(error) => {
46
- console.error("An error occurred:", error);
66
+ console.error(" Authentication error:", error);
67
+ // Handle authentication errors
68
+ }}
69
+ onLogout={() => {
70
+ console.log("👋 User logged out");
71
+ // Handle logout events
47
72
  }}
48
73
  >
49
- <div>
50
- <h1>Welcome to My App</h1>
51
- <ShogunButton />
74
+ <div className="app">
75
+ <header>
76
+ <h1>Welcome to My Awesome App</h1>
77
+ <ShogunButton />
78
+ </header>
79
+ <main>
80
+ {/* Your app content */}
81
+ </main>
52
82
  </div>
53
83
  </ShogunButtonProvider>
54
84
  );
@@ -57,7 +87,56 @@ function App() {
57
87
  export default App;
58
88
  ```
59
89
 
60
- ## API Reference
90
+ ## 🔧 Advanced Configuration
91
+
92
+ ### Custom Authentication Options
93
+
94
+ ```tsx
95
+ const { sdk, options } = shogunConnector({
96
+ appName: "My App",
97
+
98
+ // Customize which authentication methods to show
99
+ showMetamask: true, // Enable MetaMask login
100
+ showWebauthn: true, // Enable WebAuthn (biometric/security keys)
101
+ showNostr: true, // Enable Nostr wallet connection
102
+ showOauth: true, // Enable OAuth providers
103
+
104
+ // Network configuration
105
+ peers: [
106
+ "https://gun-manhattan.herokuapp.com/gun",
107
+ "https://gun-us.herokuapp.com/gun"
108
+ ],
109
+
110
+ // OAuth provider configuration
111
+ oauth: {
112
+ providers: {
113
+ google: {
114
+ clientId: "your-google-client-id",
115
+ clientSecret: "your-google-client-secret",
116
+ redirectUri: "https://myapp.com/auth/callback"
117
+ },
118
+ github: {
119
+ clientId: "your-github-client-id",
120
+ redirectUri: "https://myapp.com/auth/callback"
121
+ }
122
+ }
123
+ },
124
+
125
+ // Advanced plugin configuration
126
+ enableGunDebug: true,
127
+ enableConnectionMonitoring: true,
128
+ defaultPageSize: 20,
129
+ connectionTimeout: 10000,
130
+
131
+ // Logging configuration
132
+ logging: {
133
+ enabled: true,
134
+ level: "info" // "error" | "warning" | "info" | "debug"
135
+ }
136
+ });
137
+ ```
138
+
139
+ ## 🎯 API Reference
61
140
 
62
141
  ### ShogunButtonProvider
63
142
 
@@ -65,125 +144,366 @@ The provider component that supplies Shogun context to your application.
65
144
 
66
145
  #### Props
67
146
 
68
- | Name | Type | Description |
69
- | --------------- | ------------------------ | ---------------------------------------------- |
70
- | sdk | ShogunCore | Shogun SDK instance created by shogunConnector |
71
- | options | Object | Configuration options |
72
- | onLoginSuccess | (data: { userPub: string; username: string; password?: string; authMethod?: string }) => void | Callback fired on successful login |
73
- | onSignupSuccess | (data: { userPub: string; username: string; password?: string; authMethod?: string }) => void | Callback fired on successful signup |
74
- | onError | (error: Error) => void | Callback fired when an error occurs |
147
+ | Name | Type | Description | Required |
148
+ |------|------|-------------|----------|
149
+ | `sdk` | `ShogunCore` | Shogun SDK instance created by `shogunConnector` | ✅ |
150
+ | `options` | `ShogunConnectorOptions` | Configuration options | ✅ |
151
+ | `onLoginSuccess` | `(data: AuthData) => void` | Callback fired on successful login | ❌ |
152
+ | `onSignupSuccess` | `(data: AuthData) => void` | Callback fired on successful signup | ❌ |
153
+ | `onError` | `(error: string) => void` | Callback fired when an error occurs | ❌ |
154
+ | `onLogout` | `() => void` | Callback fired when user logs out | ❌ |
155
+
156
+ #### AuthData Interface
157
+
158
+ ```typescript
159
+ interface AuthData {
160
+ userPub: string; // User's public key
161
+ username: string; // Display name
162
+ password?: string; // Password (if applicable)
163
+ authMethod?: "password" | "web3" | "webauthn" | "nostr" | "oauth" | "pair";
164
+ }
165
+ ```
75
166
 
76
167
  ### ShogunButton
77
168
 
78
- The main button component for triggering Shogun authentication. The component provides a complete authentication UI with modal dialogs for login and signup.
169
+ The main button component that provides a complete authentication UI with modal dialogs for login, signup, and account management.
170
+
171
+ **Features:**
172
+ - Multi-method authentication selection
173
+ - Password-based login/signup with recovery
174
+ - Gun pair export/import for account backup
175
+ - Responsive modal design
176
+ - Error handling and user feedback
79
177
 
80
178
  ### useShogun Hook
81
179
 
82
- A hook to access Shogun authentication state and functions.
180
+ A comprehensive hook to access Shogun authentication state and functions.
83
181
 
84
182
  ```tsx
85
183
  import React, { useEffect } from "react";
86
184
  import { useShogun } from "shogun-button-react";
87
185
 
88
- function Profile() {
186
+ function UserProfile() {
89
187
  const {
188
+ // Authentication state
90
189
  isLoggedIn,
91
190
  userPub,
92
191
  username,
192
+
193
+ // Authentication methods
93
194
  login,
94
- signup,
195
+ signUp,
95
196
  logout,
96
- setProvider,
197
+
198
+ // Plugin management
97
199
  hasPlugin,
98
200
  getPlugin,
201
+
202
+ // Account management
99
203
  exportGunPair,
100
204
  importGunPair,
205
+
206
+ // Data operations
101
207
  observe,
208
+ put,
209
+ get,
210
+ remove,
211
+
212
+ // Advanced Gun hooks
213
+ useGunState,
214
+ useGunCollection,
215
+ useGunConnection,
216
+ useGunDebug,
217
+ useGunRealtime,
102
218
  } = useShogun();
103
219
 
104
- const handleLogin = async () => {
105
- // Login with username/password
106
- await login("password", "username", "password");
107
-
108
- // Or login with MetaMask
109
- await login("web3");
110
-
111
- // Or login with WebAuthn
112
- await login("webauthn", "username");
113
-
114
- // Or login with Nostr
115
- await login("nostr");
116
-
117
- // Or login with OAuth
118
- await login("oauth", "google");
119
-
120
- // Or login with Gun pair (for account recovery)
121
- const pairData = { /* Gun pair object */ };
122
- await login("pair", pairData);
220
+ // Example: Login with different methods
221
+ const handlePasswordLogin = async () => {
222
+ try {
223
+ const result = await login("password", "username", "password");
224
+ if (result.success) {
225
+ console.log("Password login successful!");
226
+ }
227
+ } catch (error) {
228
+ console.error("Login failed:", error);
229
+ }
123
230
  };
124
231
 
125
- const handleSignUp = async () => {
126
- // Sign up with username/password
127
- await signup("password", "newusername", "newpassword");
128
-
129
- // Or sign up with other methods (similar to login)
130
- await signup("web3");
131
- await signup("webauthn", "newusername");
232
+ const handleMetaMaskLogin = async () => {
233
+ try {
234
+ const result = await login("web3");
235
+ if (result.success) {
236
+ console.log("MetaMask login successful!");
237
+ }
238
+ } catch (error) {
239
+ console.error("MetaMask login failed:", error);
240
+ }
132
241
  };
133
242
 
134
- const switchToCustomNetwork = () => {
135
- setProvider('https://my-custom-rpc.example.com');
243
+ const handleWebAuthnLogin = async () => {
244
+ try {
245
+ const result = await login("webauthn", "username");
246
+ if (result.success) {
247
+ console.log("WebAuthn login successful!");
248
+ }
249
+ } catch (error) {
250
+ console.error("WebAuthn login failed:", error);
251
+ }
136
252
  };
137
253
 
138
- const handleExportPair = async () => {
254
+ // Example: Account backup and recovery
255
+ const handleExportAccount = async () => {
139
256
  try {
140
- const pairData = await exportGunPair("optional-encryption-password");
141
- console.log("Exported pair:", pairData);
142
- // Save this data securely for account recovery
257
+ const pairData = await exportGunPair("my-secure-password");
258
+ console.log("Account exported successfully!");
259
+
260
+ // Save to file or copy to clipboard
261
+ if (navigator.clipboard) {
262
+ await navigator.clipboard.writeText(pairData);
263
+ alert("Account data copied to clipboard!");
264
+ }
143
265
  } catch (error) {
144
266
  console.error("Export failed:", error);
145
267
  }
146
268
  };
147
269
 
148
- const handleImportPair = async () => {
270
+ const handleImportAccount = async (pairData: string, password?: string) => {
149
271
  try {
150
- const success = await importGunPair(savedPairData, "optional-password");
272
+ const success = await importGunPair(pairData, password);
151
273
  if (success) {
152
- console.log("Pair imported successfully");
274
+ console.log("Account imported successfully!");
153
275
  }
154
276
  } catch (error) {
155
277
  console.error("Import failed:", error);
156
278
  }
157
279
  };
158
280
 
159
- // Observe reactive data changes
281
+ // Example: Real-time data observation
160
282
  useEffect(() => {
161
283
  if (isLoggedIn) {
162
284
  const subscription = observe<any>('user/profile').subscribe(data => {
163
- console.log('Profile data updated:', data);
285
+ console.log('Profile updated:', data);
164
286
  });
165
287
 
166
288
  return () => subscription.unsubscribe();
167
289
  }
168
290
  }, [isLoggedIn, observe]);
169
291
 
170
- return isLoggedIn ? (
171
- <div>
292
+ if (!isLoggedIn) {
293
+ return <div>Please log in to view your profile</div>;
294
+ }
295
+
296
+ return (
297
+ <div className="user-profile">
172
298
  <h2>Welcome, {username}!</h2>
173
- <p>User Public Key: {userPub}</p>
174
- <button onClick={logout}>Logout</button>
175
- <button onClick={switchToCustomNetwork}>Switch Network</button>
176
- <button onClick={handleExportPair}>Export Account</button>
299
+ <div className="profile-info">
300
+ <p><strong>Public Key:</strong> {userPub}</p>
301
+ <p><strong>Authentication Method:</strong> {authMethod}</p>
302
+ </div>
303
+
304
+ <div className="actions">
305
+ <button onClick={handleExportAccount}>
306
+ 🔒 Export Account
307
+ </button>
308
+ <button onClick={logout}>
309
+ 🚪 Logout
310
+ </button>
311
+ </div>
312
+ </div>
313
+ );
314
+ }
315
+ ```
316
+
317
+ ## 🔌 Advanced Gun Plugin Usage
318
+
319
+ ### Using Gun State Hooks
320
+
321
+ ```tsx
322
+ function UserSettings() {
323
+ const { useGunState, useGunCollection } = useShogun();
324
+
325
+ // Single value state
326
+ const profile = useGunState('user/profile', {
327
+ name: '',
328
+ email: '',
329
+ preferences: {}
330
+ });
331
+
332
+ // Collection management
333
+ const posts = useGunCollection('user/posts', {
334
+ pageSize: 10,
335
+ sortBy: 'createdAt',
336
+ sortOrder: 'desc',
337
+ filter: (post) => post.isPublished
338
+ });
339
+
340
+ const updateProfile = async () => {
341
+ await profile.update({
342
+ name: 'New Name',
343
+ preferences: { theme: 'dark' }
344
+ });
345
+ };
346
+
347
+ const addPost = async () => {
348
+ await posts.addItem({
349
+ title: 'New Post',
350
+ content: 'Post content...',
351
+ createdAt: Date.now(),
352
+ isPublished: true
353
+ });
354
+ };
355
+
356
+ return (
357
+ <div>
358
+ <h3>Profile Settings</h3>
359
+ {profile.isLoading ? (
360
+ <p>Loading...</p>
361
+ ) : profile.error ? (
362
+ <p>Error: {profile.error}</p>
363
+ ) : (
364
+ <div>
365
+ <input
366
+ value={profile.data?.name || ''}
367
+ onChange={(e) => profile.update({ name: e.target.value })}
368
+ placeholder="Name"
369
+ />
370
+ <button onClick={updateProfile}>Save Changes</button>
371
+ </div>
372
+ )}
373
+
374
+ <h3>Your Posts ({posts.items.length})</h3>
375
+ {posts.isLoading ? (
376
+ <p>Loading posts...</p>
377
+ ) : (
378
+ <div>
379
+ {posts.items.map((post, index) => (
380
+ <div key={index}>
381
+ <h4>{post.title}</h4>
382
+ <p>{post.content}</p>
383
+ </div>
384
+ ))}
385
+
386
+ <div className="pagination">
387
+ {posts.hasPrevPage && (
388
+ <button onClick={posts.prevPage}>Previous</button>
389
+ )}
390
+ <span>Page {posts.currentPage + 1} of {posts.totalPages}</span>
391
+ {posts.hasNextPage && (
392
+ <button onClick={posts.nextPage}>Next</button>
393
+ )}
394
+ </div>
395
+ </div>
396
+ )}
397
+ </div>
398
+ );
399
+ }
400
+ ```
401
+
402
+ ### Connection Monitoring
403
+
404
+ ```tsx
405
+ function ConnectionStatus() {
406
+ const { useGunConnection, useGunDebug } = useShogun();
407
+
408
+ // Monitor connection status
409
+ const connection = useGunConnection('user/data');
410
+
411
+ // Enable debug logging
412
+ useGunDebug('user/data', true);
413
+
414
+ return (
415
+ <div className="connection-status">
416
+ <div className={`status-indicator ${connection.isConnected ? 'connected' : 'disconnected'}`}>
417
+ {connection.isConnected ? '🟢 Connected' : '🔴 Disconnected'}
418
+ </div>
419
+
420
+ {connection.lastSeen && (
421
+ <p>Last seen: {connection.lastSeen.toLocaleTimeString()}</p>
422
+ )}
423
+
424
+ {connection.error && (
425
+ <p className="error">Error: {connection.error}</p>
426
+ )}
177
427
  </div>
178
- ) : (
179
- <div>Please login to continue</div>
180
428
  );
181
429
  }
182
430
  ```
183
431
 
184
- ## Configuration Options
432
+ ## 🎨 Customization
433
+
434
+ ### CSS Variables
185
435
 
186
- The `shogunConnector` accepts the following options:
436
+ Customize the appearance using CSS variables:
437
+
438
+ ```css
439
+ :root {
440
+ /* Primary colors */
441
+ --shogun-primary: #3b82f6;
442
+ --shogun-primary-hover: #2563eb;
443
+
444
+ /* Background colors */
445
+ --shogun-bg: #ffffff;
446
+ --shogun-bg-secondary: #f3f4f6;
447
+
448
+ /* Text colors */
449
+ --shogun-text: #1f2937;
450
+ --shogun-text-secondary: #6b7280;
451
+
452
+ /* Border and shadow */
453
+ --shogun-border: #e5e7eb;
454
+ --shogun-border-radius: 12px;
455
+ --shogun-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
456
+
457
+ /* Transitions */
458
+ --shogun-transition: all 0.2s ease;
459
+ }
460
+
461
+ /* Dark mode overrides */
462
+ @media (prefers-color-scheme: dark) {
463
+ :root {
464
+ --shogun-bg: #1f2937;
465
+ --shogun-bg-secondary: #374151;
466
+ --shogun-text: #f3f4f6;
467
+ --shogun-text-secondary: #9ca3af;
468
+ --shogun-border: #4b5563;
469
+ }
470
+ }
471
+ ```
472
+
473
+ ### Custom Styling
474
+
475
+ ```css
476
+ /* Custom button styles */
477
+ .shogun-connect-button {
478
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
479
+ border-radius: 25px;
480
+ font-weight: 700;
481
+ text-transform: uppercase;
482
+ letter-spacing: 1px;
483
+ }
484
+
485
+ /* Custom modal styles */
486
+ .shogun-modal {
487
+ border-radius: 20px;
488
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
489
+ }
490
+
491
+ /* Custom form styles */
492
+ .shogun-form-group input {
493
+ border-radius: 10px;
494
+ border: 2px solid transparent;
495
+ transition: border-color 0.3s ease;
496
+ }
497
+
498
+ .shogun-form-group input:focus {
499
+ border-color: var(--shogun-primary);
500
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
501
+ }
502
+ ```
503
+
504
+ ## 🔧 Configuration Options
505
+
506
+ ### Complete Configuration Interface
187
507
 
188
508
  ```typescript
189
509
  interface ShogunConnectorOptions {
@@ -223,50 +543,84 @@ interface ShogunConnectorOptions {
223
543
  clientSecret?: string;
224
544
  redirectUri?: string;
225
545
  }>
226
- }
546
+ };
547
+
548
+ // Gun Advanced Plugin configuration
549
+ enableGunDebug?: boolean;
550
+ enableConnectionMonitoring?: boolean;
551
+ defaultPageSize?: number;
552
+ connectionTimeout?: number;
553
+ debounceInterval?: number;
227
554
  }
228
555
  ```
229
556
 
230
- The `shogunConnector` returns an object with the following properties:
557
+ ### Connector Result
231
558
 
232
559
  ```typescript
233
560
  interface ShogunConnectorResult {
234
561
  sdk: ShogunCore;
235
562
  options: ShogunConnectorOptions;
236
- setProvider: (provider: string | EthersProvider) => boolean;
237
- getCurrentProviderUrl: () => string | null;
238
563
  registerPlugin: (plugin: any) => boolean;
239
564
  hasPlugin: (name: string) => boolean;
565
+ gunPlugin: GunAdvancedPlugin;
240
566
  }
241
567
  ```
242
568
 
243
- > **Note**: The `setProvider` method attempts to update the RPC provider URL used by the SDK. This functionality depends on the specific version of Shogun Core you're using. If the SDK does not have a public `setRpcUrl` method available, the provider URL will still be saved but not applied to the SDK directly. In such cases, the setting will only be available through the `getCurrentProviderUrl` method.
569
+ ## 🌐 Browser Support
244
570
 
245
- ## Styling
571
+ - **Chrome** ≥ 60
572
+ - **Firefox** ≥ 60
573
+ - **Safari** ≥ 12
574
+ - **Edge** ≥ 79
246
575
 
247
- The component comes with default styling that you can override using CSS variables:
576
+ ## 📱 Mobile Support
248
577
 
249
- ```css
250
- :root {
251
- --shogun-button-primary: #5c6bc0;
252
- --shogun-button-hover: #3f51b5;
253
- --shogun-text-primary: #333333;
254
- --shogun-background: #ffffff;
255
- /* ... other variables */
256
- }
257
- ```
578
+ The library is fully responsive and works seamlessly on mobile devices. All authentication methods are optimized for touch interfaces.
579
+
580
+ ## 🔒 Security Features
258
581
 
259
- ## Browser Support
582
+ - **Encrypted Storage**: Gun pairs can be encrypted with passwords
583
+ - **Secure Authentication**: Multiple secure authentication methods
584
+ - **Session Management**: Automatic session handling and cleanup
585
+ - **Error Handling**: Comprehensive error handling and user feedback
260
586
 
261
- - Chrome ≥ 60
262
- - Firefox ≥ 60
263
- - Safari ≥ 12
264
- - Edge ≥ 79
587
+ ## 🚀 Performance
265
588
 
266
- ## Contributing
589
+ - **Lazy Loading**: Components load only when needed
590
+ - **Optimized Rendering**: Efficient React rendering with proper memoization
591
+ - **Connection Pooling**: Smart connection management for optimal performance
592
+ - **Debounced Updates**: Prevents excessive re-renders during rapid data changes
593
+
594
+ ## 🤝 Contributing
267
595
 
268
596
  We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
269
597
 
270
- ## License
598
+ ### Development Setup
599
+
600
+ ```bash
601
+ # Clone the repository
602
+ git clone https://github.com/shogun/shogun-button-react.git
603
+
604
+ # Install dependencies
605
+ yarn install
606
+
607
+ # Start development server
608
+ yarn dev
609
+
610
+ # Build the library
611
+ yarn build
612
+
613
+ # Run tests
614
+ yarn test
615
+ ```
616
+
617
+ ## 📄 License
271
618
 
272
619
  MIT © [Shogun](https://github.com/shogun)
620
+
621
+ ## 🆘 Support
622
+
623
+ - **Documentation**: [Full API Reference](https://docs.shogun.dev)
624
+ - **Issues**: [GitHub Issues](https://github.com/shogun/shogun-button-react/issues)
625
+ - **Discussions**: [GitHub Discussions](https://github.com/shogun/shogun-button-react/discussions)
626
+ - **Discord**: [Join our community](https://discord.gg/shogun)