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