shogun-button-react 3.0.20 → 4.0.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/CHANGELOG.md CHANGED
@@ -1,6 +1,76 @@
1
1
  # Changelog
2
2
 
3
- ## Version 1.3.4 (Latest)
3
+ ## Version 4.0.0 (Latest)
4
+
5
+ ### 💥 Breaking Changes
6
+ - **OAuth Removed**: Removed OAuth authentication support following removal from shogun-core
7
+ - Removed `showOauth` option from `ShogunConnectorOptions`
8
+ - Removed `oauth` configuration from connector options
9
+ - Removed OAuth login/signup methods from button component
10
+ - Removed Google OAuth icon and UI elements
11
+ - Updated `authMethod` type to exclude "oauth"
12
+
13
+ ### ✨ New Features
14
+ - **ZK-Proof Authentication**: Added support for anonymous authentication using Zero-Knowledge Proofs
15
+ - New `showZkProof` option to enable/disable ZK-Proof in UI
16
+ - `zkproof` configuration for customizing ZK-Proof settings
17
+ - Login with trapdoor (recovery phrase)
18
+ - Signup generates new anonymous identity with trapdoor
19
+ - Complete anonymity using Semaphore protocol
20
+ - Multi-device support with same trapdoor
21
+ - Added ZK-Proof icon and UI components
22
+ - Added `authMethod: "zkproof"` support
23
+ - Added `seedPhrase` field to `AuthData` interface for trapdoor backup
24
+
25
+ ### ⬆️ Dependencies Update
26
+ - **shogun-core**: Updated from `^3.3.8` to `^4.0.0`
27
+ - **rxjs**: Updated from `^7.8.1` to `^7.8.2` (aligned with shogun-core 4.0.0)
28
+
29
+ ### 🔄 Migration Guide
30
+ If you were using OAuth authentication:
31
+ - Remove `showOauth` property from your `shogunConnector` configuration
32
+ - Remove `oauth` provider configuration
33
+ - Use alternative authentication methods: Password, MetaMask, WebAuthn, or Nostr
34
+
35
+ For updating from version 3.x:
36
+ - Update dependencies: `yarn upgrade shogun-button-react shogun-core`
37
+ - No API changes required - all existing functionality is maintained
38
+ - Verify compatibility with shogun-core 4.0.0 features
39
+ - New ZK-Proof authentication available (opt-in via `showZkProof: true`)
40
+
41
+ ### 📝 New Configuration Options
42
+
43
+ ```typescript
44
+ const { core, options } = shogunConnector({
45
+ appName: "My App",
46
+ showZkProof: true, // Enable ZK-Proof authentication
47
+ zkproof: {
48
+ enabled: true,
49
+ defaultGroupId: "my-app-users",
50
+ },
51
+ });
52
+ ```
53
+
54
+ ### 🔐 ZK-Proof Authentication Flow
55
+
56
+ **Signup:**
57
+ ```typescript
58
+ const result = await signUp("zkproof");
59
+ if (result.success && result.seedPhrase) {
60
+ // User MUST save the seedPhrase (trapdoor)
61
+ console.log("Save this trapdoor:", result.seedPhrase);
62
+ }
63
+ ```
64
+
65
+ **Login:**
66
+ ```typescript
67
+ const result = await login("zkproof", savedTrapdoor);
68
+ if (result.success) {
69
+ console.log("Logged in anonymously!");
70
+ }
71
+ ```
72
+
73
+ ## Version 1.3.4
4
74
 
5
75
  ### 🐛 Bug Fixes
6
76
  - **Export Gun Pair Fix**: Fixed issue where "Export Pair" option was not accessible from user dropdown - now works correctly without requiring disconnect
package/README.md CHANGED
@@ -2,25 +2,43 @@
2
2
 
3
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
+ > **Version 4.0.0** - Compatible with shogun-core ^4.0.0
6
+
5
7
  ## ✨ Features
6
8
 
7
9
  - 🚀 **Easy Integration** - Simple setup with minimal configuration
8
10
  - 🎨 **Customizable UI** - Modern, responsive design with dark mode support
