Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
238 changes: 153 additions & 85 deletions package-lock.json

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions packages/composables/no-modal-vue-composables/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
8 changes: 8 additions & 0 deletions packages/composables/no-modal-vue-composables/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Web3Auth Modal Vue Composables
Vue composables to simplify integration with Web3Auth no-modal SDK.

## 🔗 Installation

```shell
npm install --save @web3auth/no-modal-vue-composables
```
56 changes: 56 additions & 0 deletions packages/composables/no-modal-vue-composables/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "@web3auth/no-modal-vue-composables",
"version": "8.9.1",
"description": "Vue composables to simplify integration with web3Auth no-modal SDK.",
"keywords": [
"web3Auth/no-modal-vue-composables",
"web3Auth",
"blockchain",
"vue composables",
"web3Auth composables",
"web3Auth no-modal vue composables"
],
"main": "dist/noModalVueComposables.cjs.js",
"module": "dist/noModalVueComposables.esm.js",
"unpkg": "dist/noModalVueComposables.umd.min.js",
"jsdelivr": "dist/noModalVueComposables.umd.min.js",
"types": "dist/types/index.d.ts",
"author": "Torus Labs",
"homepage": "https://github.com/Web3Auth/Web3Auth/tree/master/packages/composables/no-modal-vue-composables#readme",
"license": "ISC",
"scripts": {
"dev": "torus-scripts start",
"build": "torus-scripts build",
"lint": "eslint --fix 'src/**/*.ts'",
"prepack": "npm run build"
},
"files": [
"dist"
],
"dependencies": {
"@web3auth/base": "^8.8.0",
"@web3auth/no-modal": "^8.9.1"
},
"devDependencies": {
"@toruslabs/openlogin-utils": "^8.2.1",
"@web3auth/openlogin-adapter": "^8.8.0"
},
"peerDependencies": {
"@babel/runtime": "^7.x",
"vue": "^3.4.x"
},
"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"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import {
ADAPTER_EVENTS,
type ADAPTER_STATUS_TYPE,
type CustomChainConfig,
type IPlugin,
type IProvider,
WALLET_ADAPTER_TYPE,
WalletInitializationError,
WalletLoginError,
} from "@web3auth/base";
import { Web3AuthNoModal } from "@web3auth/no-modal";
import type { LoginParams, OpenloginUserInfo } from "@web3auth/openlogin-adapter";
import { defineComponent, h, InjectionKey, PropType, provide, ref, shallowRef, triggerRef, watch } from "vue";

import { IWeb3AuthContext, Web3AuthContextConfig } from "./interfaces";

export const Web3AuthContextKey = Symbol("Web3AuthContextKey") as InjectionKey<IWeb3AuthContext>;

export default defineComponent({
name: "Web3AuthProvider",
props: {
config: { type: Object as PropType<Web3AuthContextConfig>, required: true },
},
setup(props) {
const web3Auth = shallowRef<Web3AuthNoModal | null>(null);
const isConnected = ref(false);
const provider = ref<IProvider | null>(null);
const userInfo = ref<Partial<OpenloginUserInfo> | null>(null);
const isMFAEnabled = ref(false);
const isInitialized = ref(false);
const status = ref<ADAPTER_STATUS_TYPE | null>(null);

const addPlugin = (plugin: IPlugin) => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
return web3Auth.value.addPlugin(plugin);
};

const getPlugin = (name: string) => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
return web3Auth.value.getPlugin(name);
};

const init = async () => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
await web3Auth.value.init();
triggerRef(web3Auth);
};

const enableMFA = async (loginParams?: Partial<LoginParams>) => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
if (!isConnected.value) throw WalletLoginError.notConnectedError();
await web3Auth.value.enableMFA(loginParams);
triggerRef(web3Auth);
const localUserInfo = await web3Auth.value.getUserInfo();
userInfo.value = localUserInfo;
isMFAEnabled.value = localUserInfo.isMfaEnabled || false;
};

