diff --git a/README.md b/README.md index 3636af6b4..34c78aed8 100644 --- a/README.md +++ b/README.md @@ -87,14 +87,13 @@ await web3auth.connect(); | `@web3auth/phantom-adapter` | [![npm version](https://img.shields.io/npm/v/@web3auth/phantom-adapter?label=%22%22)](https://www.npmjs.com/package/@web3auth/phantom-adapter/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/phantom-adapter?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/phantom-adapter@latest) | Adds phantom chrome extension login functionality | | `@web3auth/torus-evm-adapter` | [![npm version](https://img.shields.io/npm/v/@web3auth/torus-evm-adapter?label=%22%22)](https://www.npmjs.com/package/@web3auth/torus-evm-adapter/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/torus-evm-adapter?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/torus-evm-adapter@latest) | Adds Torus Wallet login functionality (https://app.tor.us) | | `@web3auth/torus-solana-adapter` | [![npm version](https://img.shields.io/npm/v/@web3auth/torus-solana-adapter?label=%22%22)](https://www.npmjs.com/package/@web3auth/torus-solana-adapter/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/torus-solana-adapter?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/torus-solana-adapter@latest) | Adds Solana Torus Wallet login functionality (https://solana.tor.us) | -| `@web3auth/wallet-connect-v1-adapter` | [![npm version](https://img.shields.io/npm/v/@web3auth/wallet-connect-v1-adapter?label=%22%22)](https://www.npmjs.com/package/@web3auth/wallet-connect-v1-adapter/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/wallet-connect-v1-adapter?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/wallet-connect-v1-adapter@latest) | Adds wallet connect v1 login functionality + all supported adapters (eg: Metamask mobile, rainbow etc.) | +| `@web3auth/wallet-connect-v2-adapter` | [![npm version](https://img.shields.io/npm/v/@web3auth/wallet-connect-v2-adapter?label=%22%22)](https://www.npmjs.com/package/@web3auth/wallet-connect-v2-adapter/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/wallet-connect-v2-adapter?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/wallet-connect-v2-adapter@latest) | Adds wallet connect v2 login functionality + all supported adapters (eg: Metamask mobile, rainbow etc.) | | 🐉 **Providers** | | `@web3auth/base-provider` | [![npm version](https://img.shields.io/npm/v/@web3auth/base-provider?label=%22%22)](https://www.npmjs.com/package/@web3auth/base-provider/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/base-provider?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/base-provider@latest) | Base implementation of JRPC provider | | `@web3auth/ethereum-provider` | [![npm version](https://img.shields.io/npm/v/@web3auth/ethereum-provider?label=%22%22)](https://www.npmjs.com/package/@web3auth/ethereum-provider/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/ethereum-provider?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/ethereum-provider@latest) | EIP-1193 compatible JRPC provider | | `@web3auth/solana-provider` | [![npm version](https://img.shields.io/npm/v/@web3auth/solana-provider?label=%22%22)](https://www.npmjs.com/package/@web3auth/solana-provider/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/solana-provider?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/solana-provider@latest) | Solana chain compatible JRPC provider | -| 🐉 **Plugins** | -| `@web3auth/base-plugin` | [![npm version](https://img.shields.io/npm/v/@web3auth/base-plugin?label=%22%22)](https://www.npmjs.com/package/@web3auth/base-plugin/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/base-plugin?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/base-plugin@latest) | Base implementation of plugin | -| `@web3auth/torus-wallet-connector-plugin` | [![npm version](https://img.shields.io/npm/v/@web3auth/torus-wallet-connector-plugin?label=%22%22)](https://www.npmjs.com/package/@web3auth/torus-wallet-connector-plugin/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/torus-wallet-connector-plugin?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/torus-wallet-connector-plugin@latest) | Allows to inject your web3auth scoped private key into torus wallet UI (https://app.tor.us) | +| 🐉 **Plugins** | | +| `@web3auth/wallet-services-plugin` | [![npm version](https://img.shields.io/npm/v/@web3auth/wallet-services-plugin?label=%22%22)](https://www.npmjs.com/package/@web3auth/wallet-services-plugin/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/wallet-services-plugin?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/wallet-services-plugin@latest) | Allows to inject your web3auth scoped private key into Wallet Services UI | | `@web3auth/solana-wallet-connector-plugin` | [![npm version](https://img.shields.io/npm/v/@web3auth/solana-wallet-connector-plugin?label=%22%22)](https://www.npmjs.com/package/@web3auth/solana-wallet-connector-plugin/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/solana-wallet-connector-plugin?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/solana-wallet-connector-plugin@latest) | Allows to inject your web3auth scoped private key into torus solana wallet UI (https://solana.tor.us) | | 🐉 **Low-Level** | | `@web3auth/base` | [![npm version](https://img.shields.io/npm/v/@web3auth/base?label=%22%22)](https://www.npmjs.com/package/@web3auth/base/v/latest) | [![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/base?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/base@latest) | Base reusable functionalities for creating a web3auth instance | diff --git a/package-lock.json b/package-lock.json index b9c7d873e..fa54fe607 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6283,10 +6283,6 @@ "resolved": "packages/adapters/base-evm-adapter", "link": true }, - "node_modules/@web3auth/base-plugin": { - "resolved": "packages/plugins/base-plugin", - "link": true - }, "node_modules/@web3auth/base-provider": { "resolved": "packages/providers/base-provider", "link": true @@ -28298,13 +28294,12 @@ "version": "8.3.0", "license": "ISC", "dependencies": { - "@web3auth/base": "^8.3.0", - "@web3auth/base-plugin": "^8.3.0" + "@web3auth/base": "^8.3.0" }, "devDependencies": { - "@web3auth/base-plugin": "^8.1.0", "@web3auth/modal": "^8.3.0", - "@web3auth/openlogin-adapter": "^8.3.0" + "@web3auth/openlogin-adapter": "^8.3.0", + "@web3auth/wallet-services-plugin": "8.3.0" }, "engines": { "node": ">=18.x", @@ -28312,10 +28307,15 @@ }, "peerDependencies": { "@babel/runtime": "^7.x", - "@web3auth/base-plugin": "^8.x", "@web3auth/modal": "^8.x", "@web3auth/openlogin-adapter": "^8.x", + "@web3auth/wallet-services-plugin": "^8.x", "react": "^18.x" + }, + "peerDependenciesMeta": { + "@web3auth/wallet-services-plugin": { + "optional": true + } } }, "packages/modal": { @@ -28364,7 +28364,6 @@ "@toruslabs/openlogin-jrpc": "^8.1.1", "@toruslabs/openlogin-utils": "^8.1.0", "@web3auth/base": "^8.3.0", - "@web3auth/base-plugin": "^8.3.0", "@web3auth/base-provider": "^8.3.0", "lodash.clonedeep": "^4.5.0", "lodash.merge": "^4.6.2" @@ -28394,10 +28393,14 @@ "packages/plugins/base-plugin": { "name": "@web3auth/base-plugin", "version": "8.3.0", + "extraneous": true, "license": "ISC", "dependencies": { "@web3auth/base": "^8.3.0" }, + "devDependencies": { + "@toruslabs/openlogin-jrpc": "^8.1.1" + }, "engines": { "node": ">=18.x", "npm": ">=9.x" @@ -28411,7 +28414,6 @@ "@toruslabs/openlogin-jrpc": "^8.1.1", "@toruslabs/solana-embed": "^2.1.0", "@web3auth/base": "^8.3.0", - "@web3auth/base-plugin": "^8.3.0", "@web3auth/no-modal": "^8.3.0", "loglevel": "^1.9.1" }, @@ -28434,7 +28436,6 @@ "@toruslabs/ethereum-controllers": "^5.5.6", "@toruslabs/openlogin-jrpc": "^8.1.1", "@web3auth/base": "^8.3.0", - "@web3auth/base-plugin": "^8.3.0", "@web3auth/no-modal": "^8.3.0", "@web3auth/ws-embed": "^1.2.0", "loglevel": "^1.9.1" diff --git a/packages/adapters/default-evm-adapter/src/index.ts b/packages/adapters/default-evm-adapter/src/index.ts index 85a024497..4a750e7bb 100644 --- a/packages/adapters/default-evm-adapter/src/index.ts +++ b/packages/adapters/default-evm-adapter/src/index.ts @@ -1,6 +1,6 @@ -import { CHAIN_NAMESPACES, CustomChainConfig, getChainConfig, IAdapter, Web3AuthNoModalOptions } from "@web3auth/base"; +import { CHAIN_NAMESPACES, CustomChainConfig, getChainConfig, IAdapter, IWeb3AuthCoreOptions } from "@web3auth/base"; -export const getDefaultExternalAdapters = async (params: { options: Web3AuthNoModalOptions }): Promise[]> => { +export const getDefaultExternalAdapters = async (params: { options: IWeb3AuthCoreOptions }): Promise[]> => { const { options } = params; const { clientId, chainConfig, sessionTime, web3AuthNetwork, useCoreKitKey } = options; if (!Object.values(CHAIN_NAMESPACES).includes(chainConfig.chainNamespace)) throw new Error(`Invalid chainNamespace: ${chainConfig.chainNamespace}`); diff --git a/packages/adapters/default-solana-adapter/src/index.ts b/packages/adapters/default-solana-adapter/src/index.ts index 673021c37..8e334fac9 100644 --- a/packages/adapters/default-solana-adapter/src/index.ts +++ b/packages/adapters/default-solana-adapter/src/index.ts @@ -1,6 +1,6 @@ -import { CHAIN_NAMESPACES, CustomChainConfig, getChainConfig, IAdapter, Web3AuthNoModalOptions } from "@web3auth/base"; +import { CHAIN_NAMESPACES, CustomChainConfig, getChainConfig, IAdapter, IWeb3AuthCoreOptions } from "@web3auth/base"; -export const getDefaultExternalAdapters = async (params: { options: Web3AuthNoModalOptions }): Promise[]> => { +export const getDefaultExternalAdapters = async (params: { options: IWeb3AuthCoreOptions }): Promise[]> => { const { options } = params; const { clientId, chainConfig, sessionTime, web3AuthNetwork, useCoreKitKey } = options; if (!Object.values(CHAIN_NAMESPACES).includes(chainConfig.chainNamespace)) throw new Error(`Invalid chainNamespace: ${chainConfig.chainNamespace}`); diff --git a/packages/base/src/core/IWeb3Auth.ts b/packages/base/src/core/IWeb3Auth.ts index 80e736d9d..b83da5d00 100644 --- a/packages/base/src/core/IWeb3Auth.ts +++ b/packages/base/src/core/IWeb3Auth.ts @@ -3,32 +3,10 @@ import { WhiteLabelData } from "@toruslabs/openlogin-utils"; import { ADAPTER_STATUS_TYPE, IAdapter, IBaseProvider, IProvider, OPENLOGIN_NETWORK_TYPE, UserAuthInfo, UserInfo } from "../adapter/IAdapter"; import { CustomChainConfig } from "../chain/IChainInterface"; +import { type IPlugin } from "../plugin"; import { WALLET_ADAPTER_TYPE } from "../wallet"; -export interface IWeb3Auth extends SafeEventEmitter { - connected: boolean; - connectedAdapterName: string | null; - status: ADAPTER_STATUS_TYPE; - cachedAdapter: string | null; - provider: IProvider | null; - walletAdapters: Record>; - init(): Promise; - getAdapter(adapterName: WALLET_ADAPTER_TYPE): IAdapter | null; - configureAdapter(adapter: IAdapter): IWeb3Auth; - /** - * Connect to a specific wallet adapter - * @param walletName - Key of the walletAdapter to use. - */ - connectTo(walletName: WALLET_ADAPTER_TYPE, loginParams?: T): Promise; - logout(options?: { cleanup: boolean }): Promise; - getUserInfo(): Promise>; - authenticateUser(): Promise; - addChain(chainConfig: CustomChainConfig): Promise; - switchChain(params: { chainId: string }): Promise; - enableMFA(params: T): Promise; -} - -export interface Web3AuthNoModalOptions { +export interface IWeb3AuthCoreOptions { /** * Client id for web3auth. * You can obtain your client id from the web3auth developer dashboard. @@ -84,3 +62,31 @@ export interface Web3AuthNoModalOptions { */ privateKeyProvider?: IBaseProvider; } + +export interface IWeb3Auth extends SafeEventEmitter { + readonly coreOptions: IWeb3AuthCoreOptions; + connected: boolean; + connectedAdapterName: string | null; + status: ADAPTER_STATUS_TYPE; + cachedAdapter: string | null; + provider: IProvider | null; + walletAdapters: Record>; + init(): Promise; + getAdapter(adapterName: WALLET_ADAPTER_TYPE): IAdapter | null; + configureAdapter(adapter: IAdapter): IWeb3Auth; + /** + * Connect to a specific wallet adapter + * @param walletName - Key of the walletAdapter to use. + */ + connectTo(walletName: WALLET_ADAPTER_TYPE, loginParams?: T): Promise; + logout(options?: { cleanup: boolean }): Promise; + getUserInfo(): Promise>; + authenticateUser(): Promise; + addChain(chainConfig: CustomChainConfig): Promise; + switchChain(params: { chainId: string }): Promise; + enableMFA(params: T): Promise; + addPlugin(plugin: IPlugin): void; + getPlugin(pluginName: string): IPlugin | null; +} + +export type Web3AuthNoModalOptions = IWeb3AuthCoreOptions; diff --git a/packages/base/src/index.ts b/packages/base/src/index.ts index fe501b0da..c99589b00 100644 --- a/packages/base/src/index.ts +++ b/packages/base/src/index.ts @@ -4,6 +4,7 @@ export * from "./chain/IChainInterface"; export * from "./core/IWeb3Auth"; export * from "./errors"; export { default as log } from "./loglevel"; +export * from "./plugin"; export * from "./provider/IProvider"; export * from "./utils"; export * from "./wallet"; diff --git a/packages/plugins/base-plugin/src/IPlugin.ts b/packages/base/src/plugin/IPlugin.ts similarity index 73% rename from packages/plugins/base-plugin/src/IPlugin.ts rename to packages/base/src/plugin/IPlugin.ts index 37e78aac0..1c51f609b 100644 --- a/packages/plugins/base-plugin/src/IPlugin.ts +++ b/packages/base/src/plugin/IPlugin.ts @@ -1,4 +1,9 @@ -import { CHAIN_NAMESPACES, IProvider, IWeb3Auth, UserInfo, WALLET_ADAPTER_TYPE } from "@web3auth/base"; +import { type SafeEventEmitter } from "@toruslabs/openlogin-jrpc"; + +import { IProvider, UserInfo } from "../adapter"; +import { CHAIN_NAMESPACES } from "../chain/IChainInterface"; +import { type IWeb3Auth } from "../core/IWeb3Auth"; +import { WALLET_ADAPTER_TYPE } from "../wallet"; export const PLUGIN_NAMESPACES = { ...CHAIN_NAMESPACES, @@ -32,7 +37,7 @@ export const WALLET_PLUGINS = { ...SOLANA_PLUGINS, } as const; -export interface IPlugin { +export interface IPlugin extends SafeEventEmitter { name: string; SUPPORTED_ADAPTERS: WALLET_ADAPTER_TYPE[]; pluginNamespace: PluginNamespace; diff --git a/packages/base/src/plugin/errors.ts b/packages/base/src/plugin/errors.ts new file mode 100644 index 000000000..4c1bdd596 --- /dev/null +++ b/packages/base/src/plugin/errors.ts @@ -0,0 +1,62 @@ +import { ErrorCodes, IWeb3AuthError, Web3AuthError } from "../errors"; + +export class WalletServicesPluginError extends Web3AuthError { + protected static messages: ErrorCodes = { + 5210: "Wallet Services Plugin is not initialized", + 5211: "Web3Auth is connected to unsupported adapter. Wallet services connector plugin requires web3auth connected to openlogin adapter.", + 5212: "Provider is required..", + 5213: "Web3Auth instance is required while initialization.", + 5214: "Web3Auth is not connected.", + 5216: "Plugin is already initialized", + 5218: "Unsupported chain namespace.", + 5219: "Plugin network different than web3auth instance network.", + }; + + public constructor(code: number, message?: string) { + // takes care of stack and proto + super(code, message); + + // Set name explicitly as minification can mangle class names + Object.defineProperty(this, "name", { value: "WalletServicesPluginError" }); + } + + public static fromCode(code: number, extraMessage = ""): IWeb3AuthError { + return new WalletServicesPluginError(code, `${WalletServicesPluginError.messages[code]}${extraMessage}`); + } + + public static notInitialized(extraMessage = ""): IWeb3AuthError { + return WalletServicesPluginError.fromCode(5210, extraMessage); + } + + public static unsupportedAdapter(extraMessage = ""): IWeb3AuthError { + return WalletServicesPluginError.fromCode(5211, extraMessage); + } + + public static providerRequired(extraMessage = ""): IWeb3AuthError { + return WalletServicesPluginError.fromCode(5212, extraMessage); + } + + public static web3authRequired(extraMessage = ""): IWeb3AuthError { + return WalletServicesPluginError.fromCode(5213, extraMessage); + } + + public static web3AuthNotConnected(extraMessage = ""): IWeb3AuthError { + return WalletServicesPluginError.fromCode(5214, extraMessage); + } + + public static alreadyInitialized(extraMessage = ""): IWeb3AuthError { + return WalletServicesPluginError.fromCode(5216, extraMessage); + } + + public static unsupportedChainNamespace(extraMessage = ""): IWeb3AuthError { + return WalletServicesPluginError.fromCode(5218, extraMessage); + } + + public static differentWeb3authNetwork(extraMessage = ""): IWeb3AuthError { + return WalletServicesPluginError.fromCode(5219, extraMessage); + } + + public static invalidParams(extraMessage = ""): IWeb3AuthError { + return WalletServicesPluginError.fromCode(5220, extraMessage); + } +} diff --git a/packages/plugins/base-plugin/src/index.ts b/packages/base/src/plugin/index.ts similarity index 50% rename from packages/plugins/base-plugin/src/index.ts rename to packages/base/src/plugin/index.ts index b91a6f79c..6624965ff 100644 --- a/packages/plugins/base-plugin/src/index.ts +++ b/packages/base/src/plugin/index.ts @@ -1 +1,2 @@ +export * from "./errors"; export * from "./IPlugin"; diff --git a/packages/hooks/modal-react-hooks/package.json b/packages/hooks/modal-react-hooks/package.json index 0b1be5250..93dd5296e 100644 --- a/packages/hooks/modal-react-hooks/package.json +++ b/packages/hooks/modal-react-hooks/package.json @@ -31,21 +31,25 @@ "dist" ], "devDependencies": { - "@web3auth/base-plugin": "^8.1.0", "@web3auth/modal": "^8.3.0", - "@web3auth/openlogin-adapter": "^8.3.0" + "@web3auth/openlogin-adapter": "^8.3.0", + "@web3auth/wallet-services-plugin": "8.3.0" }, "dependencies": { - "@web3auth/base": "^8.3.0", - "@web3auth/base-plugin": "^8.3.0" + "@web3auth/base": "^8.3.0" }, "peerDependencies": { "@babel/runtime": "^7.x", - "@web3auth/base-plugin": "^8.x", "@web3auth/modal": "^8.x", "@web3auth/openlogin-adapter": "^8.x", + "@web3auth/wallet-services-plugin": "^8.x", "react": "^18.x" }, + "peerDependenciesMeta": { + "@web3auth/wallet-services-plugin": { + "optional": true + } + }, "lint-staged": { "!(*d).ts": [ "eslint --cache --fix", diff --git a/packages/hooks/modal-react-hooks/src/Web3AuthProvider.ts b/packages/hooks/modal-react-hooks/src/Web3AuthProvider.ts index d5483d071..c9cbe0ec3 100644 --- a/packages/hooks/modal-react-hooks/src/Web3AuthProvider.ts +++ b/packages/hooks/modal-react-hooks/src/Web3AuthProvider.ts @@ -1,5 +1,4 @@ -import type { IAdapter } from "@web3auth/base"; -import type { IPlugin } from "@web3auth/base-plugin"; +import type { IAdapter, IPlugin } from "@web3auth/base"; import { Web3Auth, Web3AuthOptions } from "@web3auth/modal"; import { createContext, createElement, PropsWithChildren, useEffect, useState } from "react"; diff --git a/packages/hooks/modal-react-hooks/src/index.ts b/packages/hooks/modal-react-hooks/src/index.ts index 4bcd3bb30..66a5334cc 100644 --- a/packages/hooks/modal-react-hooks/src/index.ts +++ b/packages/hooks/modal-react-hooks/src/index.ts @@ -1,2 +1,3 @@ +export { useWalletServicesPlugin } from "./useWalletServicesPlugin"; export { useWeb3Auth } from "./useWeb3auth"; export { Web3AuthProvider } from "./Web3AuthProvider"; diff --git a/packages/hooks/modal-react-hooks/src/useWalletServicesPlugin.ts b/packages/hooks/modal-react-hooks/src/useWalletServicesPlugin.ts new file mode 100644 index 000000000..2edf6d90c --- /dev/null +++ b/packages/hooks/modal-react-hooks/src/useWalletServicesPlugin.ts @@ -0,0 +1,61 @@ +import { PLUGIN_EVENTS, WalletServicesPluginError } from "@web3auth/base"; +import { type WalletServicesPlugin } from "@web3auth/wallet-services-plugin"; +import { useContext, useEffect, useState } from "react"; + +import { Web3AuthContext } from "./Web3AuthProvider"; + +const WALLET_SERVICES_PLUGIN_NAME = "WALLET_SERVICES_PLUGIN"; + +export const useWalletServicesPlugin = () => { + const web3auth = useContext(Web3AuthContext); + + const [walletServicesPlugin, setWalletServicesPlugin] = useState(null); + const [isConnected, setIsConnected] = useState(false); + + useEffect(() => { + if (web3auth) { + const plugin = web3auth.getPlugin(WALLET_SERVICES_PLUGIN_NAME) as WalletServicesPlugin | null; + if (plugin) setWalletServicesPlugin(plugin); + } + }, [web3auth]); + + useEffect(() => { + if (walletServicesPlugin) { + walletServicesPlugin.on(PLUGIN_EVENTS.CONNECTED, () => { + setIsConnected(true); + }); + walletServicesPlugin.on(PLUGIN_EVENTS.DISCONNECTED, () => { + setIsConnected(false); + }); + } + }, [walletServicesPlugin]); + + const showWalletConnectScanner = async () => { + if (!walletServicesPlugin) throw WalletServicesPluginError.notInitialized(); + if (!isConnected) throw WalletServicesPluginError.web3AuthNotConnected(); + + return walletServicesPlugin.showWalletConnectScanner(); + }; + + const showWalletUI = async () => { + if (!walletServicesPlugin) throw WalletServicesPluginError.notInitialized(); + if (!isConnected) throw WalletServicesPluginError.web3AuthNotConnected(); + + return walletServicesPlugin.showWalletUi(); + }; + + const showCheckout = async () => { + if (!walletServicesPlugin) throw WalletServicesPluginError.notInitialized(); + if (!isConnected) throw WalletServicesPluginError.web3AuthNotConnected(); + + return walletServicesPlugin.showCheckout(); + }; + + return { + plugin: walletServicesPlugin, + isConnected, + showWalletConnectScanner, + showCheckout, + showWalletUI, + }; +}; diff --git a/packages/hooks/modal-react-hooks/src/useWeb3auth.ts b/packages/hooks/modal-react-hooks/src/useWeb3auth.ts index dbcc55b50..77cd84054 100644 --- a/packages/hooks/modal-react-hooks/src/useWeb3auth.ts +++ b/packages/hooks/modal-react-hooks/src/useWeb3auth.ts @@ -1,12 +1,10 @@ -import { ADAPTER_EVENTS, CustomChainConfig, type IProvider, WALLET_ADAPTERS } from "@web3auth/base"; +import { ADAPTER_EVENTS, CustomChainConfig, type IPlugin, type IProvider, WalletInitializationError, WalletLoginError } from "@web3auth/base"; import { type ModalConfig } from "@web3auth/modal"; -import { type LoginParams, type OpenloginAdapter, type OpenloginUserInfo } from "@web3auth/openlogin-adapter"; -import { useContext, useEffect, useState } from "react"; +import { type LoginParams, type OpenloginUserInfo } from "@web3auth/openlogin-adapter"; +import { useCallback, useContext, useEffect, useState } from "react"; import { Web3AuthContext } from "./Web3AuthProvider"; -const WAIT_FOR_INIT_MSG = "Wait for web3auth to be ready first"; - export const useWeb3Auth = () => { const web3auth = useContext(Web3AuthContext); @@ -14,6 +12,7 @@ export const useWeb3Auth = () => { const [provider, setProvider] = useState(null); const [userInfo, setUserInfo] = useState | null>(null); const [isMFAEnabled, setIsMFAEnabled] = useState(false); + const [status, setStatus] = useState(null); useEffect(() => { const addState = async () => { @@ -35,11 +34,19 @@ export const useWeb3Auth = () => { } }, [web3auth, isConnected]); - const initModal = async (params: { modalConfig?: Record } = {}) => { - if (!web3auth) throw new Error(WAIT_FOR_INIT_MSG); + useEffect(() => { + if (web3auth?.status) { + setStatus(web3auth.status); + } + }, [web3auth?.status]); - await web3auth.initModal(params); - }; + const initModal = useCallback( + async (params: { modalConfig?: Record } = {}) => { + if (!web3auth) throw WalletInitializationError.notReady(); + await web3auth.initModal(params); + }, + [web3auth] + ); useEffect(() => { if (web3auth) { @@ -48,37 +55,70 @@ export const useWeb3Auth = () => { } }, [web3auth]); - async function enableMFA(params: Partial = {}) { - if (!web3auth) throw new Error(WAIT_FOR_INIT_MSG); - if (!isConnected) throw new Error("Connect to a wallet first"); - if (web3auth.connectedAdapterName !== WALLET_ADAPTERS.OPENLOGIN) throw new Error("Enable MFA is only supported for OpenLogin."); - - if (web3auth.connectedAdapterName === WALLET_ADAPTERS.OPENLOGIN) { - await (web3auth.walletAdapters[WALLET_ADAPTERS.OPENLOGIN] as OpenloginAdapter).openloginInstance?.enableMFA(params); - setIsMFAEnabled(userInfo?.isMfaEnabled || false); - } - } - - async function logout(params: { cleanup: boolean } = { cleanup: false }) { - if (!web3auth) throw new Error(WAIT_FOR_INIT_MSG); - if (!isConnected) throw new Error("Connect to a wallet first"); - - await web3auth.logout(params); - } - - async function connect(): Promise { - if (!web3auth) throw new Error(WAIT_FOR_INIT_MSG); - + const enableMFA = useCallback( + async (params: Partial) => { + if (!web3auth) throw WalletInitializationError.notReady(); + if (!isConnected) throw WalletLoginError.notConnectedError(); + await web3auth.enableMFA(params); + setIsMFAEnabled(true); + }, + [web3auth, isConnected] + ); + + const logout = useCallback( + async (params: { cleanup: boolean } = { cleanup: false }) => { + if (!web3auth) throw WalletInitializationError.notReady(); + if (!isConnected) throw WalletLoginError.notConnectedError(); + + await web3auth.logout(params); + }, + [web3auth, isConnected] + ); + + const connect = useCallback(async () => { + if (!web3auth) throw WalletInitializationError.notReady(); const localProvider = await web3auth.connect(); return localProvider; - } + }, [web3auth]); - async function addAndSwitchChain(chainConfig: CustomChainConfig) { - if (!web3auth) throw new Error(WAIT_FOR_INIT_MSG); - await web3auth.addChain(chainConfig); + const addAndSwitchChain = useCallback( + async (chainConfig: CustomChainConfig) => { + if (!web3auth) throw WalletInitializationError.notReady(); + await web3auth.addChain(chainConfig); + + await web3auth.switchChain({ chainId: chainConfig.chainId }); + }, + [web3auth] + ); + + const addPlugin = useCallback( + (plugin: IPlugin) => { + if (!web3auth) throw WalletInitializationError.notReady(); + return web3auth.addPlugin(plugin); + }, + [web3auth] + ); + + const authenticateUser = useCallback(async () => { + if (!web3auth) throw WalletInitializationError.notReady(); + return web3auth.authenticateUser(); + }, [web3auth]); - await web3auth.switchChain({ chainId: chainConfig.chainId }); - } + const addChain = useCallback( + async (chainConfig: CustomChainConfig) => { + if (!web3auth) throw WalletInitializationError.notReady(); + return web3auth.addChain(chainConfig); + }, + [web3auth] + ); + + const switchChain = useCallback( + (params: { chainId: string }) => { + if (!web3auth) throw WalletInitializationError.notReady(); + return web3auth.switchChain(params); + }, + [web3auth] + ); return { web3auth, @@ -86,14 +126,15 @@ export const useWeb3Auth = () => { provider, userInfo, isMFAEnabled, + status, initModal, connect, enableMFA, logout, addAndSwitchChain, - addChain: web3auth?.addChain.bind(web3auth), - addPlugin: web3auth?.addPlugin.bind(web3auth), - authenticateUser: web3auth?.authenticateUser.bind(web3auth), - switchChain: web3auth?.switchChain.bind(web3auth), + addChain, + addPlugin, + authenticateUser, + switchChain, }; }; diff --git a/packages/modal/src/modalManager.ts b/packages/modal/src/modalManager.ts index 05fdf7e81..8fd2401c4 100644 --- a/packages/modal/src/modalManager.ts +++ b/packages/modal/src/modalManager.ts @@ -8,13 +8,13 @@ import { getChainConfig, IBaseProvider, IProvider, + IWeb3AuthCoreOptions, log, LoginMethodConfig, PROJECT_CONFIG_RESPONSE, WALLET_ADAPTER_TYPE, WALLET_ADAPTERS, WalletInitializationError, - Web3AuthNoModalOptions, } from "@web3auth/base"; import { CommonJRPCProvider } from "@web3auth/base-provider"; import { Web3AuthNoModal } from "@web3auth/no-modal"; @@ -27,7 +27,7 @@ import merge from "lodash.merge"; import { defaultOtherModalConfig } from "./config"; import { AdaptersModalConfig, IWeb3AuthModal, ModalConfig } from "./interface"; -export interface Web3AuthOptions extends Web3AuthNoModalOptions { +export interface Web3AuthOptions extends IWeb3AuthCoreOptions { /** * Config for configuring modal ui display properties */ diff --git a/packages/no-modal/package.json b/packages/no-modal/package.json index 7b13b1ac1..d74483444 100644 --- a/packages/no-modal/package.json +++ b/packages/no-modal/package.json @@ -40,7 +40,6 @@ "@toruslabs/openlogin-jrpc": "^8.1.1", "@toruslabs/openlogin-utils": "^8.1.0", "@web3auth/base": "^8.3.0", - "@web3auth/base-plugin": "^8.3.0", "@web3auth/base-provider": "^8.3.0", "lodash.clonedeep": "^4.5.0", "lodash.merge": "^4.6.2" diff --git a/packages/no-modal/src/noModal.ts b/packages/no-modal/src/noModal.ts index 0bfe161fa..496205166 100644 --- a/packages/no-modal/src/noModal.ts +++ b/packages/no-modal/src/noModal.ts @@ -11,9 +11,12 @@ import { getChainConfig, IAdapter, IBaseProvider, + IPlugin, IProvider, IWeb3Auth, + IWeb3AuthCoreOptions, log, + PLUGIN_NAMESPACES, PROJECT_CONFIG_RESPONSE, storageAvailable, UserAuthInfo, @@ -23,9 +26,7 @@ import { WalletInitializationError, WalletLoginError, Web3AuthError, - Web3AuthNoModalOptions, } from "@web3auth/base"; -import { IPlugin, PLUGIN_NAMESPACES } from "@web3auth/base-plugin"; import { CommonJRPCProvider } from "@web3auth/base-provider"; import { LOGIN_PROVIDER, LoginConfig, OpenloginAdapter } from "@web3auth/openlogin-adapter"; import { WalletConnectV2Adapter } from "@web3auth/wallet-connect-v2-adapter"; @@ -34,7 +35,7 @@ import merge from "lodash.merge"; const ADAPTER_CACHE_KEY = "Web3Auth-cachedAdapter"; export class Web3AuthNoModal extends SafeEventEmitter implements IWeb3Auth { - readonly coreOptions: Web3AuthNoModalOptions; + readonly coreOptions: IWeb3AuthCoreOptions; public connectedAdapterName: WALLET_ADAPTER_TYPE | null = null; @@ -50,7 +51,7 @@ export class Web3AuthNoModal extends SafeEventEmitter implements IWeb3Auth { private storage: "sessionStorage" | "localStorage" = "localStorage"; - constructor(options: Web3AuthNoModalOptions) { + constructor(options: IWeb3AuthCoreOptions) { super(); if (!options.clientId) throw WalletInitializationError.invalidParams("Please provide a valid clientId in constructor"); if (options.enableLogging) log.enableAll(); @@ -281,6 +282,10 @@ export class Web3AuthNoModal extends SafeEventEmitter implements IWeb3Auth { return this; } + public getPlugin(name: string): IPlugin | null { + return this.plugins[name] || null; + } + protected subscribeToAdapterEvents(walletAdapter: IAdapter): void { walletAdapter.on(ADAPTER_EVENTS.CONNECTED, async (data: CONNECTED_EVENT_DATA) => { if (!this.commonJRPCProvider) throw WalletInitializationError.notFound(`CommonJrpcProvider not found`); diff --git a/packages/plugins/base-plugin/README.md b/packages/plugins/base-plugin/README.md deleted file mode 100644 index d6f42bf26..000000000 --- a/packages/plugins/base-plugin/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# Web3Auth Base Plugin - -[![npm version](https://img.shields.io/npm/v/@web3auth/base-plugin?label=%22%22)](https://www.npmjs.com/package/@web3auth/base-plugin/v/latest) -[![minzip](https://img.shields.io/bundlephobia/minzip/@web3auth/base-plugin?label=%22%22)](https://bundlephobia.com/result?p=@web3auth/base-plugin@latest) - -> Web3Auth is where passwordless auth meets non-custodial key infrastructure for Web3 apps and wallets. By aggregating OAuth (Google, Twitter, Discord) logins, different wallets and innovative Multi Party Computation (MPC) - Web3Auth provides a seamless login experience to every user on your application. - -Plugins are essentially extensions to the core functionality of Web3Auth, allowing you to add additional features to your dApp. This base plugin is the base implementation of a plugin, and is the foundation of all other plugins. - -## 📖 Documentation - -Read more about Web3Auth plugins in the [official Web3Auth Documentation](https://web3auth.io/docs/sdk/web/plugins/). - -## 💡 Features -- Plug and Play, OAuth based Web3 Authentication Service -- Fully decentralized, non-custodial key infrastructure -- End to end Whitelabelable solution -- Threshold Cryptography based Key Reconstruction -- Multi Factor Authentication Setup & Recovery (Includes password, backup phrase, device factor editing/deletion etc) -- Support for WebAuthn & Passwordless Login -- Support for connecting to multiple wallets -- DApp Active Session Management - -...and a lot more - -## 🔗 Installation - -```shell -npm install --save @web3auth/base-plugin -``` - -## 🩹 Example - -Checkout the examples for your preferred blockchain and platform in our [examples repository](https://github.com/Web3Auth/examples/) - -## 🌐 Demo - -Checkout the [Web3Auth Demo](https://demo-app.web3auth.io/) to see how Web3Auth can be used in your application. - -## 💬 Troubleshooting and Support - -- Have a look at our [Community Portal](https://community.web3auth.io/) to see if anyone has any questions or issues you might be having. Feel free to reate new topics and we'll help you out as soon as possible. -- Checkout our [Troubleshooting Documentation Page](https://web3auth.io/docs/troubleshooting) to know the common issues and solutions. -- For Priority Support, please have a look at our [Pricing Page](https://web3auth.io/pricing.html) for the plan that suits your needs. diff --git a/packages/plugins/base-plugin/package.json b/packages/plugins/base-plugin/package.json deleted file mode 100644 index 2492a2833..000000000 --- a/packages/plugins/base-plugin/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@web3auth/base-plugin", - "version": "8.3.0", - "description": "Base plugin for web3auth plugins", - "keywords": [ - "web3Auth/base-plugin", - "web3Auth", - "multichainWallet", - "blockchain", - "ethereum", - "metamask" - ], - "main": "dist/basePlugin.cjs.js", - "module": "dist/basePlugin.esm.js", - "unpkg": "dist/basePlugin.umd.min.js", - "jsdelivr": "dist/basePlugin.umd.min.js", - "types": "dist/types/index.d.ts", - "author": "Torus Labs", - "homepage": "https://github.com/Web3Auth/Web3Auth/tree/master/packages/basePlugin#readme", - "license": "ISC", - "scripts": { - "test": "mocha --config ../../../.mocharc.json test/**.ts", - "test-debugger": "mocha --config ../../../.mocharc.json --inspect-brk test/**.ts", - "dev": "torus-scripts start", - "build": "torus-scripts build", - "lint": "eslint --fix 'src/**/*.ts'", - "prepack": "npm run build", - "pre-commit": "lint-staged --cwd ." - }, - "files": [ - "dist" - ], - "dependencies": { - "@web3auth/base": "^8.3.0" - }, - "lint-staged": { - "!(*d).ts": [ - "eslint --cache --fix", - "prettier --write" - ] - }, - "publishConfig": { - "access": "public" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Web3Auth/Web3Auth.git" - }, - "bugs": { - "url": "https://github.com/Web3Auth/Web3Auth/issues" - }, - "engines": { - "node": ">=18.x", - "npm": ">=9.x" - } -} diff --git a/packages/plugins/base-plugin/torus.config.js b/packages/plugins/base-plugin/torus.config.js deleted file mode 100644 index 6df6a4932..000000000 --- a/packages/plugins/base-plugin/torus.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("../../../torus.config"); diff --git a/packages/plugins/base-plugin/tsconfig.json b/packages/plugins/base-plugin/tsconfig.json deleted file mode 100644 index 1d7a4c2a9..000000000 --- a/packages/plugins/base-plugin/tsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "include": ["src", "test"] -} diff --git a/packages/plugins/base-plugin/webpack.config.js b/packages/plugins/base-plugin/webpack.config.js deleted file mode 100644 index 8229e9abc..000000000 --- a/packages/plugins/base-plugin/webpack.config.js +++ /dev/null @@ -1,15 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -const path = require("path"); -const generateWebpackConfig = require("../../../webpack.config"); - -const pkg = require("./package.json"); - -const currentPath = path.resolve("."); - -const config = generateWebpackConfig({ - currentPath, - pkg, - alias: {}, -}); - -module.exports = config; diff --git a/packages/plugins/solana-wallet-connector-plugin/package.json b/packages/plugins/solana-wallet-connector-plugin/package.json index 806ded22d..7edb7ae7a 100644 --- a/packages/plugins/solana-wallet-connector-plugin/package.json +++ b/packages/plugins/solana-wallet-connector-plugin/package.json @@ -37,7 +37,6 @@ "@toruslabs/openlogin-jrpc": "^8.1.1", "@toruslabs/solana-embed": "^2.1.0", "@web3auth/base": "^8.3.0", - "@web3auth/base-plugin": "^8.3.0", "@web3auth/no-modal": "^8.3.0", "loglevel": "^1.9.1" }, diff --git a/packages/plugins/solana-wallet-connector-plugin/src/plugin.ts b/packages/plugins/solana-wallet-connector-plugin/src/plugin.ts index 5c33195fc..52474273a 100644 --- a/packages/plugins/solana-wallet-connector-plugin/src/plugin.ts +++ b/packages/plugins/solana-wallet-connector-plugin/src/plugin.ts @@ -1,9 +1,17 @@ import type { JsonRpcError } from "@metamask/rpc-errors"; import { SafeEventEmitter } from "@toruslabs/openlogin-jrpc"; import TorusEmbed, { NetworkInterface, PAYMENT_PROVIDER_TYPE, PaymentParams, TorusCtorArgs, TorusParams } from "@toruslabs/solana-embed"; -import { ADAPTER_EVENTS, CustomChainConfig, SafeEventEmitterProvider, UserInfo, WALLET_ADAPTERS } from "@web3auth/base"; -import { IPlugin, PLUGIN_EVENTS, PLUGIN_NAMESPACES } from "@web3auth/base-plugin"; -import type { Web3AuthNoModal } from "@web3auth/no-modal"; +import { + ADAPTER_EVENTS, + CustomChainConfig, + IPlugin, + IWeb3Auth, + PLUGIN_EVENTS, + PLUGIN_NAMESPACES, + SafeEventEmitterProvider, + UserInfo, + WALLET_ADAPTERS, +} from "@web3auth/base"; import log from "loglevel"; import { SolanaWalletPluginError } from "./errors"; @@ -24,7 +32,7 @@ export class SolanaWalletConnectorPlugin extends SafeEventEmitter implements IPl private provider: SafeEventEmitterProvider | null = null; - private web3auth: Web3AuthNoModal | null = null; + private web3auth: IWeb3Auth | null = null; private userInfo: UserInfo | null = null; @@ -49,7 +57,7 @@ export class SolanaWalletConnectorPlugin extends SafeEventEmitter implements IPl return this.torusWalletInstance.isLoggedIn ? (this.torusWalletInstance.provider as unknown as SafeEventEmitterProvider) : null; } - async initWithWeb3Auth(web3auth: Web3AuthNoModal): Promise { + async initWithWeb3Auth(web3auth: IWeb3Auth): Promise { if (this.isInitialized) return; if (!web3auth) throw SolanaWalletPluginError.web3authRequired(); if (web3auth.provider && web3auth.connectedAdapterName !== WALLET_ADAPTERS.OPENLOGIN) throw SolanaWalletPluginError.unsupportedAdapter(); @@ -176,7 +184,7 @@ export class SolanaWalletConnectorPlugin extends SafeEventEmitter implements IPl }); } - private subscribeToWeb3AuthNoModalEvents(web3Auth: Web3AuthNoModal) { + private subscribeToWeb3AuthNoModalEvents(web3Auth: IWeb3Auth) { web3Auth.on(ADAPTER_EVENTS.CONNECTED, async () => { if (web3Auth.connectedAdapterName !== WALLET_ADAPTERS.OPENLOGIN) { log.warn(`${web3Auth.connectedAdapterName} is not compatible with torus wallet connector plugin`); diff --git a/packages/plugins/wallet-services-plugin/package.json b/packages/plugins/wallet-services-plugin/package.json index 7db5d812c..0bfe991f1 100644 --- a/packages/plugins/wallet-services-plugin/package.json +++ b/packages/plugins/wallet-services-plugin/package.json @@ -37,7 +37,6 @@ "@toruslabs/ethereum-controllers": "^5.5.6", "@toruslabs/openlogin-jrpc": "^8.1.1", "@web3auth/base": "^8.3.0", - "@web3auth/base-plugin": "^8.3.0", "@web3auth/no-modal": "^8.3.0", "@web3auth/ws-embed": "^1.2.0", "loglevel": "^1.9.1" diff --git a/packages/plugins/wallet-services-plugin/src/plugin.ts b/packages/plugins/wallet-services-plugin/src/plugin.ts index 2b44356a7..188c08ef4 100644 --- a/packages/plugins/wallet-services-plugin/src/plugin.ts +++ b/packages/plugins/wallet-services-plugin/src/plugin.ts @@ -1,8 +1,16 @@ import type { EthereumProviderConfig } from "@toruslabs/ethereum-controllers"; import { SafeEventEmitter } from "@toruslabs/openlogin-jrpc"; -import { ADAPTER_EVENTS, ADAPTER_STATUS, CustomChainConfig, SafeEventEmitterProvider, WALLET_ADAPTERS } from "@web3auth/base"; -import { IPlugin, PLUGIN_EVENTS, PLUGIN_NAMESPACES } from "@web3auth/base-plugin"; -import type { Web3AuthNoModal } from "@web3auth/no-modal"; +import { + ADAPTER_EVENTS, + ADAPTER_STATUS, + CustomChainConfig, + IPlugin, + IWeb3Auth, + PLUGIN_EVENTS, + PLUGIN_NAMESPACES, + SafeEventEmitterProvider, + WALLET_ADAPTERS, +} from "@web3auth/base"; import type { OpenloginAdapter } from "@web3auth/openlogin-adapter"; import WsEmbed, { CtorArgs, WsEmbedParams } from "@web3auth/ws-embed"; import log from "loglevel"; @@ -20,7 +28,7 @@ export class WalletServicesPlugin extends SafeEventEmitter implements IPlugin { private provider: SafeEventEmitterProvider | null = null; - private web3auth: Web3AuthNoModal | null = null; + private web3auth: IWeb3Auth | null = null; private isInitialized = false; @@ -40,7 +48,7 @@ export class WalletServicesPlugin extends SafeEventEmitter implements IPlugin { return this.wsEmbedInstance.provider ? (this.wsEmbedInstance.provider as unknown as SafeEventEmitterProvider) : null; } - async initWithWeb3Auth(web3auth: Web3AuthNoModal): Promise { + async initWithWeb3Auth(web3auth: IWeb3Auth): Promise { if (this.isInitialized) return; if (!web3auth) throw WalletServicesPluginError.web3authRequired(); if (web3auth.provider && web3auth.connectedAdapterName !== WALLET_ADAPTERS.OPENLOGIN) throw WalletServicesPluginError.unsupportedAdapter(); @@ -170,11 +178,11 @@ export class WalletServicesPlugin extends SafeEventEmitter implements IPlugin { this.wsEmbedInstance.hideTorusButton(); }); provider.on("connect", () => { - if (this.walletInitOptions?.whiteLabel.showWidgetButton) this.wsEmbedInstance.showTorusButton(); + if (this.walletInitOptions?.whiteLabel?.showWidgetButton) this.wsEmbedInstance.showTorusButton(); }); } - private subscribeToWeb3AuthNoModalEvents(web3Auth: Web3AuthNoModal) { + private subscribeToWeb3AuthNoModalEvents(web3Auth: IWeb3Auth) { web3Auth.on(ADAPTER_EVENTS.CONNECTED, async () => { if (web3Auth.connectedAdapterName !== WALLET_ADAPTERS.OPENLOGIN) { log.warn(`${web3Auth.connectedAdapterName} is not compatible with wallet services connector plugin`);