9
- - 🔒 **Multi-Authentication** - Support for Password, MetaMask, WebAuthn, Nostr, and OAuth
11
+ - 🔒 **Multi-Authentication** - Support for Password, MetaMask, WebAuthn, Nostr, and ZK-Proof
10
12
  - 🔑 **Account Management** - Export/import Gun pairs for account backup and recovery
11
13
  - 📱 **Responsive Design** - Works seamlessly across all device sizes
12
14
  - 🌍 **TypeScript Support** - Full type safety and IntelliSense support
13
15
  - 🔌 **Plugin System** - Advanced Gun operations with custom hooks
14
16
  - 📊 **Real-time Data** - Reactive data synchronization with RxJS observables
15
17
 
18
+ ## 📦 Requirements
19
+
20
+ - **React**: ^18.0.0
21
+ - **shogun-core**: ^4.0.0
22
+ - **Node.js**: ≥18
23
+
16
24
  ## 🚀 Quick Start
17
25
 
18
26
  ### Installation
19
27
 
20
28
  ```bash
21
- npm install shogun-button-react
29
+ npm install shogun-button-react shogun-core
22
30
  # or
23
- yarn add shogun-button-react
31
+ yarn add shogun-button-react shogun-core
32
+ ```
33
+
34
+ ### Updating from 3.x
35
+
36
+ If you're upgrading from version 3.x:
37
+
38
+ ```bash
39
+ yarn upgrade shogun-button-react shogun-core
40
+ # or
41
+ npm update shogun-button-react shogun-core
24
42
  ```
25
43
 
26
44
  ### Basic Usage
