@web3auth/no-modal 5.0.0-alpha.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.
@@ -0,0 +1 @@
1
+ export * from "./noModal";
@@ -0,0 +1,76 @@
1
+ import type { OPENLOGIN_NETWORK_TYPE } from "@toruslabs/openlogin";
2
+ import { SafeEventEmitter } from "@toruslabs/openlogin-jrpc";
3
+ import { ADAPTER_STATUS_TYPE, CustomChainConfig, IAdapter, IWeb3Auth, SafeEventEmitterProvider, UserAuthInfo, UserInfo, WALLET_ADAPTER_TYPE } from "@web3auth/base";
4
+ import { IPlugin } from "@web3auth/base-plugin";
5
+ export interface Web3AuthNoModalOptions {
6
+ /**
7
+ * Client id for web3auth.
8
+ * You can obtain your client id from the web3auth developer dashboard.
9
+ * You can set any random string for this on localhost.
10
+ */
11
+ clientId: string;
12
+ /**
13
+ * custom chain configuration for chainNamespace
14
+ *
15
+ * @defaultValue mainnet config of provided chainNamespace
16
+ */
17
+ chainConfig: Partial<CustomChainConfig> & Pick<CustomChainConfig, "chainNamespace">;
18
+ /**
19
+ * setting to true will enable logs
20
+ *
21
+ * @defaultValue false
22
+ */
23
+ enableLogging?: boolean;
24
+ /**
25
+ * setting to "local" will persist social login session accross browser tabs.
26
+ *
27
+ * @defaultValue "local"
28
+ */
29
+ storageKey?: "session" | "local";
30
+ /**
31
+ * sessionTime (in seconds) for idToken issued by Web3Auth for server side verification.
32
+ * @defaultValue 86400
33
+ *
34
+ * Note: max value can be 7 days (86400 * 7) and min can be 1 day (86400)
35
+ */
36
+ sessionTime?: number;
37
+ /**
38
+ * Web3Auth Network to use for the session & the issued idToken
39
+ * @defaultValue mainnet
40
+ */
41
+ web3AuthNetwork?: OPENLOGIN_NETWORK_TYPE;
42
+ useCoreKitKey?: boolean;
43
+ }
44
+ export declare class Web3AuthNoModal extends SafeEventEmitter implements IWeb3Auth {
45
+ readonly coreOptions: Web3AuthNoModalOptions;
46
+ connectedAdapterName: WALLET_ADAPTER_TYPE | null;
47
+ status: ADAPTER_STATUS_TYPE;
48
+ cachedAdapter: string | null;
49
+ protected walletAdapters: Record<string, IAdapter<unknown>>;
50
+ private plugins;
51
+ private storage;
52
+ constructor(options: Web3AuthNoModalOptions);
53
+ get provider(): SafeEventEmitterProvider | null;
54
+ set provider(_: SafeEventEmitterProvider | null);
55
+ init(): Promise<void>;
56
+ configureAdapter(adapter: IAdapter<unknown>): Web3AuthNoModal;
57
+ clearCache(): void;
58
+ addChain(chainConfig: CustomChainConfig): Promise<void>;
59
+ switchChain(params: {
60
+ chainId: string;
61
+ }): Promise<void>;
62
+ /**
63
+ * Connect to a specific wallet adapter
64
+ * @param walletName - Key of the walletAdapter to use.
65
+ */
66
+ connectTo<T>(walletName: WALLET_ADAPTER_TYPE, loginParams?: T): Promise<SafeEventEmitterProvider | null>;
67
+ logout(options?: {
68
+ cleanup: boolean;
69
+ }): Promise<void>;
70
+ getUserInfo(): Promise<Partial<UserInfo>>;
71
+ authenticateUser(): Promise<UserAuthInfo>;
72
+ addPlugin(plugin: IPlugin): Promise<IWeb3Auth>;
73
+ protected subscribeToAdapterEvents(walletAdapter: IAdapter<unknown>): void;
74
+ protected checkInitRequirements(): void;
75
+ private cacheWallet;
76
+ }
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@web3auth/no-modal",
3
+ "version": "5.0.0-alpha.0",
4
+ "description": "Multi chain wallet aggregator for web3Auth",
5
+ "keywords": [
6
+ "web3Auth/no-modal",
7
+ "web3Auth",
8
+ "multichainWallet",
9
+ "blockchain",
10
+ "ethereum",
11
+ "solana"
12
+ ],
13
+ "main": "dist/noModal.cjs.js",
14
+ "module": "dist/noModal.esm.js",
15
+ "unpkg": "dist/noModal.umd.min.js",
16
+ "jsdelivr": "dist/noModal.umd.min.js",
17
+ "types": "dist/types/index.d.ts",
18
+ "author": "Torus Labs",
19
+ "homepage": "https://github.com/Web3Auth/Web3Auth/tree/master/packages/no-modal#readme",
20
+ "license": "ISC",
21
+ "scripts": {
22
+ "test": "mocha --config ../../.mocharc.json test/**.ts",
23
+ "test-debugger": "mocha --config ../../.mocharc.json --inspect-brk test/**.ts",
24
+ "dev": "torus-scripts start",
25
+ "build": "torus-scripts build",
26
+ "lint": "eslint --fix 'src/**/*.ts'",
27
+ "prepack": "yarn run build",
28
+ "pre-commit": "lint-staged --cwd ."
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "src"
33
+ ],
34
+ "peerDependencies": {
35
+ "@babel/runtime": "^7.x"
36
+ },
37
+ "dependencies": {
38
+ "@toruslabs/openlogin": "^3.1.0",
39
+ "@toruslabs/openlogin-jrpc": "^3.0.0",
40
+ "@web3auth/base": "^5.0.0-alpha.0",
41
+ "@web3auth/base-plugin": "^5.0.0-alpha.0"
42
+ },
43
+ "lint-staged": {
44
+ "!(*d).ts": [
45
+ "eslint --cache --fix",
46
+ "prettier --write"
47
+ ]
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "git+https://github.com/Web3Auth/Web3Auth.git"
55
+ },
56
+ "bugs": {
57
+ "url": "https://github.com/Web3Auth/Web3Auth/issues"
58
+ },
59
+ "gitHead": "f8efd80b6c25a5c9af2057ed723ca9fb7f3f8e40"
60
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./noModal";
package/src/noModal.ts ADDED
@@ -0,0 +1,315 @@
1
+ import type { OPENLOGIN_NETWORK_TYPE } from "@toruslabs/openlogin";
2
+ import { SafeEventEmitter } from "@toruslabs/openlogin-jrpc";
3
+ import {
4
+ ADAPTER_EVENTS,
5
+ ADAPTER_NAMESPACES,
6
+ ADAPTER_STATUS,
7
+ ADAPTER_STATUS_TYPE,
8
+ CHAIN_NAMESPACES,
9
+ CONNECTED_EVENT_DATA,
10
+ CustomChainConfig,
11
+ getChainConfig,
12
+ IAdapter,
13
+ IWeb3Auth,
14
+ log,
15
+ SafeEventEmitterProvider,
16
+ storageAvailable,
17
+ UserAuthInfo,
18
+ UserInfo,
19
+ WALLET_ADAPTER_TYPE,
20
+ WalletInitializationError,
21
+ WalletLoginError,
22
+ Web3AuthError,
23
+ } from "@web3auth/base";
24
+ import { IPlugin, PLUGIN_NAMESPACES } from "@web3auth/base-plugin";
25
+
26
+ export interface Web3AuthNoModalOptions {
27
+ /**
28
+ * Client id for web3auth.
29
+ * You can obtain your client id from the web3auth developer dashboard.
30
+ * You can set any random string for this on localhost.
31
+ */
32
+ clientId: string;
33
+ /**
34
+ * custom chain configuration for chainNamespace
35
+ *
36
+ * @defaultValue mainnet config of provided chainNamespace
37
+ */
38
+ chainConfig: Partial<CustomChainConfig> & Pick<CustomChainConfig, "chainNamespace">;
39
+
40
+ /**
41
+ * setting to true will enable logs
42
+ *
43
+ * @defaultValue false
44
+ */
45
+ enableLogging?: boolean;
46
+ /**
47
+ * setting to "local" will persist social login session accross browser tabs.
48
+ *
49
+ * @defaultValue "local"
50
+ */
51
+ storageKey?: "session" | "local";
52
+
53
+ /**
54
+ * sessionTime (in seconds) for idToken issued by Web3Auth for server side verification.
55
+ * @defaultValue 86400
56
+ *
57
+ * Note: max value can be 7 days (86400 * 7) and min can be 1 day (86400)
58
+ */
59
+ sessionTime?: number;
60
+ /**
61
+ * Web3Auth Network to use for the session & the issued idToken
62
+ * @defaultValue mainnet
63
+ */
64
+ web3AuthNetwork?: OPENLOGIN_NETWORK_TYPE;
65
+
66
+ useCoreKitKey?: boolean;
67
+ }
68
+
69
+ const ADAPTER_CACHE_KEY = "Web3Auth-cachedAdapter";
70
+ export class Web3AuthNoModal extends SafeEventEmitter implements IWeb3Auth {
71
+ readonly coreOptions: Web3AuthNoModalOptions;
72
+
73
+ public connectedAdapterName: WALLET_ADAPTER_TYPE | null = null;
74
+
75
+ public status: ADAPTER_STATUS_TYPE = ADAPTER_STATUS.NOT_READY;
76
+
77
+ public cachedAdapter: string | null = null;
78
+
79
+ protected walletAdapters: Record<string, IAdapter<unknown>> = {};
80
+
81
+ private plugins: Record<string, IPlugin> = {};
82
+
83
+ private storage: "sessionStorage" | "localStorage" = "localStorage";
84
+
85
+ constructor(options: Web3AuthNoModalOptions) {
86
+ super();
87
+ if (!options.clientId) throw WalletInitializationError.invalidParams("Please provide a valid clientId in constructor");
88
+ if (options.enableLogging) log.enableAll();
89
+ else log.disableAll();
90
+ if (!options.chainConfig?.chainNamespace || !Object.values(CHAIN_NAMESPACES).includes(options.chainConfig?.chainNamespace))
91
+ throw WalletInitializationError.invalidParams("Please provide a valid chainNamespace in chainConfig");
92
+ if (options.storageKey === "session") this.storage = "sessionStorage";
93
+ this.cachedAdapter = storageAvailable(this.storage) ? window[this.storage].getItem(ADAPTER_CACHE_KEY) : null;
94
+
95
+ this.coreOptions = {
96
+ ...options,
97
+ chainConfig: {
98
+ ...(getChainConfig(options.chainConfig?.chainNamespace, options.chainConfig?.chainId) || {}),
99
+ ...options.chainConfig,
100
+ },
101
+ };
102
+ this.subscribeToAdapterEvents = this.subscribeToAdapterEvents.bind(this);
103
+ }
104
+
105
+ get provider(): SafeEventEmitterProvider | null {
106
+ if (this.status === ADAPTER_STATUS.CONNECTED && this.connectedAdapterName) {
107
+ const adapter = this.walletAdapters[this.connectedAdapterName];
108
+ return adapter.provider;
109
+ }
110
+ return null;
111
+ }
112
+
113
+ set provider(_: SafeEventEmitterProvider | null) {
114
+ throw new Error("Not implemented");
115
+ }
116
+
117
+ public async init(): Promise<void> {
118
+ const initPromises = Object.keys(this.walletAdapters).map((adapterName) => {
119
+ this.subscribeToAdapterEvents(this.walletAdapters[adapterName]);
120
+ // if adapter doesn't have any chain config yet thn set it based on provided namespace and chainId.
121
+ // if no chainNamespace or chainId is being provided, it will connect with mainnet.
122
+ if (!this.walletAdapters[adapterName].chainConfigProxy) {
123
+ const providedChainConfig = this.coreOptions.chainConfig;
124
+ if (!providedChainConfig.chainNamespace) throw WalletInitializationError.invalidParams("Please provide chainNamespace in chainConfig");
125
+ this.walletAdapters[adapterName].setAdapterSettings({
126
+ chainConfig: providedChainConfig,
127
+ sessionTime: this.coreOptions.sessionTime,
128
+ clientId: this.coreOptions.clientId,
129
+ web3AuthNetwork: this.coreOptions.web3AuthNetwork,
130
+ useCoreKitKey: this.coreOptions.useCoreKitKey,
131
+ });
132
+ } else {
133
+ this.walletAdapters[adapterName].setAdapterSettings({
134
+ sessionTime: this.coreOptions.sessionTime,
135
+ clientId: this.coreOptions.clientId,
136
+ web3AuthNetwork: this.coreOptions.web3AuthNetwork,
137
+ useCoreKitKey: this.coreOptions.useCoreKitKey,
138
+ });
139
+ }
140
+
141
+ return this.walletAdapters[adapterName].init({ autoConnect: this.cachedAdapter === adapterName }).catch((e) => log.error(e));
142
+ });
143
+ this.status = ADAPTER_STATUS.READY;
144
+ await Promise.all(initPromises);
145
+ }
146
+
147
+ public configureAdapter(adapter: IAdapter<unknown>): Web3AuthNoModal {
148
+ this.checkInitRequirements();
149
+ const providedChainConfig = this.coreOptions.chainConfig;
150
+
151
+ if (!providedChainConfig.chainNamespace) throw WalletInitializationError.invalidParams("Please provide chainNamespace in chainConfig");
152
+
153
+ const adapterAlreadyExists = this.walletAdapters[adapter.name];
154
+ if (adapterAlreadyExists) throw WalletInitializationError.duplicateAdapterError(`Wallet adapter for ${adapter.name} already exists`);
155
+ if (adapter.adapterNamespace !== ADAPTER_NAMESPACES.MULTICHAIN && adapter.adapterNamespace !== providedChainConfig.chainNamespace)
156
+ throw WalletInitializationError.incompatibleChainNameSpace(
157
+ `This wallet adapter belongs to ${adapter.adapterNamespace} which is incompatible with currently used namespace: ${providedChainConfig.chainNamespace}`
158
+ );
159
+
160
+ if (
161
+ adapter.adapterNamespace === ADAPTER_NAMESPACES.MULTICHAIN &&
162
+ adapter.currentChainNamespace &&
163
+ providedChainConfig.chainNamespace !== adapter.currentChainNamespace
164
+ ) {
165
+ // chainConfig checks are already validated in constructor so using typecast is safe here.
166
+ adapter.setAdapterSettings({ chainConfig: providedChainConfig as CustomChainConfig });
167
+ }
168
+
169
+ this.walletAdapters[adapter.name] = adapter;
170
+ return this;
171
+ }
172
+
173
+ public clearCache() {
174
+ if (!storageAvailable(this.storage)) return;
175
+ window[this.storage].removeItem(ADAPTER_CACHE_KEY);
176
+ this.cachedAdapter = null;
177
+ }
178
+
179
+ public async addChain(chainConfig: CustomChainConfig): Promise<void> {
180
+ if (this.status !== ADAPTER_STATUS.CONNECTED || !this.connectedAdapterName) throw WalletLoginError.notConnectedError(`No wallet is connected`);
181
+ return this.walletAdapters[this.connectedAdapterName].addChain(chainConfig);
182
+ }
183
+
184
+ public async switchChain(params: { chainId: string }): Promise<void> {
185
+ if (this.status !== ADAPTER_STATUS.CONNECTED || !this.connectedAdapterName) throw WalletLoginError.notConnectedError(`No wallet is connected`);
186
+ return this.walletAdapters[this.connectedAdapterName].switchChain(params);
187
+ }
188
+
189
+ /**
190
+ * Connect to a specific wallet adapter
191
+ * @param walletName - Key of the walletAdapter to use.
192
+ */
193
+ async connectTo<T>(walletName: WALLET_ADAPTER_TYPE, loginParams?: T): Promise<SafeEventEmitterProvider | null> {
194
+ if (!this.walletAdapters[walletName])
195
+ throw WalletInitializationError.notFound(`Please add wallet adapter for ${walletName} wallet, before connecting`);
196
+ const provider = await this.walletAdapters[walletName].connect(loginParams);
197
+ return provider;
198
+ }
199
+
200
+ async logout(options: { cleanup: boolean } = { cleanup: false }): Promise<void> {
201
+ if (this.status !== ADAPTER_STATUS.CONNECTED || !this.connectedAdapterName) throw WalletLoginError.notConnectedError(`No wallet is connected`);
202
+ await this.walletAdapters[this.connectedAdapterName].disconnect(options);
203
+ }
204
+
205
+ async getUserInfo(): Promise<Partial<UserInfo>> {
206
+ log.debug("Getting user info", this.status, this.connectedAdapterName);
207
+ if (this.status !== ADAPTER_STATUS.CONNECTED || !this.connectedAdapterName) throw WalletLoginError.notConnectedError(`No wallet is connected`);
208
+ return this.walletAdapters[this.connectedAdapterName].getUserInfo();
209
+ }
210
+
211
+ async authenticateUser(): Promise<UserAuthInfo> {
212
+ if (this.status !== ADAPTER_STATUS.CONNECTED || !this.connectedAdapterName) throw WalletLoginError.notConnectedError(`No wallet is connected`);
213
+ return this.walletAdapters[this.connectedAdapterName].authenticateUser();
214
+ }
215
+
216
+ public async addPlugin(plugin: IPlugin): Promise<IWeb3Auth> {
217
+ if (this.plugins[plugin.name]) throw new Error(`Plugin ${plugin.name} already exist`);
218
+ if (plugin.pluginNamespace !== PLUGIN_NAMESPACES.MULTICHAIN && plugin.pluginNamespace !== this.coreOptions.chainConfig.chainNamespace)
219
+ throw new Error(
220
+ `This plugin belongs to ${plugin.pluginNamespace} namespace which is incompatible with currently used namespace: ${this.coreOptions.chainConfig.chainNamespace}`
221
+ );
222
+
223
+ this.plugins[plugin.name] = plugin;
224
+ return this;
225
+ }
226
+
227
+ protected subscribeToAdapterEvents(walletAdapter: IAdapter<unknown>): void {
228
+ walletAdapter.on(ADAPTER_EVENTS.CONNECTED, async (data: CONNECTED_EVENT_DATA) => {
229
+ this.status = ADAPTER_STATUS.CONNECTED;
230
+ this.connectedAdapterName = data.adapter;
231
+ this.cacheWallet(data.adapter);
232
+ log.debug("connected", this.status, this.connectedAdapterName);
233
+
234
+ Object.values(this.plugins).map(async (plugin) => {
235
+ try {
236
+ if (!plugin.SUPPORTED_ADAPTERS.includes(data.adapter)) {
237
+ return;
238
+ }
239
+ await plugin.initWithWeb3Auth(this);
240
+ await plugin.connect();
241
+ } catch (error: unknown) {
242
+ // swallow error if connector adapter doesn't supports this plugin.
243
+ if ((error as Web3AuthError).code === 5211) {
244
+ return;
245
+ }
246
+ log.error(error);
247
+ }
248
+ });
249
+
250
+ this.emit(ADAPTER_EVENTS.CONNECTED, { ...data } as CONNECTED_EVENT_DATA);
251
+ });
252
+
253
+ walletAdapter.on(ADAPTER_EVENTS.DISCONNECTED, async (data) => {
254
+ // get back to ready state for rehydrating.
255
+ this.status = ADAPTER_STATUS.READY;
256
+ if (storageAvailable(this.storage)) {
257
+ const cachedAdapter = window[this.storage].getItem(ADAPTER_CACHE_KEY);
258
+ if (this.connectedAdapterName === cachedAdapter) {
259
+ this.clearCache();
260
+ }
261
+ }
262
+
263
+ log.debug("disconnected", this.status, this.connectedAdapterName);
264
+ await Promise.all(
265
+ Object.values(this.plugins).map((plugin) => {
266
+ return plugin.disconnect().catch((error: Web3AuthError) => {
267
+ // swallow error if adapter doesn't supports this plugin.
268
+ if (error.code === 5211) {
269
+ return;
270
+ }
271
+ // throw error;
272
+ log.error(error);
273
+ });
274
+ })
275
+ );
276
+ this.connectedAdapterName = null;
277
+ this.emit(ADAPTER_EVENTS.DISCONNECTED, data);
278
+ });
279
+ walletAdapter.on(ADAPTER_EVENTS.CONNECTING, (data) => {
280
+ this.status = ADAPTER_STATUS.CONNECTING;
281
+ this.emit(ADAPTER_EVENTS.CONNECTING, data);
282
+ log.debug("connecting", this.status, this.connectedAdapterName);
283
+ });
284
+ walletAdapter.on(ADAPTER_EVENTS.ERRORED, (data) => {
285
+ this.status = ADAPTER_STATUS.ERRORED;
286
+ this.clearCache();
287
+ this.emit(ADAPTER_EVENTS.ERRORED, data);
288
+ log.debug("errored", this.status, this.connectedAdapterName);
289
+ });
290
+
291
+ walletAdapter.on(ADAPTER_EVENTS.ADAPTER_DATA_UPDATED, (data) => {
292
+ log.debug("adapter data updated", data);
293
+ this.emit(ADAPTER_EVENTS.ADAPTER_DATA_UPDATED, data);
294
+ });
295
+
296
+ walletAdapter.on(ADAPTER_EVENTS.CACHE_CLEAR, (data) => {
297
+ log.debug("adapter cache clear", data);
298
+ if (storageAvailable(this.storage)) {
299
+ this.clearCache();
300
+ }
301
+ });
302
+ }
303
+
304
+ protected checkInitRequirements(): void {
305
+ if (this.status === ADAPTER_STATUS.CONNECTING) throw WalletInitializationError.notReady("Already pending connection");
306
+ if (this.status === ADAPTER_STATUS.CONNECTED) throw WalletInitializationError.notReady("Already connected");
307
+ if (this.status === ADAPTER_STATUS.READY) throw WalletInitializationError.notReady("Adapter is already initialized");
308
+ }
309
+
310
+ private cacheWallet(walletName: string) {
311
+ if (!storageAvailable(this.storage)) return;
312
+ window[this.storage].setItem(ADAPTER_CACHE_KEY, walletName);
313
+ this.cachedAdapter = walletName;
314
+ }
315
+ }