shogun-core 3.0.4 → 3.0.5

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.
Files changed (95) hide show
  1. package/dist/browser/shogun-core.js +92134 -0
  2. package/dist/browser/shogun-core.js.map +1 -0
  3. package/dist/config/simplified-config.js +230 -0
  4. package/dist/core.js +338 -0
  5. package/dist/gundb/crypto.js +268 -0
  6. package/dist/gundb/db.js +1833 -0
  7. package/dist/gundb/derive.js +229 -0
  8. package/dist/gundb/errors.js +66 -0
  9. package/dist/gundb/index.js +6 -0
  10. package/dist/gundb/restricted-put.js +81 -0
  11. package/dist/gundb/rxjs.js +445 -0
  12. package/dist/gundb/simple-api.js +438 -0
  13. package/dist/gundb/types.js +4 -0
  14. package/dist/index.js +16 -0
  15. package/dist/interfaces/common.js +1 -0
  16. package/dist/interfaces/events.js +36 -0
  17. package/dist/interfaces/plugin.js +1 -0
  18. package/dist/interfaces/shogun.js +34 -0
  19. package/dist/managers/AuthManager.js +225 -0
  20. package/dist/managers/CoreInitializer.js +240 -0
  21. package/dist/managers/EventManager.js +67 -0
  22. package/dist/managers/PluginManager.js +296 -0
  23. package/dist/migration-test.js +91 -0
  24. package/dist/plugins/base.js +47 -0
  25. package/dist/plugins/index.js +15 -0
  26. package/dist/plugins/nostr/index.js +4 -0
  27. package/dist/plugins/nostr/nostrConnector.js +413 -0
  28. package/dist/plugins/nostr/nostrConnectorPlugin.js +446 -0
  29. package/dist/plugins/nostr/nostrSigner.js +313 -0
  30. package/dist/plugins/nostr/types.js +1 -0
  31. package/dist/plugins/oauth/index.js +3 -0
  32. package/dist/plugins/oauth/oauthConnector.js +753 -0
  33. package/dist/plugins/oauth/oauthPlugin.js +396 -0
  34. package/dist/plugins/oauth/types.js +1 -0
  35. package/dist/plugins/web3/index.js +4 -0
  36. package/dist/plugins/web3/types.js +1 -0
  37. package/dist/plugins/web3/web3Connector.js +528 -0
  38. package/dist/plugins/web3/web3ConnectorPlugin.js +448 -0
  39. package/dist/plugins/web3/web3Signer.js +308 -0
  40. package/dist/plugins/webauthn/index.js +3 -0
  41. package/dist/plugins/webauthn/types.js +11 -0
  42. package/dist/plugins/webauthn/webauthn.js +478 -0
  43. package/dist/plugins/webauthn/webauthnPlugin.js +398 -0
  44. package/dist/plugins/webauthn/webauthnSigner.js +304 -0
  45. package/dist/storage/storage.js +147 -0
  46. package/dist/types/config/simplified-config.d.ts +114 -0
  47. package/dist/types/core.d.ts +305 -0
  48. package/dist/types/gundb/crypto.d.ts +95 -0
  49. package/dist/types/gundb/db.d.ts +404 -0
  50. package/dist/types/gundb/derive.d.ts +21 -0
  51. package/dist/types/gundb/errors.d.ts +42 -0
  52. package/dist/types/gundb/index.d.ts +3 -0
  53. package/dist/types/gundb/restricted-put.d.ts +15 -0
  54. package/dist/types/gundb/rxjs.d.ts +110 -0
  55. package/dist/types/gundb/simple-api.d.ts +90 -0
  56. package/dist/types/gundb/types.d.ts +264 -0
  57. package/dist/types/index.d.ts +14 -0
  58. package/dist/types/interfaces/common.d.ts +85 -0
  59. package/dist/types/interfaces/events.d.ts +131 -0
  60. package/dist/types/interfaces/plugin.d.ts +162 -0
  61. package/dist/types/interfaces/shogun.d.ts +215 -0
  62. package/dist/types/managers/AuthManager.d.ts +72 -0
  63. package/dist/types/managers/CoreInitializer.d.ts +40 -0
  64. package/dist/types/managers/EventManager.d.ts +49 -0
  65. package/dist/types/managers/PluginManager.d.ts +145 -0
  66. package/dist/types/migration-test.d.ts +16 -0
  67. package/dist/types/plugins/base.d.ts +35 -0
  68. package/dist/types/plugins/index.d.ts +14 -0
  69. package/dist/types/plugins/nostr/index.d.ts +4 -0
  70. package/dist/types/plugins/nostr/nostrConnector.d.ts +119 -0
  71. package/dist/types/plugins/nostr/nostrConnectorPlugin.d.ts +163 -0
  72. package/dist/types/plugins/nostr/nostrSigner.d.ts +105 -0
  73. package/dist/types/plugins/nostr/types.d.ts +122 -0
  74. package/dist/types/plugins/oauth/index.d.ts +3 -0
  75. package/dist/types/plugins/oauth/oauthConnector.d.ts +110 -0
  76. package/dist/types/plugins/oauth/oauthPlugin.d.ts +91 -0
  77. package/dist/types/plugins/oauth/types.d.ts +114 -0
  78. package/dist/types/plugins/web3/index.d.ts +4 -0
  79. package/dist/types/plugins/web3/types.d.ts +107 -0
  80. package/dist/types/plugins/web3/web3Connector.d.ts +129 -0
  81. package/dist/types/plugins/web3/web3ConnectorPlugin.d.ts +160 -0
  82. package/dist/types/plugins/web3/web3Signer.d.ts +114 -0
  83. package/dist/types/plugins/webauthn/index.d.ts +3 -0
  84. package/dist/types/plugins/webauthn/types.d.ts +162 -0
  85. package/dist/types/plugins/webauthn/webauthn.d.ts +129 -0
  86. package/dist/types/plugins/webauthn/webauthnPlugin.d.ts +158 -0
  87. package/dist/types/plugins/webauthn/webauthnSigner.d.ts +91 -0
  88. package/dist/types/storage/storage.d.ts +50 -0
  89. package/dist/types/utils/errorHandler.d.ts +119 -0
  90. package/dist/types/utils/eventEmitter.d.ts +39 -0
  91. package/dist/types/utils/validation.d.ts +27 -0
  92. package/dist/utils/errorHandler.js +241 -0
  93. package/dist/utils/eventEmitter.js +76 -0
  94. package/dist/utils/validation.js +72 -0
  95. package/package.json +1 -1