@@ -37,7 +55,7 @@ function App() {
37
55
  showMetamask: true,
38
56
  showWebauthn: true,
39
57
  showNostr: true,
40
- showOauth: true,
58
+ showZkProof: true,
41
59
  // Optional peers
42
60
  peers: [
43
61
  "https://gun-manhattan.herokuapp.com/gun"
@@ -84,21 +102,17 @@ const { core, options } = shogunConnector({
84
102
  showMetamask: true,
85
103
  showWebauthn: true,
86
104
  showNostr: true,
87
- showOauth: true,
105
+ showZkProof: true,
88
106
 
89
107
  // Network configuration
90
108
  peers: [
91
109
  "https://gun-manhattan.herokuapp.com/gun"
92
110
  ],
93
111
 
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
- }
112
+ // ZK-Proof configuration
113
+ zkproof: {
114
+ enabled: true,
115
+ defaultGroupId: "my-app-users",
102
116
  },
103
117
 
104
118
  // Gun Advanced Plugin configuration
@@ -132,7 +146,8 @@ interface AuthData {
132
146
  userPub: string; // User's public key
133
147
  username: string; // Display name
134
148
  password?: string; // Password (if applicable)
135
- authMethod?: "password" | "web3" | "webauthn" | "nostr" | "oauth" | "pair";
149
+ seedPhrase?: string; // Seed phrase/trapdoor (for ZK-Proof)
150
+ authMethod?: "password" | "web3" | "webauthn" | "nostr" | "zkproof" | "pair";
136
151
  }
137
152
  ```
138
153
 
@@ -223,6 +238,31 @@ function UserProfile() {
223
238
  }
224
239
  };
225
240
 
241
+ const handleZkProofSignup = async () => {
242
+ try {
243
+ const result = await signUp("zkproof");
244
+ if (result.success && result.seedPhrase) {
245
+ console.log("ZK-Proof signup successful!");
246
+ console.log("SAVE THIS TRAPDOOR:", result.seedPhrase);
247
+ // CRITICAL: User must save the trapdoor for account recovery
248
+ }
249
+ } catch (error) {
250
+ console.error("ZK-Proof signup failed:", error);
251
+ }
252
+ };
253
+
254
+ const handleZkProofLogin = async () => {
255
+ try {
256
+ const trapdoor = "user-saved-trapdoor-here";
257
+ const result = await login("zkproof", trapdoor);
258
+ if (result.success) {
259
+ console.log("ZK-Proof anonymous login successful!");
260
+ }
261
+ } catch (error) {
262
+ console.error("ZK-Proof login failed:", error);
263
+ }
264
+ };
265
+
226
266
  // Example: Account backup and recovery
227
267
  const handleExportAccount = async () => {
228
268
  try {
@@ -367,6 +407,84 @@ function UserSettings() {
367
407
  }
368
408
  ```
369
409
 
410
+ ### ZK-Proof Anonymous Authentication
411
+
412
+ ZK-Proof (Zero-Knowledge Proof) authentication provides complete anonymity using Semaphore protocol. Users can authenticate without revealing their identity.
413
+
414
+ ```tsx
415
+ function ZkProofExample() {
416
+ const { login, signUp } = useShogun();
417
+ const [trapdoor, setTrapdoor] = useState("");
418
+
419
+ // Signup: Creates anonymous identity and returns trapdoor
420
+ const handleSignup = async () => {
421
+ try {
422
+ const result = await signUp("zkproof");
423
+
424
+ if (result.success && result.seedPhrase) {
425
+ // CRITICAL: User MUST save this trapdoor!
426
+ // It's the ONLY way to recover the anonymous account
427
+ console.log("Your trapdoor (save securely):", result.seedPhrase);
428
+
429
+ // Recommend user to:
430
+ // 1. Write it down on paper
431
+ // 2. Store in password manager
432
+ // 3. Keep multiple secure copies
433
+ alert(`Save this trapdoor securely:\n\n${result.seedPhrase}\n\nYou'll need it to login on other devices!`);
434
+ }
435
+ } catch (error) {
436
+ console.error("ZK-Proof signup failed:", error);
437
+ }
438
+ };
439
+
440
+ // Login: Use saved trapdoor to restore anonymous identity
441
+ const handleLogin = async () => {
442
+ try {
443
+ const result = await login("zkproof", trapdoor);
444
+
445
+ if (result.success) {
446
+ console.log("Logged in anonymously!");
447
+ console.log("Identity commitment:", result.userPub);
448
+ }
449
+ } catch (error) {
450
+ console.error("ZK-Proof login failed:", error);
451
+ }
452
+ };
453
+
454
+ return (
455
+ <div>
456
+ <h3>Anonymous Authentication with ZK-Proof</h3>
457
+
458
+ <div>
459
+ <button onClick={handleSignup}>
460
+ Create Anonymous Identity
461
+ </button>
462
+ </div>
463
+
464
+ <div>
465
+ <input
466
+ type="text"
467
+ value={trapdoor}
468
+ onChange={(e) => setTrapdoor(e.target.value)}
469
+ placeholder="Enter your trapdoor to login"
470
+ />
471
+ <button onClick={handleLogin}>
472
+ Login Anonymously
473
+ </button>
474
+ </div>
475
+ </div>
476
+ );
477
+ }
478
+ ```
479
+
480
+ **Important Notes about ZK-Proof:**
481
+
482
+ - **Trapdoor is Critical**: The trapdoor is like a master password - without it, the account is permanently lost
483
+ - **No Recovery**: Unlike traditional auth, there's no "forgot password" - trapdoor loss means permanent account loss
484
+ - **Complete Anonymity**: Your identity remains private even from the application
485
+ - **Multi-Device Support**: Use the same trapdoor on different devices
486
+ - **Privacy-Preserving**: Uses Semaphore protocol for zero-knowledge proofs
487
+
370
488
  ### Connection Monitoring
371
489
 
372
490
  ```tsx
@@ -482,7 +600,6 @@ interface ShogunConnectorOptions {
482
600
  showMetamask?: boolean;
483
601
  showWebauthn?: boolean;
484
602
  showNostr?: boolean;
485
- showOauth?: boolean;
486
603
  darkMode?: boolean;
487
604
 
488
605
  // Network configuration
@@ -496,13 +613,6 @@ interface ShogunConnectorOptions {
496
613
  signup?: number;
497
614
  operation?: number;
498
615
  };
499
- oauth?: {
500
- providers: Record<string, {
501
- clientId: string;
502
- redirectUri?: string;
503
- clientSecret?: string;
504
- }>;
505
- };
506
616
 
507
617
  // Gun Advanced Plugin configuration
508
618
  enableGunDebug?: boolean;
@@ -44,13 +44,14 @@ type ShogunButtonProviderProps = {
44
44
  userPub: string;
45
45
  username: string;
46
46
  password?: string;
47
- authMethod?: "password" | "web3" | "webauthn" | "nostr" | "oauth";
47
+ authMethod?: "password" | "web3" | "webauthn" | "nostr" | "zkproof";
48
48
  }) => void;
