shogun-button-react 1.3.8 → 1.3.9

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.
@@ -1,10 +1,11 @@
1
- import React, { useContext, useState, createContext, useEffect, useRef } from "react";
1
+ import React, { useContext, useState, createContext, useEffect, useRef, } from "react";
2
2
  import { Observable } from "rxjs";
3
+ import { GunAdvancedPlugin } from "../plugins/GunAdvancedPlugin";
3
4
  import "../types/index.js"; // Import type file to extend definitions
4
5
  import "../styles/index.css";
5
6
  // Default context
6
7
  const defaultShogunContext = {
7
- sdk: null,
8
+ core: null,
8
9
  options: {},
9
10
  isLoggedIn: false,
10
11
  userPub: null,
@@ -18,13 +19,22 @@ const defaultShogunContext = {
18
19
  getPlugin: () => undefined,
19
20
  exportGunPair: async () => "",
20
21
  importGunPair: async () => false,
22
+ gunPlugin: null,
23
+ useGunState: () => ({}),
24
+ useGunCollection: () => ({}),
25
+ useGunConnection: () => ({ isConnected: false, lastSeen: null, error: null }),
26
+ useGunDebug: () => { },
27
+ useGunRealtime: () => ({ data: null, key: null }),
28
+ put: async () => { },
29
+ get: () => null,
30
+ remove: async () => { },
21
31
  };
22
32
  // Create context using React's createContext directly
23
33
  const ShogunContext = createContext(defaultShogunContext);
24
34
  // Custom hook to access the context
25
35
  export const useShogun = () => useContext(ShogunContext);
26
36
  // Provider component
27
- export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, onSignupSuccess, onError, }) {
37
+ export function ShogunButtonProvider({ children, core, options, onLoginSuccess, onSignupSuccess, onError, }) {
28
38
  // Use React's useState directly
29
39
  const [isLoggedIn, setIsLoggedIn] = useState(false);
30
40
  const [userPub, setUserPub] = useState(null);
@@ -32,32 +42,32 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
32
42
  // Effetto per gestire l'inizializzazione e pulizia
33
43
  useEffect(() => {
34
44
  var _a, _b;
35
- if (!sdk)
45
+ if (!core)
36
46
  return;
37
47
  // Verifichiamo se l'utente è già loggato all'inizializzazione
38
- if (sdk.isLoggedIn()) {
39
- const pub = (_b = (_a = sdk.gun.user()) === null || _a === void 0 ? void 0 : _a.is) === null || _b === void 0 ? void 0 : _b.pub;
48
+ if (core.isLoggedIn()) {
49
+ const pub = (_b = (_a = core.gun.user()) === null || _a === void 0 ? void 0 : _a.is) === null || _b === void 0 ? void 0 : _b.pub;
40
50
  if (pub) {
41
51
  setIsLoggedIn(true);
42
52
  setUserPub(pub);
43
- setUsername(pub.slice(0, 8) + '...');
53
+ setUsername(pub.slice(0, 8) + "...");
44
54
  }
45
55
  }
46
- // Poiché il metodo 'on' non esiste su ShogunCore,
56
+ // Poiché il metodo 'on' non esiste su ShogunCore,
47
57
  // gestiamo gli stati direttamente nei metodi di login/logout
48
- }, [sdk, onLoginSuccess]);
58
+ }, [core, onLoginSuccess]);
49
59
  // RxJS observe method
50
60
  const observe = (path) => {
51
- if (!sdk) {
61
+ if (!core) {
52
62
  return new Observable();
53
63
  }
54
- return sdk.observe(path);
64
+ return core.observe(path);
55
65
  };
56
66
  // Unified login
57
67
  const login = async (method, ...args) => {
58
68
  var _a, _b;
59
69
  try {
60
- if (!sdk) {
70
+ if (!core) {
61
71
  throw new Error("SDK not initialized");
62
72
  }
63
73
  let result;
@@ -66,16 +76,16 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
66
76
  switch (method) {
67
77
  case "password":
68
78
  username = args[0];
69
- result = await sdk.login(args[0], args[1]);
79
+ result = await core.login(args[0], args[1]);
70
80
  break;
71
81
  case "pair":
72
82
  // New pair authentication method
73
83
  const pair = args[0];
74
- if (!pair || typeof pair !== 'object') {
84
+ if (!pair || typeof pair !== "object") {
75
85
  throw new Error("Invalid pair data provided");
76
86
  }
77
87
  result = await new Promise((resolve, reject) => {
78
- sdk.gun.user().auth(pair, (ack) => {
88
+ core.gun.user().auth(pair, (ack) => {
79
89
  if (ack.err) {
80
90
  reject(new Error(`Pair authentication failed: ${ack.err}`));
81
91
  return;
@@ -86,7 +96,7 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
86
96
  success: true,
87
97
  userPub: pub,
88
98
  alias: alias,
89
- method: 'pair'
99
+ method: "pair",
90
100
  });
91
101
  });
92
102
  });
@@ -95,13 +105,13 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
95
105
  break;
96
106
  case "webauthn":
97
107
  username = args[0];
98
- const webauthn = sdk.getPlugin("webauthn");
108
+ const webauthn = core.getPlugin("webauthn");
99
109
  if (!webauthn)
100
110
  throw new Error("WebAuthn plugin not available");
101
111
  result = await webauthn.login(username);
102
112
  break;
103
113
  case "web3":
104
- const web3 = sdk.getPlugin("web3");
114
+ const web3 = core.getPlugin("web3");
105
115
  if (!web3)
106
116
  throw new Error("Web3 plugin not available");
107
117
  const connectionResult = await web3.connectMetaMask();
@@ -112,7 +122,7 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
112
122
  result = await web3.login(connectionResult.address);
113
123
  break;
114
124
  case "nostr":
115
- const nostr = sdk.getPlugin("nostr");
125
+ const nostr = core.getPlugin("nostr");
116
126
  if (!nostr)
117
127
  throw new Error("Nostr plugin not available");
118
128
  const nostrResult = await nostr.connectBitcoinWallet();
@@ -126,7 +136,7 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
126
136
  result = await nostr.login(pubkey);
127
137
  break;
128
138
  case "oauth":
129
- const oauth = sdk.getPlugin("oauth");
139
+ const oauth = core.getPlugin("oauth");
130
140
  if (!oauth)
131
141
  throw new Error("OAuth plugin not available");
132
142
  const provider = args[0] || "google";
@@ -140,8 +150,8 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
140
150
  throw new Error("Unsupported login method");
141
151
  }
142
152
  if (result.success) {
143
- const userPub = result.userPub || ((_b = (_a = sdk.gun.user()) === null || _a === void 0 ? void 0 : _a.is) === null || _b === void 0 ? void 0 : _b.pub) || "";
144
- const displayName = result.alias || username || userPub.slice(0, 8) + '...';
153
+ const userPub = result.userPub || ((_b = (_a = core.gun.user()) === null || _a === void 0 ? void 0 : _a.is) === null || _b === void 0 ? void 0 : _b.pub) || "";
154
+ const displayName = result.alias || username || userPub.slice(0, 8) + "...";
145
155
  setIsLoggedIn(true);
146
156
  setUserPub(userPub);
147
157
  setUsername(displayName);
@@ -165,7 +175,7 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
165
175
  const signUp = async (method, ...args) => {
166
176
  var _a, _b;
167
177
  try {
168
- if (!sdk) {
178
+ if (!core) {
169
179
  throw new Error("SDK not initialized");
170
180
  }
171
181
  let result;
@@ -177,17 +187,17 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
177
187
  if (args[1] !== args[2]) {
178
188
  throw new Error("Passwords do not match");
179
189
  }
180
- result = await sdk.signUp(args[0], args[1]);
190
+ result = await core.signUp(args[0], args[1]);
181
191
  break;
182
192
  case "webauthn":
183
193
  username = args[0];
184
- const webauthn = sdk.getPlugin("webauthn");
194
+ const webauthn = core.getPlugin("webauthn");
185
195
  if (!webauthn)
186
196
  throw new Error("WebAuthn plugin not available");
187
197
  result = await webauthn.signUp(username);
188
198
  break;
189
199
  case "web3":
190
- const web3 = sdk.getPlugin("web3");
200
+ const web3 = core.getPlugin("web3");
191
201
  if (!web3)
192
202
  throw new Error("Web3 plugin not available");
193
203
  const connectionResult = await web3.connectMetaMask();
@@ -198,7 +208,7 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
198
208
  result = await web3.signUp(connectionResult.address);
199
209
  break;
200
210
  case "nostr":
201
- const nostr = sdk.getPlugin("nostr");
211
+ const nostr = core.getPlugin("nostr");
202
212
  if (!nostr)
203
213
  throw new Error("Nostr plugin not available");
204
214
  const nostrResult = await nostr.connectBitcoinWallet();
@@ -212,7 +222,7 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
212
222
  result = await nostr.signUp(pubkey);
213
223
  break;
214
224
  case "oauth":
215
- const oauth = sdk.getPlugin("oauth");
225
+ const oauth = core.getPlugin("oauth");
216
226
  if (!oauth)
217
227
  throw new Error("OAuth plugin not available");
218
228
  const provider = args[0] || "google";
@@ -226,8 +236,8 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
226
236
  throw new Error("Unsupported signup method");
227
237
  }
228
238
  if (result.success) {
229
- const userPub = result.userPub || ((_b = (_a = sdk.gun.user()) === null || _a === void 0 ? void 0 : _a.is) === null || _b === void 0 ? void 0 : _b.pub) || "";
230
- const displayName = result.alias || username || userPub.slice(0, 8) + '...';
239
+ const userPub = result.userPub || ((_b = (_a = core.gun.user()) === null || _a === void 0 ? void 0 : _a.is) === null || _b === void 0 ? void 0 : _b.pub) || "";
240
+ const displayName = result.alias || username || userPub.slice(0, 8) + "...";
231
241
  setIsLoggedIn(true);
232
242
  setUserPub(userPub);
233
243
  setUsername(displayName);
@@ -249,7 +259,7 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
249
259
  };
250
260
  // Logout
251
261
  const logout = () => {
252
- sdk.logout();
262
+ core.logout();
253
263
  setIsLoggedIn(false);
254
264
  setUserPub(null);
255
265
  setUsername(null);
@@ -259,7 +269,7 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
259
269
  };
260
270
  // Implementazione del metodo setProvider
261
271
  const setProvider = (provider) => {
262
- if (!sdk) {
272
+ if (!core) {
263
273
  return false;
264
274
  }
265
275
  try {
@@ -267,12 +277,12 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
267
277
  if (provider && provider.connection && provider.connection.url) {
268
278
  newProviderUrl = provider.connection.url;
269
279
  }
270
- else if (typeof provider === 'string') {
280
+ else if (typeof provider === "string") {
271
281
  newProviderUrl = provider;
272
282
  }
273
283
  if (newProviderUrl) {
274
- if (typeof sdk.setRpcUrl === 'function') {
275
- return sdk.setRpcUrl(newProviderUrl);
284
+ if (typeof core.setRpcUrl === "function") {
285
+ return core.setRpcUrl(newProviderUrl);
276
286
  }
277
287
  }
278
288
  return false;
@@ -283,14 +293,14 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
283
293
  }
284
294
  };
285
295
  const hasPlugin = (name) => {
286
- return sdk ? sdk.hasPlugin(name) : false;
296
+ return core ? core.hasPlugin(name) : false;
287
297
  };
288
298
  const getPlugin = (name) => {
289
- return sdk ? sdk.getPlugin(name) : undefined;
299
+ return core ? core.getPlugin(name) : undefined;
290
300
  };
291
301
  // Export Gun pair functionality
292
302
  const exportGunPair = async (password) => {
293
- if (!sdk) {
303
+ if (!core) {
294
304
  throw new Error("SDK not initialized");
295
305
  }
296
306
  if (!isLoggedIn) {
@@ -320,7 +330,7 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
320
330
  };
321
331
  // Import Gun pair functionality
322
332
  const importGunPair = async (pairData, password) => {
323
- if (!sdk) {
333
+ if (!core) {
324
334
  throw new Error("SDK not initialized");
325
335
  }
326
336
  try {
@@ -350,23 +360,111 @@ export function ShogunButtonProvider({ children, sdk, options, onLoginSuccess, o
350
360
  throw new Error(`Failed to import Gun pair: ${error.message}`);
351
361
  }
352
362
  };
363
+ // Inizializza il plugin
364
+ const gunPlugin = React.useMemo(() => {
365
+ if (!core)
366
+ return null;
367
+ return new GunAdvancedPlugin(core, {
368
+ enableDebug: options.enableGunDebug !== false,
369
+ enableConnectionMonitoring: options.enableConnectionMonitoring !== false,
370
+ defaultPageSize: options.defaultPageSize || 20,
371
+ connectionTimeout: options.connectionTimeout || 10000,
372
+ debounceInterval: options.debounceInterval || 100,
373
+ });
374
+ }, [core, options]);
375
+ // Effetto per pulizia del plugin
376
+ React.useEffect(() => {
377
+ return () => {
378
+ if (gunPlugin) {
379
+ gunPlugin.cleanup();
380
+ }
381
+ };
382
+ }, [gunPlugin]);
383
+ // Crea gli hook del plugin
384
+ const pluginHooks = React.useMemo(() => {
385
+ if (!gunPlugin)
386
+ return {};
387
+ return gunPlugin.createHooks();
388
+ }, [gunPlugin]);
389
+ // Create a properly typed context value
390
+ const contextValue = React.useMemo(() => ({
391
+ core,
392
+ options,
393
+ isLoggedIn,
394
+ userPub,
395
+ username,
396
+ login,
397
+ signUp,
398
+ logout,
399
+ observe,
400
+ hasPlugin,
401
+ getPlugin,
402
+ exportGunPair,
403
+ importGunPair,
404
+ setProvider,
405
+ gunPlugin,
406
+ // Ensure all required hooks are present with proper fallbacks
407
+ useGunState: pluginHooks.useGunState ||
408
+ (() => ({
409
+ data: null,
410
+ isLoading: false,
411
+ error: null,
412
+ update: async () => { },
413
+ set: async () => { },
414
+ remove: async () => { },
415
+ refresh: () => { },
416
+ })),
417
+ useGunCollection: pluginHooks.useGunCollection ||
418
+ (() => ({
419
+ items: [],
420
+ currentPage: 0,
421
+ totalPages: 0,
422
+ hasNextPage: false,
423
+ hasPrevPage: false,
424
+ nextPage: () => { },
425
+ prevPage: () => { },
426
+ goToPage: () => { },
427
+ isLoading: false,
428
+ error: null,
429
+ refresh: () => { },
430
+ addItem: async () => { },
431
+ updateItem: async () => { },
432
+ removeItem: async () => { },
433
+ })),
434
+ useGunConnection: pluginHooks.useGunConnection ||
435
+ (() => ({
436
+ isConnected: false,
437
+ lastSeen: null,
438
+ error: null,
439
+ })),
440
+ useGunDebug: pluginHooks.useGunDebug || (() => { }),
441
+ useGunRealtime: pluginHooks.useGunRealtime ||
442
+ (() => ({
443
+ data: null,
444
+ key: null,
445
+ })),
446
+ put: (gunPlugin === null || gunPlugin === void 0 ? void 0 : gunPlugin.put.bind(gunPlugin)) || (async () => { }),
447
+ get: (gunPlugin === null || gunPlugin === void 0 ? void 0 : gunPlugin.get.bind(gunPlugin)) || (() => null),
448
+ remove: (gunPlugin === null || gunPlugin === void 0 ? void 0 : gunPlugin.remove.bind(gunPlugin)) || (async () => { }),
449
+ }), [
450
+ core,
451
+ options,
452
+ isLoggedIn,
453
+ userPub,
454
+ username,
455
+ login,
456
+ signUp,
457
+ logout,
458
+ observe,
459
+ hasPlugin,
460
+ getPlugin,
461
+ exportGunPair,
462
+ importGunPair,
463
+ gunPlugin,
464
+ pluginHooks,
465
+ ]);
353
466
  // Provide the context value to children
354
- return (React.createElement(ShogunContext.Provider, { value: {
355
- sdk,
356
- options,
357
- isLoggedIn,
358
- userPub,
359
- username,
360
- login,
361
- signUp,
362
- logout,
363
- observe,
364
- setProvider,
365
- hasPlugin,
366
- getPlugin,
367
- exportGunPair,
368
- importGunPair,
369
- } }, children));
467
+ return (React.createElement(ShogunContext.Provider, { value: contextValue }, children));
370
468
  }
371
469
  // SVG Icons Components
372
470
  const WalletIcon = () => (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" },
@@ -414,7 +512,7 @@ const ExportIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org
414
512
  // Component for Shogun login button
415
513
  export const ShogunButton = (() => {
416
514
  const Button = () => {
417
- const { isLoggedIn, username, logout, login, signUp, sdk, options, exportGunPair, importGunPair } = useShogun();
515
+ const { isLoggedIn, username, logout, login, signUp, core, options, exportGunPair, importGunPair, } = useShogun();
418
516
  // Form states
419
517
  const [modalIsOpen, setModalIsOpen] = useState(false);
420
518
  const [formUsername, setFormUsername] = useState("");
@@ -439,14 +537,15 @@ export const ShogunButton = (() => {
439
537
  // Handle click outside to close dropdown
440
538
  useEffect(() => {
441
539
  const handleClickOutside = (event) => {
442
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
540
+ if (dropdownRef.current &&
541
+ !dropdownRef.current.contains(event.target)) {
443
542
  setDropdownOpen(false);
444
543
  }
445
544
  };
446
545
  if (dropdownOpen) {
447
- document.addEventListener('mousedown', handleClickOutside);
546
+ document.addEventListener("mousedown", handleClickOutside);
448
547
  return () => {
449
- document.removeEventListener('mousedown', handleClickOutside);
548
+ document.removeEventListener("mousedown", handleClickOutside);
450
549
  };
451
550
  }
452
551
  }, [dropdownOpen]);
@@ -510,8 +609,8 @@ export const ShogunButton = (() => {
510
609
  if (formMode === "signup") {
511
610
  const result = await signUp("password", formUsername, formPassword, formPasswordConfirm);
512
611
  if (result && result.success) {
513
- if (sdk === null || sdk === void 0 ? void 0 : sdk.gundb) {
514
- await sdk.gundb.setPasswordHint(formUsername, formPassword, formHint, [formSecurityQuestion], [formSecurityAnswer]);
612
+ if (core === null || core === void 0 ? void 0 : core.gundb) {
613
+ await core.gundb.setPasswordHint(formUsername, formPassword, formHint, [formSecurityQuestion], [formSecurityAnswer]);
515
614
  }
516
615
  setModalIsOpen(false);
517
616
  }
@@ -532,7 +631,7 @@ export const ShogunButton = (() => {
532
631
  };
533
632
  const handleWeb3Auth = () => handleAuth("web3");
534
633
  const handleWebAuthnAuth = () => {
535
- if (!(sdk === null || sdk === void 0 ? void 0 : sdk.hasPlugin("webauthn"))) {
634
+ if (!(core === null || core === void 0 ? void 0 : core.hasPlugin("webauthn"))) {
536
635
  setError("WebAuthn is not supported in your browser");
537
636
  return;
538
637
  }
@@ -544,10 +643,10 @@ export const ShogunButton = (() => {
544
643
  setError("");
545
644
  setLoading(true);
546
645
  try {
547
- if (!(sdk === null || sdk === void 0 ? void 0 : sdk.gundb)) {
646
+ if (!(core === null || core === void 0 ? void 0 : core.gundb)) {
548
647
  throw new Error("SDK not ready");
549
648
  }
550
- const result = await sdk.gundb.forgotPassword(formUsername, [
649
+ const result = await core.gundb.forgotPassword(formUsername, [
551
650
  formSecurityAnswer,
552
651
  ]);
553
652
  if (result.success && result.hint) {
@@ -644,27 +743,35 @@ export const ShogunButton = (() => {
644
743
  };
645
744
  // Add buttons for both login and signup for alternative auth methods
646
745
  const renderAuthOptions = () => (React.createElement("div", { className: "shogun-auth-options" },
647
- options.showMetamask !== false && (sdk === null || sdk === void 0 ? void 0 : sdk.hasPlugin("web3")) && (React.createElement("div", { className: "shogun-auth-option-group" },
746
+ options.showMetamask !== false && (core === null || core === void 0 ? void 0 : core.hasPlugin("web3")) && (React.createElement("div", { className: "shogun-auth-option-group" },
648
747
  React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: () => handleAuth("web3"), disabled: loading },
649
748
  React.createElement(WalletIcon, null),
650
- formMode === "login" ? "Login with MetaMask" : "Signup with MetaMask"))),
651
- options.showWebauthn !== false && (sdk === null || sdk === void 0 ? void 0 : sdk.hasPlugin("webauthn")) && (React.createElement("div", { className: "shogun-auth-option-group" },
749
+ formMode === "login"
750
+ ? "Login with MetaMask"
751
+ : "Signup with MetaMask"))),
752
+ options.showWebauthn !== false && (core === null || core === void 0 ? void 0 : core.hasPlugin("webauthn")) && (React.createElement("div", { className: "shogun-auth-option-group" },
652
753
  React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: handleWebAuthnAuth, disabled: loading },
653
754
  React.createElement(WebAuthnIcon, null),
654
- formMode === "login" ? "Login with WebAuthn" : "Signup with WebAuthn"))),
655
- options.showNostr !== false && (sdk === null || sdk === void 0 ? void 0 : sdk.hasPlugin("nostr")) && (React.createElement("div", { className: "shogun-auth-option-group" },
755
+ formMode === "login"
756
+ ? "Login with WebAuthn"
757
+ : "Signup with WebAuthn"))),
758
+ options.showNostr !== false && (core === null || core === void 0 ? void 0 : core.hasPlugin("nostr")) && (React.createElement("div", { className: "shogun-auth-option-group" },
656
759
  React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: () => handleAuth("nostr"), disabled: loading },
657
760
  React.createElement(NostrIcon, null),
658
761
  formMode === "login" ? "Login with Nostr" : "Signup with Nostr"))),
659
- options.showOauth !== false && (sdk === null || sdk === void 0 ? void 0 : sdk.hasPlugin("oauth")) && (React.createElement("div", { className: "shogun-auth-option-group" },
762
+ options.showOauth !== false && (core === null || core === void 0 ? void 0 : core.hasPlugin("oauth")) && (React.createElement("div", { className: "shogun-auth-option-group" },
660
763
  React.createElement("button", { type: "button", className: "shogun-auth-option-button shogun-google-button", onClick: () => handleAuth("oauth", "google"), disabled: loading },
661
764
  React.createElement(GoogleIcon, null),
662
- formMode === "login" ? "Login with Google" : "Signup with Google"))),
765
+ formMode === "login"
766
+ ? "Login with Google"
767
+ : "Signup with Google"))),
663
768
  React.createElement("div", { className: "shogun-divider" },
664
769
  React.createElement("span", null, "or")),
665
770
  React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: () => setAuthView("password"), disabled: loading },
666
771
  React.createElement(LockIcon, null),
667
- formMode === "login" ? "Login with Password" : "Signup with Password"),
772
+ formMode === "login"
773
+ ? "Login with Password"
774
+ : "Signup with Password"),
668
775
  formMode === "login" && (React.createElement("button", { type: "button", className: "shogun-auth-option-button", onClick: () => setAuthView("import"), disabled: loading },
669
776
  React.createElement(ImportIcon, null),
670
777
  "Import Gun Pair"))));
@@ -711,11 +818,25 @@ export const ShogunButton = (() => {
711
818
  : "Already have an account? Log in"),
712
819
  formMode === "login" && (React.createElement("button", { type: "button", className: "shogun-toggle-mode", onClick: () => setAuthView("recover"), disabled: loading }, "Forgot password?")))));
713
820
  const renderWebAuthnUsernameForm = () => (React.createElement("div", { className: "shogun-auth-form" },
714
- React.createElement("h3", null, formMode === "login" ? "Login with WebAuthn" : "Sign Up with WebAuthn"),
715
- React.createElement("div", { style: { backgroundColor: '#f0f9ff', padding: '12px', borderRadius: '8px', marginBottom: '16px', border: '1px solid #0ea5e9' } },
716
- React.createElement("p", { style: { fontSize: '14px', color: '#0c4a6e', margin: '0', fontWeight: '500' } }, "\uD83D\uDD11 WebAuthn Authentication"),
717
- React.createElement("p", { style: { fontSize: '13px', color: '#075985', margin: '4px 0 0 0' } },
718
- "Please enter your username to continue with WebAuthn ",
821
+ React.createElement("h3", null, formMode === "login"
822
+ ? "Login with WebAuthn"
823
+ : "Sign Up with WebAuthn"),
824
+ React.createElement("div", { style: {
825
+ backgroundColor: "#f0f9ff",
826
+ padding: "12px",
827
+ borderRadius: "8px",
828
+ marginBottom: "16px",
829
+ border: "1px solid #0ea5e9",
830
+ } },
831
+ React.createElement("p", { style: {
832
+ fontSize: "14px",
833
+ color: "#0c4a6e",
834
+ margin: "0",
835
+ fontWeight: "500",
836
+ } }, "\uD83D\uDD11 WebAuthn Authentication"),
837
+ React.createElement("p", { style: { fontSize: "13px", color: "#075985", margin: "4px 0 0 0" } },
838
+ "Please enter your username to continue with WebAuthn",
839
+ " ",
719
840
  formMode === "login" ? "login" : "registration",
720
841
  ".")),
721
842
  React.createElement("div", { className: "shogun-form-group" },
@@ -753,9 +874,20 @@ export const ShogunButton = (() => {
753
874
  } }, "Back to Login")));
754
875
  const renderExportForm = () => (React.createElement("div", { className: "shogun-auth-form" },
755
876
  React.createElement("h3", null, "Export Gun Pair"),
756
- React.createElement("div", { style: { backgroundColor: '#f0f9ff', padding: '12px', borderRadius: '8px', marginBottom: '16px', border: '1px solid #0ea5e9' } },
757
- React.createElement("p", { style: { fontSize: '14px', color: '#0c4a6e', margin: '0', fontWeight: '500' } }, "\uD83D\uDD12 Backup Your Account"),
758
- React.createElement("p", { style: { fontSize: '13px', color: '#075985', margin: '4px 0 0 0' } }, "Export your Gun pair to backup your account. You can use this to login from another device or restore access if needed.")),
877
+ React.createElement("div", { style: {
878
+ backgroundColor: "#f0f9ff",
879
+ padding: "12px",
880
+ borderRadius: "8px",
881
+ marginBottom: "16px",
882
+ border: "1px solid #0ea5e9",
883
+ } },
884
+ React.createElement("p", { style: {
885
+ fontSize: "14px",
886
+ color: "#0c4a6e",
887
+ margin: "0",
888
+ fontWeight: "500",
889
+ } }, "\uD83D\uDD12 Backup Your Account"),
890
+ React.createElement("p", { style: { fontSize: "13px", color: "#075985", margin: "4px 0 0 0" } }, "Export your Gun pair to backup your account. You can use this to login from another device or restore access if needed.")),
759
891
  React.createElement("div", { className: "shogun-form-group" },
760
892
  React.createElement("label", { htmlFor: "exportPassword" },
761
893
  React.createElement(LockIcon, null),
@@ -764,23 +896,23 @@ export const ShogunButton = (() => {
764
896
  exportedPair && (React.createElement("div", { className: "shogun-form-group" },
765
897
  React.createElement("label", null, "Your Gun Pair (copy this safely):"),
766
898
  showCopySuccess && (React.createElement("div", { style: {
767
- backgroundColor: '#dcfce7',
768
- color: '#166534',
769
- padding: '8px 12px',
770
- borderRadius: '4px',
771
- marginBottom: '8px',
772
- fontSize: '14px',
773
- border: '1px solid #22c55e'
899
+ backgroundColor: "#dcfce7",
900
+ color: "#166534",
901
+ padding: "8px 12px",
902
+ borderRadius: "4px",
903
+ marginBottom: "8px",
904
+ fontSize: "14px",
905
+ border: "1px solid #22c55e",
774
906
  } }, "\u2705 Copied to clipboard successfully!")),
775
907
  React.createElement("textarea", { value: exportedPair, readOnly: true, rows: 6, style: {
776
- fontFamily: 'monospace',
777
- fontSize: '12px',
778
- width: '100%',
779
- padding: '8px',
780
- border: '1px solid #ccc',
781
- borderRadius: '4px'
908
+ fontFamily: "monospace",
909
+ fontSize: "12px",
910
+ width: "100%",
911
+ padding: "8px",
912
+ border: "1px solid #ccc",
913
+ borderRadius: "4px",
782
914
  } }),
783
- !navigator.clipboard && (React.createElement("p", { style: { fontSize: '12px', color: '#666', marginTop: '8px' } }, "\u26A0\uFE0F Auto-copy not available. Please manually copy the text above.")))),
915
+ !navigator.clipboard && (React.createElement("p", { style: { fontSize: "12px", color: "#666", marginTop: "8px" } }, "\u26A0\uFE0F Auto-copy not available. Please manually copy the text above.")))),
784
916
  React.createElement("button", { type: "button", className: "shogun-submit-button", onClick: handleExportPair, disabled: loading }, loading ? "Exporting..." : "Export Pair"),
785
917
  React.createElement("div", { className: "shogun-form-footer" },
786
918
  React.createElement("button", { className: "shogun-toggle-mode", onClick: () => {
@@ -798,20 +930,31 @@ export const ShogunButton = (() => {
798
930
  }, disabled: loading }, "Back"))));
799
931
  const renderImportForm = () => (React.createElement("div", { className: "shogun-auth-form" },
800
932
  React.createElement("h3", null, "Import Gun Pair"),
801
- React.createElement("div", { style: { backgroundColor: '#fef3c7', padding: '12px', borderRadius: '8px', marginBottom: '16px', border: '1px solid #f59e0b' } },
802
- React.createElement("p", { style: { fontSize: '14px', color: '#92400e', margin: '0', fontWeight: '500' } }, "\uD83D\uDD11 Restore Your Account"),
803
- React.createElement("p", { style: { fontSize: '13px', color: '#a16207', margin: '4px 0 0 0' } }, "Import a Gun pair to login with your existing account from another device. Make sure you have your backup data ready.")),
933
+ React.createElement("div", { style: {
934
+ backgroundColor: "#fef3c7",
935
+ padding: "12px",
936
+ borderRadius: "8px",
937
+ marginBottom: "16px",
938
+ border: "1px solid #f59e0b",
939
+ } },
940
+ React.createElement("p", { style: {
941
+ fontSize: "14px",
942
+ color: "#92400e",
943
+ margin: "0",
944
+ fontWeight: "500",
945
+ } }, "\uD83D\uDD11 Restore Your Account"),
946
+ React.createElement("p", { style: { fontSize: "13px", color: "#a16207", margin: "4px 0 0 0" } }, "Import a Gun pair to login with your existing account from another device. Make sure you have your backup data ready.")),
804
947
  React.createElement("div", { className: "shogun-form-group" },
805
948
  React.createElement("label", { htmlFor: "importPairData" },
806
949
  React.createElement(ImportIcon, null),
807
950
  React.createElement("span", null, "Gun Pair Data")),
808
951
  React.createElement("textarea", { id: "importPairData", value: importPairData, onChange: (e) => setImportPairData(e.target.value), disabled: loading, placeholder: "Paste your Gun pair JSON here...", rows: 6, style: {
809
- fontFamily: 'monospace',
810
- fontSize: '12px',
811
- width: '100%',
812
- padding: '8px',
813
- border: '1px solid #ccc',
814
- borderRadius: '4px'
952
+ fontFamily: "monospace",
953
+ fontSize: "12px",
954
+ width: "100%",
955
+ padding: "8px",
956
+ border: "1px solid #ccc",
957
+ borderRadius: "4px",
815
958
  } })),
816
959
  React.createElement("div", { className: "shogun-form-group" },
817
960
  React.createElement("label", { htmlFor: "importPassword" },
@@ -819,16 +962,20 @@ export const ShogunButton = (() => {
819
962
  React.createElement("span", null, "Decryption Password (if encrypted)")),
820
963
  React.createElement("input", { type: "password", id: "importPassword", value: importPassword, onChange: (e) => setImportPassword(e.target.value), disabled: loading, placeholder: "Enter password if pair was encrypted" })),
821
964
  showImportSuccess && (React.createElement("div", { style: {
822
- backgroundColor: '#dcfce7',
823
- color: '#166534',
824
- padding: '12px',
825
- borderRadius: '8px',
826
- marginBottom: '16px',
827
- fontSize: '14px',
828
- border: '1px solid #22c55e',
829
- textAlign: 'center'
965
+ backgroundColor: "#dcfce7",
966
+ color: "#166534",
967
+ padding: "12px",
968
+ borderRadius: "8px",
969
+ marginBottom: "16px",
970
+ fontSize: "14px",
971
+ border: "1px solid #22c55e",
972
+ textAlign: "center",
830
973
  } }, "\u2705 Pair imported successfully! Logging you in...")),
831
- React.createElement("button", { type: "button", className: "shogun-submit-button", onClick: handleImportPair, disabled: loading || showImportSuccess }, loading ? "Importing..." : showImportSuccess ? "Success!" : "Import and Login"),
974
+ React.createElement("button", { type: "button", className: "shogun-submit-button", onClick: handleImportPair, disabled: loading || showImportSuccess }, loading
975
+ ? "Importing..."
976
+ : showImportSuccess
977
+ ? "Success!"
978
+ : "Import and Login"),
832
979
  React.createElement("div", { className: "shogun-form-footer" },
833
980
  React.createElement("button", { className: "shogun-toggle-mode", onClick: () => {
834
981
  setAuthView("options");
@@ -873,7 +1020,8 @@ export const ShogunButton = (() => {
873
1020
  authView === "showHint" && renderHint(),
874
1021
  authView === "export" && renderExportForm(),
875
1022
  authView === "import" && renderImportForm(),
876
- authView === "webauthn-username" && renderWebAuthnUsernameForm()))))));
1023
+ authView === "webauthn-username" &&
1024
+ renderWebAuthnUsernameForm()))))));
877
1025
  };
878
1026
  Button.displayName = "ShogunButton";
879
1027
  return Object.assign(Button, {