const logout = async (logoutParams: { cleanup: boolean } = { cleanup: false }) => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
if (!isConnected.value) throw WalletLoginError.notConnectedError();
await web3Auth.value.logout(logoutParams);
triggerRef(web3Auth);
};

const connectTo = async <T>(walletName: WALLET_ADAPTER_TYPE, loginParams?: T) => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
const localProvider = await web3Auth.value.connectTo(walletName, loginParams);
triggerRef(web3Auth);
return localProvider;
};

const addAndSwitchChain = async (chainConfig: CustomChainConfig) => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
await web3Auth.value.addChain(chainConfig);
await web3Auth.value.switchChain({ chainId: chainConfig.chainId });
};

const authenticateUser = async () => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
return web3Auth.value.authenticateUser();
};

const addChain = async (chainConfig: CustomChainConfig) => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
return web3Auth.value.addChain(chainConfig);
};

const switchChain = (chainParams: { chainId: string }) => {
if (!web3Auth.value) throw WalletInitializationError.notReady();
return web3Auth.value.switchChain(chainParams);
};

watch(
[web3Auth, () => props.config],
() => {
if (web3Auth.value) return;

const resetHookState = () => {
provider.value = null;
userInfo.value = null;
isMFAEnabled.value = false;
isConnected.value = false;
status.value = null;
};

resetHookState();
const { web3AuthOptions, adapters = [], plugins = [] } = props.config;
const web3AuthInstance = new Web3AuthNoModal(web3AuthOptions);
if (adapters.length) adapters.map((adapter) => web3AuthInstance.configureAdapter(adapter));
if (plugins.length) {
plugins.forEach((plugin) => {
web3AuthInstance.addPlugin(plugin);
});
}

web3Auth.value = web3AuthInstance;
},
{ immediate: true }
);

watch([web3Auth, isConnected], () => {
if (web3Auth.value) {
const addState = async (web3AuthInstance: Web3AuthNoModal) => {
provider.value = web3AuthInstance.provider;
const userState = await web3AuthInstance.getUserInfo();
userInfo.value = userState;
isMFAEnabled.value = userState?.isMfaEnabled || false;
};

const resetState = () => {
provider.value = null;
userInfo.value = null;
isMFAEnabled.value = false;
};

if (isConnected.value) addState(web3Auth.value as Web3AuthNoModal);
else resetState();
}
});

watch(
web3Auth,
(newWeb3Auth, prevWeb3Auth) => {
const notReadyListener = () => (status.value = web3Auth.value!.status);
const readyListener = () => {
status.value = web3Auth.value!.status;
isInitialized.value = true;
};
const connectedListener = () => {
status.value = web3Auth.value!.status;
isInitialized.value = true;
isConnected.value = true;
};
const disconnectedListener = () => {
status.value = web3Auth.value!.status;
isConnected.value = false;
};
const connectingListener = () => {
status.value = web3Auth.value!.status;
};
const errorListener = () => {
status.value = ADAPTER_EVENTS.ERRORED;
};

// unregister previous listeners
if (prevWeb3Auth && newWeb3Auth !== prevWeb3Auth) {
prevWeb3Auth.off(ADAPTER_EVENTS.NOT_READY, notReadyListener);
prevWeb3Auth.off(ADAPTER_EVENTS.READY, readyListener);
prevWeb3Auth.off(ADAPTER_EVENTS.CONNECTED, connectedListener);
prevWeb3Auth.off(ADAPTER_EVENTS.DISCONNECTED, disconnectedListener);
prevWeb3Auth.off(ADAPTER_EVENTS.CONNECTING, connectingListener);
prevWeb3Auth.off(ADAPTER_EVENTS.ERRORED, errorListener);
}

if (newWeb3Auth && newWeb3Auth !== prevWeb3Auth) {
status.value = newWeb3Auth.status;
// web3Auth is initialized here.
newWeb3Auth.on(ADAPTER_EVENTS.NOT_READY, notReadyListener);
newWeb3Auth.on(ADAPTER_EVENTS.READY, readyListener);
newWeb3Auth.on(ADAPTER_EVENTS.CONNECTED, connectedListener);
newWeb3Auth.on(ADAPTER_EVENTS.DISCONNECTED, disconnectedListener);
newWeb3Auth.on(ADAPTER_EVENTS.CONNECTING, connectingListener);
newWeb3Auth.on(ADAPTER_EVENTS.ERRORED, errorListener);
}
},
{ immediate: true }
);