49
49
  onSignupSuccess?: (data: {
50
50
  userPub: string;
51
51
  username: string;
52
52
  password?: string;
53
- authMethod?: "password" | "web3" | "webauthn" | "nostr" | "oauth";
53
+ seedPhrase?: string;
54
+ authMethod?: "password" | "web3" | "webauthn" | "nostr" | "zkproof";
54
55
  }) => void;
55
56
  onError?: (error: string) => void;
56
57
  };
@@ -140,16 +140,18 @@ export function ShogunButtonProvider({ children, core, options, onLoginSuccess,
140
140
  username = pubkey;
141
141
  result = await nostr.login(pubkey);
142
142
  break;
143
- case "oauth":
144
- const oauth = core.getPlugin("oauth");
145
- if (!oauth)
146
- throw new Error("OAuth plugin not available");
147
- const provider = args[0] || "google";
148
- result = await oauth.login(provider);
149
- authMethod = "oauth";
150
- if (result.redirectUrl) {
151
- return result;
143
+ case "zkproof":
144
+ const trapdoor = args[0];
145
+ if (!trapdoor || typeof trapdoor !== "string") {
146
+ throw new Error("Invalid trapdoor provided");
152
147
  }
148
+ const zkproof = core.getPlugin("zkproof");
149
+ if (!zkproof)
150
+ throw new Error("ZK-Proof plugin not available");
151
+ const zkLoginResult = await zkproof.login(trapdoor);
152
+ result = zkLoginResult;
153
+ username = zkLoginResult.username || zkLoginResult.alias || `zk_${(zkLoginResult.userPub || "").slice(0, 16)}`;
154
+ authMethod = "zkproof";
153
155
  break;
154
156
  default:
155
157
  throw new Error("Unsupported login method");
@@ -226,16 +228,15 @@ export function ShogunButtonProvider({ children, core, options, onLoginSuccess,
226
228
  username = pubkey;
227
229
  result = await nostr.signUp(pubkey);
228
230
  break;
229
- case "oauth":
230
- const oauth = core.getPlugin("oauth");
231
- if (!oauth)
232
- throw new Error("OAuth plugin not available");
233
- const provider = args[0] || "google";
234
- result = await oauth.signUp(provider);
235
- authMethod = "oauth";
236
- if (result.redirectUrl) {
237
- return result;
238
- }
231
+ case "zkproof":
232
+ const zkproofPlugin = core.getPlugin("zkproof");
233
+ if (!zkproofPlugin)
234
+ throw new Error("ZK-Proof plugin not available");
235
+ const seed = args[0]; // Optional seed
236
+ const zkSignupResult = await zkproofPlugin.signUp(seed);
237
+ result = zkSignupResult;
238
+ username = zkSignupResult.username || zkSignupResult.alias || `zk_${(zkSignupResult.userPub || "").slice(0, 16)}`;
239
+ authMethod = "zkproof";
239
240
  break;
240
241
  default:
241
242
  throw new Error("Unsupported signup method");
@@ -249,6 +250,7 @@ export function ShogunButtonProvider({ children, core, options, onLoginSuccess,
249
250
  onSignupSuccess === null || onSignupSuccess === void 0 ? void 0 : onSignupSuccess({
250
251
  userPub: userPub,
251
252
  username: displayName,
253
+ seedPhrase: result.seedPhrase, // Include seedPhrase/trapdoor for ZK-Proof
252
254
  authMethod: authMethod,
253
255
  });
254
256
  }
@@ -489,11 +491,6 @@ const KeyIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org/20
489
491
  React.createElement("circle", { cx: "7.5", cy: "15.5", r: "5.5" }),
490
492
  React.createElement("path", { d: "m21 2-9.6 9.6" }),
491
493
  React.createElement("path", { d: "m15.5 7.5 3 3L22 7l-3-3" })));
492
- const GoogleIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor" },
493
- React.createElement("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z", fill: "#4285F4" }),
494
- React.createElement("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z", fill: "#34A853" }),
495
- React.createElement("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }),
496
- React.createElement("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })));
497
494
  const NostrIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
498
495
  React.createElement("path", { d: "M19.5 4.5 15 9l-3-3-4.5 4.5L9 12l-1.5 1.5L12 18l4.5-4.5L15 12l1.5-1.5L21 6l-1.5-1.5Z" }),
499
496
  React.createElement("path", { d: "M12 12 6 6l-1.5 1.5L9 12l-4.5 4.5L6 18l6-6Z" })));
@@ -518,6 +515,10 @@ const ImportIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org
518
515
  React.createElement("polyline", { points: "14,2 14,8 20,8" }),
519
516
  React.createElement("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
520
517
  React.createElement("line", { x1: "12", y1: "17", x2: "12", y2: "9" })));
518
+ const ZkProofIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
519
+ React.createElement("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
520
+ React.createElement("path", { d: "M2 17l10 5 10-5" }),
521
+ React.createElement("path", { d: "M2 12l10 5 10-5" })));
521
522
  const ExportIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