@@ -0,0 +1,528 @@
1
+ /**
2
+ * The MetaMaskAuth class provides functionality for connecting, signing up, and logging in using MetaMask.
3
+ */
4
+ import { ethers } from "ethers";
5
+ import { ErrorHandler, ErrorType } from "../../utils/errorHandler";
6
+ import { EventEmitter } from "../../utils/eventEmitter";
7
+ import derive from "../../gundb/derive";
8
+ /**
9
+ * Class for MetaMask connection
10
+ */
11
+ class Web3Connector extends EventEmitter {
12
+ MESSAGE_TO_SIGN = "I Love Shogun!";
13
+ DEFAULT_CONFIG = {
14
+ cacheDuration: 30 * 60 * 1000, // 30 minutes
15
+ maxRetries: 3,
16
+ retryDelay: 1000,
17
+ timeout: 60000,
18
+ };
19
+ config;
20
+ signatureCache = new Map();
21
+ provider = null;
22
+ customProvider = null;
23
+ customWallet = null;
24
+ constructor(config = {}) {
25
+ super();
26
+ this.config = { ...this.DEFAULT_CONFIG, ...config };
27
+ this.initProvider();
28
+ this.setupEventListeners();
29
+ }
30
+ /**
31
+ * Initialize the provider synchronously with fallback mechanisms
32
+ * to handle conflicts between multiple wallet providers
33
+ */
34
+ initProvider() {
35
+ if (typeof window !== "undefined") {
36
+ try {
37
+ // Check if ethereum is available from any provider
38
+ const ethereumProvider = this.getAvailableEthereumProvider();
39
+ if (ethereumProvider) {
40
+ this.provider = new ethers.BrowserProvider(ethereumProvider);
41
+ }
42
+ else {
43
+ console.warn("No compatible Ethereum provider found");
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.error("Failed to initialize BrowserProvider", error);
48
+ }
49
+ }
50
+ else {
51
+ console.warn("Window object not available (non-browser environment)");
52
+ }
53
+ }
54
+ /**
55
+ * Get available Ethereum provider from multiple possible sources
56
+ */
57
+ getAvailableEthereumProvider() {
58
+ if (typeof window === "undefined")
59
+ return undefined;
60
+ // Define provider sources with priority order
61
+ const providerSources = [
62
+ // Check if we have providers in the _ethereumProviders registry (from index.html)
63
+ {
64
+ source: () => window._ethereumProviders && window._ethereumProviders[0],
65
+ name: "Registry Primary",
66
+ },
67
+ { source: () => window.ethereum, name: "Standard ethereum" },
68
+ {
69
+ source: () => window.web3?.currentProvider,
70
+ name: "Legacy web3",
71
+ },
72
+ { source: () => window.metamask, name: "MetaMask specific" },
73
+ {
74
+ source: () => window.ethereum?.providers?.find((p) => p.isMetaMask),
75
+ name: "MetaMask from providers array",
76
+ },
77
+ {
78
+ source: () => window.ethereum?.providers?.[0],
79
+ name: "First provider in array",
80
+ },
81
+ // Try known provider names
82
+ {
83
+ source: () => window.enkrypt?.providers?.ethereum,
84
+ name: "Enkrypt",
85
+ },
86
+ {
87
+ source: () => window.coinbaseWalletExtension,
88
+ name: "Coinbase",
89
+ },
90
+ { source: () => window.trustWallet, name: "Trust Wallet" },
91
+ // Use special registry if available
92
+ {
93
+ source: () => Array.isArray(window._ethereumProviders)
94
+ ? window._ethereumProviders.find((p) => !p._isProxy)
95
+ : undefined,
96
+ name: "Registry non-proxy",
97
+ },
98
+ ];
99
+ // Try each provider source
100
+ for (const { source, name } of providerSources) {
101
+ try {
102
+ const provider = source();
103
+ if (provider && typeof provider.request === "function") {
104
+ return provider;
105
+ }
106
+ }
107
+ catch (error) {
108
+ // Continue to next provider source
109
+ console.warn(`Error checking provider ${name}:`, error);
110
+ continue;
111
+ }
112
+ }
113
+ // No provider found
114
+ console.warn("No compatible Ethereum provider found");
115
+ return undefined;
116
+ }
117
+ /**
118
+ * Initialize the BrowserProvider (async method for explicit calls)
119
+ */
120
+ async setupProvider() {
121
+ try {
122
+ if (typeof window !== "undefined") {
123
+ // Check if ethereum is available from any provider
124
+ const ethereumProvider = this.getAvailableEthereumProvider();
125
+ if (ethereumProvider) {
126
+ this.provider = new ethers.BrowserProvider(ethereumProvider);
127
+ }
128
+ else {
129
+ console.warn("No compatible Ethereum provider found");
130
+ }
131
+ }
132
+ else {
133
+ console.warn("Window object not available (non-browser environment)");
134
+ }
135
+ }
136
+ catch (error) {
137
+ console.error("Failed to initialize BrowserProvider", error);
138
+ }
139
+ }
140
+ /**
141
+ * Setup MetaMask event listeners using BrowserProvider
142
+ */
143
+ setupEventListeners() {
144
+ if (this.provider) {
145
+ // Listen for network changes through ethers provider
146
+ this.provider.on("network", (newNetwork, oldNetwork) => {
147
+ this.emit("chainChanged", newNetwork);
148
+ });
149
+ // Listen for account changes through the detected provider
150
+ try {
151
+ const ethereumProvider = this.getAvailableEthereumProvider();
152
+ if (ethereumProvider?.on) {
153
+ ethereumProvider.on("accountsChanged", (accounts) => {
154
+ this.emit("accountsChanged", accounts);
155
+ });
156
+ // Also listen for chainChanged events directly
157
+ ethereumProvider.on("chainChanged", (chainId) => {
158
+ this.emit("chainChanged", { chainId });
159
+ });
160
+ }
161
+ }
162
+ catch (error) {
163
+ console.warn("Failed to setup account change listeners", error);
164
+ }
165
+ }
166
+ }
167
+ /**
168
+ * Cleanup event listeners
169
+ */
170
+ cleanup() {
171
+ if (this.provider) {
172
+ this.provider.removeAllListeners();
173
+ }
174
+ this.removeAllListeners();
175
+ }
176
+ /**
177
+ * Get cached signature if valid
178
+ */
179
+ getCachedSignature(address) {
180
+ const cached = this.signatureCache.get(address);
181
+ if (!cached)
182
+ return null;
183
+ const now = Date.now();
184
+ if (now - cached.timestamp > this.config.cacheDuration) {
185
+ this.signatureCache.delete(address);
186
+ return null;
187
+ }
188
+ // Check for invalid/empty signature
189
+ if (!cached.signature ||
190
+ typeof cached.signature !== "string" ||
191
+ cached.signature.length < 16) {
192
+ console.warn(`Invalid cached signature for address ${address} (length: ${cached.signature ? cached.signature.length : 0}), deleting from cache.`);
193
+ this.signatureCache.delete(address);
194
+ return null;
195
+ }
196
+ return cached.signature;
197
+ }
198
+ /**
199
+ * Cache signature
200
+ */
201
+ cacheSignature(address, signature) {
202
+ this.signatureCache.set(address, {
203
+ signature,
204
+ timestamp: Date.now(),
205
+ address,
206
+ });
207
+ }
208
+ /**
209
+ * Validates that the address is valid
210
+ */
211
+ validateAddress(address) {
212
+ if (!address) {
213
+ throw new Error("Address not provided");
214
+ }
215
+ try {
216
+ const normalizedAddress = String(address).trim().toLowerCase();
217
+ if (!ethers.isAddress(normalizedAddress)) {
218
+ throw new Error("Invalid address format");
219
+ }
220
+ return ethers.getAddress(normalizedAddress);
221
+ }
222
+ catch (error) {
223
+ ErrorHandler.handle(ErrorType.VALIDATION, "INVALID_ADDRESS", "Invalid Ethereum address provided", error);
224
+ throw error;
225
+ }
226
+ }
227
+ /**
228
+ * Connects to MetaMask with retry logic using BrowserProvider
229
+ */
230
+ async connectMetaMask() {
231
+ try {
232
+ if (!this.provider) {
233
+ this.initProvider();
234
+ if (!this.provider) {
235
+ throw new Error("MetaMask is not available. Please install MetaMask extension.");
236
+ }
237
+ }
238
+ // First check if we can get the provider
239
+ const ethereumProvider = this.getAvailableEthereumProvider();
240
+ if (!ethereumProvider) {
241
+ throw new Error("No compatible Ethereum provider found");
242
+ }
243
+ // Richiedi esplicitamente l'accesso all'account MetaMask
244
+ let accounts = [];
245
+ // Try multiple methods of requesting accounts for compatibility
246
+ try {
247
+ // Try the provider we found first
248
+ accounts = await ethereumProvider.request({
249
+ method: "eth_requestAccounts",
250
+ });
251
+ }
252
+ catch (requestError) {
253
+ console.warn("First account request failed, trying window.ethereum:", requestError);
254
+ // Fallback to window.ethereum if available and different
255
+ if (window.ethereum && window.ethereum !== ethereumProvider) {
256
+ try {
257
+ accounts = await window.ethereum.request({
258
+ method: "eth_requestAccounts",
259
+ });
260
+ }
261
+ catch (fallbackError) {
262
+ console.error("All account request methods failed", fallbackError);
263
+ throw new Error("User denied account access");
264
+ }
265
+ }
266
+ else {
267
+ throw new Error("User denied account access");
268
+ }
269
+ }
270
+ if (!accounts || accounts.length === 0) {
271
+ }
272
+ for (let attempt = 1; attempt <= this.config.maxRetries; attempt++) {
273
+ try {
274
+ const signer = await this.provider.getSigner();
275
+ const address = await signer.getAddress();
276
+ if (!address) {
277
+ console.error("No address returned from signer");
278
+ throw new Error("No address returned from signer");
279
+ }
280
+ this.emit("connected", { address });
281
+ return {
282
+ success: true,
283
+ address,
284
+ };
285
+ }
286
+ catch (error) {
287
+ console.error(`Attempt ${attempt} failed:`, error);
288
+ if (attempt === this.config.maxRetries) {
289
+ throw error;
290
+ }
291
+ // Wait before retrying
292
+ await new Promise((resolve) => setTimeout(resolve, this.config.retryDelay));
293
+ }
294
+ }
295
+ throw new Error("Failed to get signer after all attempts");
296
+ }
297
+ catch (error) {
298
+ console.error("Failed to connect to MetaMask:", error);
299
+ ErrorHandler.handle(ErrorType.WEBAUTHN, "METAMASK_CONNECTION_ERROR", error.message ?? "Unknown error while connecting to MetaMask", error);
300
+ return { success: false, error: error.message };
301
+ }
302
+ }
303
+ /**
304
+ * Generates credentials for the given address
305
+ */
306
+ async generateCredentials(address) {
307
+ try {
308
+ const validAddress = this.validateAddress(address);
309
+ // Check if we have a cached signature
310
+ const cachedSignature = this.getCachedSignature(validAddress);
311
+ if (cachedSignature) {
312
+ return this.generateCredentialsFromSignature(validAddress, cachedSignature);
313
+ }
314
+ // Request signature with timeout
315
+ let signature;
316
+ try {
317
+ signature = await this.requestSignatureWithTimeout(validAddress, this.MESSAGE_TO_SIGN, this.config.timeout);
318
+ }
319
+ catch (signingError) {
320
+ // Gestione del fallimento di firma
321
+ console.warn(`Failed to get signature: ${signingError}. Using fallback method.`);
322
+ throw signingError;
323
+ }
324
+ // Cache the signature
325
+ this.cacheSignature(validAddress, signature);
326
+ return this.generateCredentialsFromSignature(validAddress, signature);
327
+ }
328
+ catch (error) {
329
+ ErrorHandler.handle(ErrorType.WEBAUTHN, "CREDENTIALS_GENERATION_ERROR", error.message ?? "Error generating MetaMask credentials", error);
330
+ throw error;
331
+ }
332
+ }
333
+ /**
334
+ * Generates credentials from a signature
335
+ */
336
+ async generateCredentialsFromSignature(address, signature) {
337
+ const hashedAddress = ethers.keccak256(ethers.toUtf8Bytes(address));
338
+ const salt = `${address}_${signature}`;
339
+ return await derive(hashedAddress, salt, {
340
+ includeP256: true,
341
+ });
342
+ }
343
+ /**
344
+ * Generates fallback credentials (for testing/development)
345
+ */
346
+ generateFallbackCredentials(address) {
347
+ console.warn("Using fallback credentials generation for address:", address);
348
+ // Generate a deterministic but insecure fallback
349
+ const fallbackSignature = ethers.keccak256(ethers.toUtf8Bytes(address + "fallback"));
350
+ return {
351
+ username: address.toLowerCase(),
352
+ password: fallbackSignature,
353
+ message: this.MESSAGE_TO_SIGN,
354
+ signature: fallbackSignature,
355
+ };
356
+ }
357
+ /**
358
+ * Checks if MetaMask is available
359
+ */
360
+ static isMetaMaskAvailable() {
361
+ if (typeof window === "undefined") {
362
+ return false;
363
+ }
364
+ // Check multiple possible sources
365
+ const sources = [
366
+ () => window.ethereum,
367
+ () => window.web3?.currentProvider,
368
+ () => window.metamask,
369
+ () => window._ethereumProviders?.[0],
370
+ ];
371
+ for (const source of sources) {
372
+ try {
373
+ const provider = source();
374
+ if (provider && typeof provider.request === "function") {
375
+ return true;
376
+ }
377
+ }
378
+ catch {
379
+ // Continue to next source
380
+ }
381
+ }
382
+ return false;
383
+ }
384
+ /**
385
+ * Requests signature with timeout
386
+ */
387
+ requestSignatureWithTimeout(address, message, timeout = 30000) {
388
+ return new Promise((resolve, reject) => {
389
+ const timeoutId = setTimeout(() => {
390
+ reject(new Error("Signature request timed out"));
391
+ }, timeout);
392
+ const cleanup = () => {
393
+ clearTimeout(timeoutId);
394
+ };
395
+ const errorHandler = (error) => {
396
+ cleanup();
397
+ reject(error);
398
+ };
399
+ const initializeAndSign = async () => {
400
+ try {
401
+ const signer = await this.provider.getSigner();
402
+ const signerAddress = await signer.getAddress();
403
+ // Verify the signer address matches the expected address
404
+ if (signerAddress.toLowerCase() !== address.toLowerCase()) {
405
+ throw new Error(`Signer address (${signerAddress}) does not match expected address (${address})`);
406
+ }
407
+ const signature = await signer.signMessage(message);
408
+ cleanup();
409
+ resolve(signature);
410
+ }
411
+ catch (error) {
412
+ console.error("Failed to request signature:", error);
413
+ errorHandler(error);
414
+ }
415
+ };
416
+ initializeAndSign();
417
+ });
418
+ }
419
+ /**
420
+ * Checks if the connector is available
421
+ */
422
+ isAvailable() {
423
+ return Web3Connector.isMetaMaskAvailable();
424
+ }
425
+ /**
426
+ * Sets a custom provider for testing/development
427
+ */
428
+ setCustomProvider(rpcUrl, privateKey) {
429
+ try {
430
+ this.customProvider = new ethers.JsonRpcProvider(rpcUrl);
431
+ this.customWallet = new ethers.Wallet(privateKey, this.customProvider);
432
+ }
433
+ catch (error) {
434
+ throw new Error(`Error configuring provider: ${error.message ?? "Unknown error"}`);
435
+ }
436
+ }
437
+ /**
438
+ * Get active signer instance using BrowserProvider
439
+ */
440
+ async getSigner() {
441
+ try {
442
+ if (this.customWallet) {
443
+ return this.customWallet;
444
+ }
445
+ if (!this.provider) {
446
+ this.initProvider();
447
+ }
448
+ if (!this.provider) {
449
+ throw new Error("Provider not initialized");
450
+ }
451
+ return await this.provider.getSigner();
452
+ }
453
+ catch (error) {
454
+ throw new Error(`Unable to get Ethereum signer: ${error.message || "Unknown error"}`);
455
+ }
456
+ }
457
+ /**
458
+ * Get active provider instance using BrowserProvider
459
+ */
460
+ async getProvider() {
461
+ if (this.customProvider) {
462
+ return this.customProvider;
463
+ }
464
+ if (!this.provider) {
465
+ this.initProvider();
466
+ }
467
+ return this.provider;
468
+ }
469
+ /**
470
+ * Generate deterministic password from signature
471
+ * @param signature - Cryptographic signature
472
+ * @returns 64-character hex string
473
+ * @throws {Error} For invalid signature
474
+ */
475
+ async generatePassword(signature) {
476
+ if (!signature) {
477
+ throw new Error("Invalid signature");
478
+ }
479
+ const hash = ethers.keccak256(ethers.toUtf8Bytes(signature));
480
+ return hash.slice(2, 66); // Remove 0x and use first 32 bytes
481
+ }
482
+ /**
483
+ * Verify message signature
484
+ * @param message - Original signed message
485
+ * @param signature - Cryptographic signature
486
+ * @returns Recovered Ethereum address
487
+ * @throws {Error} For invalid inputs
488
+ */
489
+ async verifySignature(message, signature) {
490
+ if (!message || !signature) {
491
+ throw new Error("Invalid message or signature");
492
+ }
493
+ try {
494
+ return ethers.verifyMessage(message, signature);
495
+ }
496
+ catch (error) {
497
+ throw new Error("Invalid message or signature");
498
+ }
499
+ }
500
+ /**
501
+ * Get browser-based Ethereum signer
502
+ * @returns Browser provider signer
503
+ * @throws {Error} If MetaMask not detected
504
+ */
505
+ async getEthereumSigner() {
506
+ if (!Web3Connector.isMetaMaskAvailable()) {
507
+ throw new Error("MetaMask not found. Please install MetaMask to continue.");
508
+ }
509
+ try {
510
+ const ethereum = window.ethereum;
511
+ await ethereum.request({
512
+ method: "eth_requestAccounts",
513
+ });
514
+ const provider = new ethers.BrowserProvider(ethereum);
515
+ return provider.getSigner();
516
+ }
517
+ catch (error) {
518
+ throw new Error(`Error accessing MetaMask: ${error.message ?? "Unknown error"}`);
519
+ }
520
+ }
521
+ }
522
+ if (typeof window !== "undefined") {
523
+ window.Web3Connector = Web3Connector;
524
+ }
525
+ else if (typeof global !== "undefined") {
526
+ global.Web3Connector = Web3Connector;
527
+ }
528
+ export { Web3Connector };