provide(Web3AuthContextKey, {
web3Auth,
isConnected,
isInitialized,
provider,
userInfo,
isMFAEnabled,
status,
getPlugin,
init,
connectTo,
enableMFA,
logout,
addAndSwitchChain,
addChain,
addPlugin,
authenticateUser,
switchChain,
});
},
render() {
return h(this.$slots.default ?? "");
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useWeb3Auth } from "./useWeb3Auth";
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { WalletInitializationError } from "@web3auth/base";
import { inject } from "vue";

import { Web3AuthContextKey } from "../Web3AuthProvider";

export const useWeb3Auth = () => {
const context = inject(Web3AuthContextKey);
if (!context) throw WalletInitializationError.fromCode(1000, "usage of `useWeb3Auth` not wrapped in `Web3AuthProvider`.");
return context;
};
3 changes: 3 additions & 0 deletions packages/composables/no-modal-vue-composables/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./composables";
export * from "./interfaces";
export { default } from "./Web3AuthProvider";
46 changes: 46 additions & 0 deletions packages/composables/no-modal-vue-composables/src/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { LoginParams, OpenloginUserInfo } from "@toruslabs/openlogin-utils";
import type {
ADAPTER_STATUS_TYPE,
CustomChainConfig,
IAdapter,
IPlugin,
IProvider,
IWeb3AuthCoreOptions,
UserAuthInfo,
WALLET_ADAPTER_TYPE,
} from "@web3auth/base";
import { type Web3AuthNoModal } from "@web3auth/no-modal";
import { Ref, ShallowRef } from "vue";

export type Web3AuthContextConfig = {
web3AuthOptions: IWeb3AuthCoreOptions;
adapters?: IAdapter<unknown>[];
plugins?: IPlugin[];
};

export interface Web3AuthProviderProps {
config: Web3AuthContextConfig;
}

interface IBaseWeb3AuthComposableContext {
isConnected: Ref<boolean>;
provider: Ref<IProvider | null>;
userInfo: Ref<Partial<OpenloginUserInfo> | null>;
isMFAEnabled: Ref<boolean>;
isInitialized: Ref<boolean>;
status: Ref<ADAPTER_STATUS_TYPE | null>;
enableMFA(params?: LoginParams): Promise<void>;
logout(params?: { cleanup: boolean }): Promise<void>;
addAndSwitchChain(chainConfig: CustomChainConfig): Promise<void>;
addPlugin(plugin: IPlugin): void;
getPlugin(pluginName: string): IPlugin | null;
authenticateUser(): Promise<UserAuthInfo>;
addChain(chainConfig: CustomChainConfig): Promise<void>;
switchChain(params: { chainId: string }): Promise<void>;
}

export interface IWeb3AuthContext extends IBaseWeb3AuthComposableContext {
web3Auth: ShallowRef<Web3AuthNoModal | null>;
init(): Promise<void>;
connectTo<T>(walletName: WALLET_ADAPTER_TYPE, loginParams?: T): Promise<IProvider | null>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"include": ["src"],
"compilerOptions": {
"jsx": "preserve"
}
}
7 changes: 7 additions & 0 deletions packages/composables/no-modal-vue-composables/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../../tsconfig.json",
"include": ["src", "test"],
"compilerOptions": {
"jsx": "preserve"
}
}