522
523
  React.createElement("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
523
524
  React.createElement("polyline", { points: "14,2 14,8 20,8" }),
@@ -547,6 +548,8 @@ export const ShogunButton = (() => {
547
548
  const [exportedPair, setExportedPair] = useState("");
548
549
  const [showCopySuccess, setShowCopySuccess] = useState(false);
549
550
  const [showImportSuccess, setShowImportSuccess] = useState(false);
551
+ const [zkTrapdoor, setZkTrapdoor] = useState("");
552
+ const [zkGeneratedTrapdoor, setZkGeneratedTrapdoor] = useState("");
550
553
  const dropdownRef = useRef(null);
551
554
  // Handle click outside to close dropdown
552
555
  useEffect(() => {
@@ -662,7 +665,57 @@ export const ShogunButton = (() => {
662
665
  setAuthView("webauthn-username");
663
666
  };
664
667
  const handleNostrAuth = () => handleAuth("nostr");
665
- const handleOAuth = (provider) => handleAuth("oauth", provider);
668
+ const handleZkProofAuth = () => {
669
+ if (!(core === null || core === void 0 ? void 0 : core.hasPlugin("zkproof"))) {
670
+ setError("ZK-Proof plugin not available");
671
+ return;
672
+ }
673
+ if (formMode === "login") {
674
+ setAuthView("zkproof-login");
675
+ }
676
+ else {
677
+ // For signup, directly call signUp and show trapdoor
678
+ handleZkProofSignup();
679
+ }
680
+ };
681
+ const handleZkProofLogin = async () => {
682
+ setError("");
683
+ setLoading(true);
684
+ try {
685
+ if (!zkTrapdoor.trim()) {
686
+ throw new Error("Please enter your trapdoor");
687
+ }
688
+ await handleAuth("zkproof", zkTrapdoor);
689
+ setModalIsOpen(false);
690
+ }
691
+ catch (e) {
692
+ setError(e.message || "ZK-Proof login failed");
693
+ }
694
+ finally {
695
+ setLoading(false);
696
+ }
697
+ };
698
+ const handleZkProofSignup = async () => {
699
+ setError("");
700
+ setLoading(true);
701
+ try {
702
+ const result = await signUp("zkproof");
703
+ if (result && result.success && result.seedPhrase) {
704
+ // Show the trapdoor to the user - CRITICAL for account recovery!
705
+ setZkGeneratedTrapdoor(result.seedPhrase);
706
+ setAuthView("zkproof-signup-result");
707
+ }
708
+ else if (result && !result.success) {
709
+ throw new Error(result.error || "ZK-Proof signup failed");
710
+ }
711
+ }
712
+ catch (e) {
713
+ setError(e.message || "ZK-Proof signup failed");
714
+ }
715
+ finally {
716
+ setLoading(false);
717
+ }
718
+ };
666
719
  const handleRecover = async () => {
667
720
  setError("");
668
721
  setLoading(true);
@@ -751,6 +804,8 @@ export const ShogunButton = (() => {
751
804
  setShowCopySuccess(false);
752
805
  setShowImportSuccess(false);
753
806
  setRecoveredHint("");
807
+ setZkTrapdoor("");
808
+ setZkGeneratedTrapdoor("");
754
809
  };
755
810
  const openModal = () => {
756
811
  resetForm();
@@ -783,12 +838,12 @@ export const ShogunButton = (() => {
783
838
  React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: () => handleAuth("nostr"), disabled: loading },
784
839
  React.createElement(NostrIcon, null),
785
840
  formMode === "login" ? "Login with Nostr" : "Signup with Nostr"))),
786
- options.showOauth !== false && (core === null || core === void 0 ? void 0 : core.hasPlugin("oauth")) && (React.createElement("div", { className: "shogun-auth-option-group" },
787
- React.createElement("button", { type: "button", className: "shogun-auth-option-button shogun-google-button", onClick: () => handleAuth("oauth", "google"), disabled: loading },
788
- React.createElement(GoogleIcon, null),
841
+ options.showZkProof !== false && (core === null || core === void 0 ? void 0 : core.hasPlugin("zkproof")) && (React.createElement("div", { className: "shogun-auth-option-group" },
842
+ React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: handleZkProofAuth, disabled: loading },
843
+ React.createElement(ZkProofIcon, null),
789
844
  formMode === "login"
790
- ? "Login with Google"
791
- : "Signup with Google"))),
845
+ ? "Login with ZK-Proof"
846
+ : "Signup with ZK-Proof"))),
792
847
  React.createElement("div", { className: "shogun-divider" },
793
848
  React.createElement("span", null, "or")),
794
849
  React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: () => setAuthView("password"), disabled: loading },
@@ -952,6 +1007,83 @@ export const ShogunButton = (() => {
952
1007
  setExportedPair("");
953
1008
  }
954
1009
  }, disabled: loading }, "Back"))));
