shogun-button-react 1.5.2 → 1.5.6
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/CHANGELOG.md +54 -0
- package/README.md +457 -103
- package/dist/components/ShogunButton.d.ts +17 -0
- package/dist/components/ShogunButton.js +97 -15
- package/dist/connector.js +17 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/plugins/GunAdvancedPlugin.d.ts +79 -0
- package/dist/plugins/GunAdvancedPlugin.js +498 -0
- package/dist/types/connector-options.d.ts +6 -0
- package/package.json +1 -1
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
|
|
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
|
|
8
|
-
- 🎨 Customizable UI
|
|
9
|
-
- 🔒
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
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
|
|
29
|
-
appName: "My App",
|
|
30
|
-
appDescription: "
|
|
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("
|
|
62
|
+
console.log("🎊 Account created successfully!", data);
|
|
63
|
+
// Handle successful account creation
|
|
44
64
|
}}
|
|
45
65
|
onError={(error) => {
|
|
46
|
-
console.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
|
-
<
|
|
51
|
-
|
|
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
|
-
##
|
|
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
|
|
69
|
-
|
|
70
|
-
| sdk
|
|
71
|
-
| options
|
|
72
|
-
| onLoginSuccess
|
|
73
|
-
| onSignupSuccess | (data:
|
|
74
|
-
| onError
|
|
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
|
|
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
|
|
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
|
-
|
|
195
|
+
signUp,
|
|
95
196
|
logout,
|
|
96
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
|
135
|
-
|
|
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
|
-
|
|
254
|
+
// Example: Account backup and recovery
|
|
255
|
+
const handleExportAccount = async () => {
|
|
139
256
|
try {
|
|
140
|
-
const pairData = await exportGunPair("
|
|
141
|
-
console.log("
|
|
142
|
-
|
|
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
|
|
270
|
+
const handleImportAccount = async (pairData: string, password?: string) => {
|
|
149
271
|
try {
|
|
150
|
-
const success = await importGunPair(
|
|
272
|
+
const success = await importGunPair(pairData, password);
|
|
151
273
|
if (success) {
|
|
152
|
-
console.log("
|
|
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
|
-
//
|
|
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
|
|
285
|
+
console.log('Profile updated:', data);
|
|
164
286
|
});
|
|
165
287
|
|
|
166
288
|
return () => subscription.unsubscribe();
|
|
167
289
|
}
|
|
168
290
|
}, [isLoggedIn, observe]);
|
|
169
291
|
|
|
170
|
-
|
|
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
|
-
<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
##
|
|
432
|
+
## 🎨 Customization
|
|
433
|
+
|
|
434
|
+
### CSS Variables
|
|
185
435
|
|
|
186
|
-
|
|
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
|
-
|
|
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
|
-
|
|
569
|
+
## 🌐 Browser Support
|
|
244
570
|
|
|
245
|
-
|
|
571
|
+
- **Chrome** ≥ 60
|
|
572
|
+
- **Firefox** ≥ 60
|
|
573
|
+
- **Safari** ≥ 12
|
|
574
|
+
- **Edge** ≥ 79
|
|
246
575
|
|
|
247
|
-
|
|
576
|
+
## 📱 Mobile Support
|
|
248
577
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
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
|
-
|
|
262
|
-
- Firefox ≥ 60
|
|
263
|
-
- Safari ≥ 12
|
|
264
|
-
- Edge ≥ 79
|
|
587
|
+
## 🚀 Performance
|
|
265
588
|
|
|
266
|
-
|
|
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
|
-
|
|
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)
|