1010
+ const renderZkProofLoginForm = () => (React.createElement("div", { className: "shogun-auth-form" },
1011
+ React.createElement("h3", null, "Login with ZK-Proof"),
1012
+ React.createElement("div", { style: {
1013
+ backgroundColor: "#f0f9ff",
1014
+ padding: "12px",
1015
+ borderRadius: "8px",
1016
+ marginBottom: "16px",
1017
+ border: "1px solid #0ea5e9",
1018
+ } },
1019
+ React.createElement("p", { style: {
1020
+ fontSize: "14px",
1021
+ color: "#0c4a6e",
1022
+ margin: "0",
1023
+ fontWeight: "500",
1024
+ } }, "\uD83D\uDD12 Anonymous Authentication"),
1025
+ React.createElement("p", { style: { fontSize: "13px", color: "#075985", margin: "4px 0 0 0" } }, "Enter your trapdoor (recovery phrase) to login anonymously using Zero-Knowledge Proofs. Your identity remains private.")),
1026
+ React.createElement("div", { className: "shogun-form-group" },
1027
+ React.createElement("label", { htmlFor: "zkTrapdoor" },
1028
+ React.createElement(KeyIcon, null),
1029
+ React.createElement("span", null, "Trapdoor / Recovery Phrase")),
1030
+ React.createElement("textarea", { id: "zkTrapdoor", value: zkTrapdoor, onChange: (e) => setZkTrapdoor(e.target.value), disabled: loading, placeholder: "Enter your trapdoor...", rows: 4, style: {
1031
+ fontFamily: "monospace",
1032
+ fontSize: "12px",
1033
+ width: "100%",
1034
+ padding: "8px",
1035
+ border: "1px solid #ccc",
1036
+ borderRadius: "4px",
1037
+ } })),
1038
+ React.createElement("button", { type: "button", className: "shogun-submit-button", onClick: handleZkProofLogin, disabled: loading || !zkTrapdoor.trim() }, loading ? "Processing..." : "Login Anonymously"),
1039
+ React.createElement("div", { className: "shogun-form-footer" },
1040
+ React.createElement("button", { className: "shogun-toggle-mode", onClick: () => setAuthView("options"), disabled: loading }, "Back to Login Options"))));
1041
+ const renderZkProofSignupResult = () => (React.createElement("div", { className: "shogun-auth-form" },
1042
+ React.createElement("h3", null, "ZK-Proof Account Created!"),
1043
+ React.createElement("div", { style: {
1044
+ backgroundColor: "#fef3c7",
1045
+ padding: "12px",
1046
+ borderRadius: "8px",
1047
+ marginBottom: "16px",
1048
+ border: "1px solid #f59e0b",
1049
+ } },
1050
+ React.createElement("p", { style: {
1051
+ fontSize: "14px",
1052
+ color: "#92400e",
1053
+ margin: "0",
1054
+ fontWeight: "500",
1055
+ } }, "\u26A0\uFE0F CRITICAL: Save Your Trapdoor!"),
1056
+ React.createElement("p", { style: { fontSize: "13px", color: "#a16207", margin: "4px 0 0 0" } }, "This is your ONLY way to recover your anonymous account. Save it in a secure location. If you lose it, you will lose access to your account permanently.")),
1057
+ React.createElement("div", { className: "shogun-form-group" },
1058
+ React.createElement("label", null, "Your Trapdoor (Recovery Phrase):"),
1059
+ React.createElement("textarea", { value: zkGeneratedTrapdoor, readOnly: true, rows: 4, style: {
1060
+ fontFamily: "monospace",
1061
+ fontSize: "12px",
1062
+ width: "100%",
1063
+ padding: "8px",
1064
+ border: "2px solid #f59e0b",
1065
+ borderRadius: "4px",
1066
+ backgroundColor: "#fffbeb",
1067
+ } }),
1068
+ React.createElement("button", { type: "button", className: "shogun-submit-button", style: { marginTop: "8px" }, onClick: async () => {
1069
+ if (navigator.clipboard) {
1070
+ await navigator.clipboard.writeText(zkGeneratedTrapdoor);
1071
+ setShowCopySuccess(true);
1072
+ setTimeout(() => setShowCopySuccess(false), 3000);
1073
+ }
1074
+ } }, showCopySuccess ? "✅ Copied!" : "📋 Copy Trapdoor"),
1075
+ !navigator.clipboard && (React.createElement("p", { style: { fontSize: "12px", color: "#666", marginTop: "8px" } }, "\u26A0\uFE0F Please manually copy the trapdoor above."))),
1076
+ React.createElement("div", { style: {
1077
+ backgroundColor: "#dcfce7",
1078
+ color: "#166534",
1079
+ padding: "12px",
1080
+ borderRadius: "8px",
1081
+ marginTop: "16px",
1082
+ fontSize: "14px",
1083
+ border: "1px solid #22c55e",
1084
+ textAlign: "center",
1085
+ } }, "\u2705 You're now logged in anonymously!"),
1086
+ React.createElement("button", { type: "button", className: "shogun-submit-button", style: { marginTop: "16px" }, onClick: () => setModalIsOpen(false) }, "Close and Start Using App")));
955
1087
  const renderImportForm = () => (React.createElement("div", { className: "shogun-auth-form" },
956
1088
  React.createElement("h3", null, "Import Gun Pair"),
957
1089
  React.createElement("div", { style: {
@@ -1024,9 +1156,13 @@ export const ShogunButton = (() => {
1024
1156
  ? "Import Gun Pair"
1025
1157
  : authView === "webauthn-username"
1026
1158
  ? "WebAuthn"
1027
- : formMode === "login"
1028
- ? "Login"
1029
- : "Sign Up"),
1159
+ : authView === "zkproof-login"
1160
+ ? "ZK-Proof Login"
1161
+ : authView === "zkproof-signup-result"
1162
+ ? "ZK-Proof Account"
1163
+ : formMode === "login"
1164
+ ? "Login"
1165
+ : "Sign Up"),
1030
1166
  React.createElement("button", { className: "shogun-close-button", onClick: closeModal, "aria-label": "Close" },
1031
1167
  React.createElement(CloseIcon, null))),
1032
1168
  React.createElement("div", { className: "shogun-modal-content" },
@@ -1045,7 +1181,10 @@ export const ShogunButton = (() => {
1045
1181
  authView === "export" && renderExportForm(),
1046
1182
  authView === "import" && renderImportForm(),
1047
1183
  authView === "webauthn-username" &&
1048
- renderWebAuthnUsernameForm()))))));
1184
+ renderWebAuthnUsernameForm(),
1185
+ authView === "zkproof-login" && renderZkProofLoginForm(),
1186
+ authView === "zkproof-signup-result" &&
1187
+ renderZkProofSignupResult()))))));
1049
1188
  };
1050
1189
  Button.displayName = "ShogunButton";
1051
1190
  return Object.assign(Button, {
package/dist/connector.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import { ShogunCore } from "shogun-core";
2
2
  import { GunAdvancedPlugin } from "./plugins/GunAdvancedPlugin";
3
3
  export function shogunConnector(options) {
4
- const { gunInstance, gunOptions, appName, timeouts, oauth, webauthn, nostr, web3, showOauth, showWebauthn, showNostr, showMetamask, darkMode, enableGunDebug = true, enableConnectionMonitoring = true, defaultPageSize = 20, connectionTimeout = 10000, debounceInterval = 100, ...restOptions } = options;
4
+ const { gunInstance, gunOptions, appName, timeouts, webauthn, nostr, web3, zkproof, showWebauthn, showNostr, showMetamask, showZkProof, darkMode, enableGunDebug = true, enableConnectionMonitoring = true, defaultPageSize = 20, connectionTimeout = 10000, debounceInterval = 100, ...restOptions } = options;
5
5
  const core = new ShogunCore({
6
6
  gunOptions: gunOptions || undefined,
7
7
  gunInstance: gunInstance || undefined,
8
- oauth,
9
8
  webauthn,
10
9
  nostr,
11
10
  web3,
11
+ zkproof,
12
12
  timeouts,
13
13
  });
14
14
  const setProvider = (provider) => {
@@ -1,4 +1,4 @@
1
- import { ShogunCore, GunInstance } from "shogun-core";
1
+ import { ShogunCore, IGunInstance } from "shogun-core";
2
2
  import { GunAdvancedPlugin } from "../plugins/GunAdvancedPlugin";
3
3
  export interface ShogunConnectorOptions {
4
4
  appName: string;
@@ -8,22 +8,15 @@ export interface ShogunConnectorOptions {
8
8
  showMetamask?: boolean;
9
9
  showWebauthn?: boolean;
10
10
  showNostr?: boolean;
11
- showOauth?: boolean;
11
+ showZkProof?: boolean;
12
12
  darkMode?: boolean;
13
- gunInstance?: GunInstance;
13
+ gunInstance?: IGunInstance;
14
14
  gunOptions?: any;
15
15
  timeouts?: {
16
16
  login?: number;
17
17
  signup?: number;
18
18
  operation?: number;
19
19
  };
20
- oauth?: {
21
- providers: Record<string, {
22
- clientId: string;
23
- clientSecret?: string;
24
- redirectUri?: string;
25
- }>;
26
- };
27
20
  webauthn?: {
28
21
  enabled?: boolean;
29
22
  };
@@ -33,6 +26,10 @@ export interface ShogunConnectorOptions {
33
26
  web3?: {
34
27
  enabled?: boolean;
35
28
  };
29
+ zkproof?: {
30
+ enabled?: boolean;
31
+ defaultGroupId?: string;
32
+ };
36
33
  enableGunDebug?: boolean;
37
34
  enableConnectionMonitoring?: boolean;
38
35
  defaultPageSize?: number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shogun-button-react",
3
3
  "description": "Shogun connector button",
4
- "version": "3.0.20",
4
+ "version": "4.0.0",
5
5
  "files": [
6
6
  "dist",
7
7
  "src/styles/index.css"
@@ -33,8 +33,8 @@
33
33
  "dependencies": {
34
34
  "ethers": "^6.13.5",
35
35
  "prettier": "^3.5.3",
36
- "rxjs": "^7.8.1",
37
- "shogun-core": "^3.0.20"
36
+ "rxjs": "^7.8.2",
37
+ "shogun-core": "^4.0.0"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "react": "^18.0.0",