vue3-web3modal
v0.1.5
Published
[![NPM version](https://img.shields.io/npm/v/vue3-web3modal.svg?style=flat)](https://npmjs.com/package/vue3-web3modal) [![NPM downloads](https://img.shields.io/npm/dm/vue3-web3modal.svg?style=flat)](https://npmjs.com/package/vue3-web3modal)[![Netlify Stat
Downloads
20
Readme
vue3-web3modal
demo (with darkmode)
The Demo works, Connect your wallet to see it in action.
Quick Start;
See demo folder in repository to see how its setup!
Copied from uniswap;
This Modal is copied from this Uniswap interface, as seen in the Uniswap exchange.
Installation
npm i vue3-web3modal
# or
yarn add vue3-web3modal
setup
web3modal So you first have to install your desired providers;
//install desired providers
npm i Authereum
npm i Venly
npm i Portis
npm i Bitski
....
For all supported providers, see origninal web3modal providers for more info;
Create a providerOptions file:
The providers options file format is the same as web3modal providers
// ./providerOptions.js
import Authereum from "authereum";
import { Venly } from "@venly/web3-provider";
import Portis from "@portis/web3";
import { Bitski } from "bitski";
export const providerOptions = {
walletconnect: {
package: WalletConnectProvider,
options: {
infuraId: process.env.VUE_APP_INFURA_KEY,
},
},
venly: {
package: Venly, // required
options: {
clientId: process.env.VUE_APP_VENLY_CLIENT_ID // required
}
},
portis: {
package: Portis, // required
options: {
id: process.env.VUE_APP_PORTIS_ID, // required
},
},
bitski: {
package: Bitski,
options: {
clientId: process.env.VUE_APP_BITSKI_CLIENT_ID,
callbackUrl: window.location.href + "bitski-callback.html",
},
},
setup vue3
Requires vue-i18n to be in your app
Some Providers dont support events so all transactions are confirmed using infura ;
infuraKey app key is required
// in your main.js
const infuraKey = process.env.VUE_APP_INFURA_KEY;
import {providerOptions} from './providers'
import { createApp } from 'vue';
import { createI18n } from "vue-i18n";
import { createWeb3 } from 'vue3-web3modal';
import App from './App.vue';
//To disable global registration , set global false
import { theme } from './theme';
import {providerOptions} from './providers'
const web3vue = createWeb3({
infuraKey,
providerOptions,
theme,
global:true // components will be registered globally
})
const app = createApp(App);
app.use(i18n);
app.use(web3vue);
app.config.devtools = true
app.mount('#app');
Using the Web3Manager
automatically registers the modal!
// import Web3Manager plugin and active web3
<script>
import { Web3Manager, useActiveWeb3Vue} from "vue3-web3modal";
export default {
components: {
Web3Manager,
},
setup() {
// all these variable need .value
const {
web3, //ref
account, //ref
etherBalance, //asyncComputed
chainId,//ref
providerInfo,//computed
isValidNetwork,//computed
active,//ref
error, //ref
} = useActiveWeb3Vue();
console.log(etherBalance.value)
return {
account
};
},
};
</script>
<template>
<Web3Manager />
</template>
The Web3Manager has a slot for user dropdown
<Web3Manager>
<UserDropDown>// your user dropdwon component
</Web3Manager>
using Web3Modal only, No Web3Manager
First Disable automatic registration.
Automatic registration disabled by default In your main.js
const web3vue = createWeb3({
infuraKey,
providerOptions,
theme,
//global:true //remove this
})
In One of your Components eg App.vue
// import web menu plugin and activeweb3
<script>
import { Web3Modal, useActiveWeb3Vue, useWeb3ModalToggle} from "vue3-web3modal";
export default {
components: {
Web3Modal,
},
setup() {
// all these variable need .value
const {
web3, //ref
account, //ref
etherBalance, //asyncComputed
...
} = useActiveWeb3Vue();
console.log(etherBalance.value)
const { open, close, isOpen, toggle} = useWeb3ModalToggle();
return {
account,
toggle
};
},
};
</script>
<template>
<Web3Modal />
<a href="#" @click="toggle()">Connect Your Wallet</a>
</template>
Translations.
Important!!! You must initialize and enable vue-i18n The Plugin uses vuei18n for translations .
{{$t('Connect Modal')}}
Add the following translations to your translation file: I will appreciate any pull requests for this ...
// in ./translations.js
const messages = {
en: {
"Account": "Account",
"Arbiscan": "Arbiscan",
"Arbitrum Bridge": "Arbitrum Bridge",
"Bridge": "Bridge",
"Bscscan": "Bscscan",
"Change": "Change",
"Check network status": "Check network status",
"close": "close",
"Connect": "Connect",
"Connect to a wallet": "Connect to a wallet",
"Connected with": "Connected with",
"Copied": "Copied",
"dashboard": "dashboard",
"Disconnect": "Disconnect",
"Error connecting": "Error connecting",
"Error Connecting": "Error Connecting",
"Error connecting. Try refreshing the page": "Error connecting. Try refreshing the page",
"Etherscan": "Etherscan",
"Help Center": "Help Center",
"here.": "here.",
"Initializing...": "Initializing...",
"Invalid Network": "Invalid Network",
"Network Warning": "Network Warning",
"onDismiss": "onDismiss",
"Optimism Gateway": "Optimism Gateway",
"Optimistic Etherscan": "Optimistic Etherscan",
"Pending": "Pending",
"Polygon Bridge": "Polygon Bridge",
"Polygonscan": "Polygonscan",
"Select a network": "Select a network",
"Show Portis": "Show Portis",
"Try Again ": "Try Again ",
"Wallet": "Wallet",
"Wrong Network": "Wrong Network",
"You may have lost your network connection, or {label} might be down right now.": "You may have lost your network connection, or {label} might be down right now.",
"You may have lost your network connection.": "You may have lost your network connection.",
"Your Wallets Network is not supported": "Your Wallets Network is not supported"
},
de:{
"Account": "Konto",
"Arbiscan": "Arbiscan",
....
//etc
}
}
Initialize vue-i18n
//in your main.js
.....
import translations from './messages'; // translations
// 2. Create i18n instance with options
const i18n = createI18n({
locale: 'en', // set locale
fallbackLocale: 'en', // set fallback locale
translations, // set locale messages
})
Place i18n before web3vue
const app = createApp(APP);
app.use(i18n); // translations come before
app.use(web3vue); // initialize web3vue
Usage
once the modal is enabled and permission granted by user you can access the following variable anywhere in your app
// anywhere in your app setup()
import { useActiveWeb3Vue } from "vue3-web3modal";
setup(){
const {
web3, //ref
account, //ref
etherBalance, //asyncComputed
chainId,//ref
providerInfo,//computed
isValidNetwork,//computed
active,//ref
error, //ref
} = useActiveWeb3Vue();
//example use of web3 initialized;
const contract = new web3.value.eth.Contract(your_toke_ABI, token_address);
const balance = await contract.methods.balanceOf(account.value);
console.log(web3.utils.fromWei(balance.toString()));
return{
account
web3
balance
}
}
web3
web3
is null ref
before initialization
after its populated with the connected web3 account
import { useActiveWeb3Vue } from "vue3-web3modal";
/// in the component setup
setup(){
const { web3, account } = useActiveWeb3Vue();
const contract = new web3.value.eth.Contract(your_toke_ABI, token_address);
const balance = await contract.methods.balanceOf(account.value);
console.log(web3.utils.fromWei(balance.toString()));
return {
balance;
}
}
account ;
account
is a null
ref
before initialization
after user connected, is the users address;
It will be modified to new address if user changes address in wallet eg metamask
import { useActiveWeb3Vue } from "vue3-web3modal";
/// in the component setup
setup(){
const { account } = useActiveWeb3Vue();
console.log(account.value);
//0x7f0374480b9Ca09144F6cBd16774FDf1da1ae528
}
etherBalance;
etherBalance
is a null
computed before initialization;
After user connected, is the users etherbalance in ETH;
Is computed
and will be recomputed if user changes network or address or spends or receives eth;
import { useActiveWeb3Vue } from "vue3-web3modal";
/// in the component setup
setup(){
const { etherBalance } = useActiveWeb3Vue();
console.log(etherBalance.value);
//0.054357546476767353
}
chainId
chainId
is a null ref
before initialization;
After user connected, is the users network chainId ;
Is a ref
and will be adjusted automatically if user changes network;
import { useActiveWeb3Vue } from "vue3-web3modal";
/// in the component setup
setup(){
const { chainId } = useActiveWeb3Vue();
console.log(chainId.value);
// 3
}
providerInfo, isValidNetwork
providerInfo
is the information of connected provider eg metamask , coinbase etc:
isValidNetwork
is a boolean
ref
, determines if user is connected to a supported network;
the follwoing networks are supported
MAINNET: 1,
ROPSTEN: 3,
RINKEBY: 4,
GOERLI: 5,
KOVAN: 42,
ARBITRUM_ONE: 42161,
ARBITRUM_RINKEBY: 421611,
OPTIMISM: 10,
OPTIMISTIC_KOVAN: 69,
POLYGON: 137,
POLYGON_MUMBAI: 80001,
BINANCE: 56,
BINANCE_TESTNET: 97,
usage
import { useActiveWeb3Vue } from "vue3-web3modal";
/// in the component setup
setup(){
const { isValidNetwork,providerInfo } = useActiveWeb3Vue();
if(isValidNetwork.value){
console(providerInfo.value)
/*{
name: metamask,
.....
}*/
}
// true
}
active, error
active
is a boolean
ref, determines if user the user has connected his wallet and everything is set;
error
is a ref
containing errors encountered,
you can use it to determine if everythiing is going ok
import { useActiveWeb3Vue } from "vue3-web3modal";
import {watch} from vue;
/// in the component setup
setup(){
const { active , error, web3 } = useActiveWeb3Vue();
watch([active, error], ([active, error])=>{
if(active){
login(); // user connected
}else{
logout() // user closed wallet
console.log('deactivated')
}
if(error){
showError(error);
}
})
}
Transactions;
Some providers dont support events, making it tough to confirm transactions. so to unify transactions confirmation, a method exists to confirm transactions via Infura
import { useActiveWeb3Vue, addTransaction, txBus } from "vue3-web3modal";
/// in the component setup
setup(){
const { web3 } = useActiveWeb3Vue();
const to = '0x7f0374480b9Ca09144F6cBd16774FDf1da1ae528';
const contract = new web3.value.eth.Contract(your_toke_ABI, token_address);
const amount = web3.utils.toWei('0.9675');
const hash = await contract.methods.transfer(to, amount);
// some providers dont support this
//contract.methods.transfer(to, amount).once('receipt',(receipt)=>console.log(receipt))
addTransaction({
hash,
onSuccess:(receipt)=>console.log(receipt), // after one confirmation
onError:(error)=>console.log(error), // called on any errors
summary:'Send 0.0967 ZBT', A summary Displayed to the user !!
approval: false, // flag to show tx is approval tx
})
// yoh can also listen to the tx's events on it hash
txBus.on(hash, ({receipt, error, hash, summary})=>{
// error occured if error was set;
if(error) return showError(error);
console.log(receipt.hash)
showNotification(summary.)
})
}
events;
Again Some providers dont support events listening; You would be wise to use infura;
Infura doesnt support binance chain
import { useInfura } from "vue3-web3modal";
/// in the component setup
setup(){
//websocket with fallback to https;
const { infuraWss } = useInfura();
// infuraWss is a web3 instance connected to infura websockets
infuraWss.value.eth
.subscribe("newBlockHeaders")
.on("data", (block) => console.log(block));
// contracts events
const contract = new infuraWss.value.eth.Contract(your_toke_ABI, token_address);
contract.events.Transfer().on('data', (event)=> console.log(event))
}
Theming
By default, Uniswap colors are preserved, But we all have our themes Adjust the colours below to suit your needs.
I just extracted this theme in random, I dont what color goes where so experimemt and share
// in ./theme.js
import { computed, reactive } from "vue";
import { darkMode } from "vue3-web3modal";
export const theme = reactive({
colors: null,
// base
white:"#FFFFFF",
black:"#000000",
// text
text1: computed(() => darkMode.value ? "#FFFFFF" : "#000000"),
text2: computed(() => darkMode.value ? "#C3C5CB" : "#565A69"),
text3: computed(() => darkMode.value ? "#6C7284" : "#888D9B"),
text4: computed(() => darkMode.value ? "#565A69" : "#C3C5CB"),
// backgrounds / greys
// backgrounds / greys
bg0: computed(() => darkMode.value ? '#191B1F' : '#FFF'),
bg1: computed(() => darkMode.value ? '#212429' : '#F7F8FA'),
bg2: computed(() => darkMode.value ? '#2C2F36' : '#EDEEF2'),
bg3: computed(() => darkMode.value ? '#40444F' : '#CED0D9'),
bg4: computed(() => darkMode.value ? '#565A69' : '#888D9B'),
//borders
bd0: computed(() => darkMode.value ? '#191B1F' : '#CED0D9'),
bd1: computed(() => darkMode.value ? '#212429' : '#CED0D9'),
bd2: computed(() => darkMode.value ? '#2C2F36' : '#EDEEF2'),
bd3: computed(() => darkMode.value ? '#40444F' : '#CED0D9'),
//specialty colors
modalBG: computed(() => darkMode.value ? "rgba(0,0,0,.425)" : "rgba(0,0,0,0.3)"),
//primary colorsrgb(209 250 229)
primary1: computed(() => darkMode.value ? '#2172E5' : '#1e7e6b'),
//primary2: computed(() => darkMode.value ? '#3680E7' : '#78baad'),
primary3: computed(() => darkMode.value ? '#4D8FEA' : '#90c3b9'),
primary4: computed(() => darkMode.value ? '#376bad70' : '#a4d2c9'),
primary5: computed(() => darkMode.value ? '#153d6f70' : '#c2eae2'),
// color text
// color text
primaryText1: computed(() => darkMode.value ? '#5090ea' : '#1e7e6b'),
// other
red1: "#FD4040",
green1: "#27AE60",
yellow2: "#F3841E",
blue1: "#a78253",
//shadows
shadow1: computed(() => darkMode.value ? "#000" : "#2F80ED"),
});
add the theme to your main.js
// adjust your main.js
const infuraKey = process.env.VUE_APP_INFURA_KEY;
import { theme } from './theme'; // see theming below
import {providerOptions} from './providers' //we created this above
const web3vue = createWeb3({
infuraKey,
providerOptions,
theme, // add theme
})
const app = createApp(DemoApp);
app.use(i18n);
app.use(web3vue);
#Dark Mode
<script setup>
import { toggleDark, isDark } from "vue3-web3modal";
console.log(isDark);
</script>
<template>
<button @click="toggleDark()"> DarkMode </button>
</template>
Env Variables
if using vue-cli its recommeded to add your api keys to your .env
file;
in vue-cli the VUE_APP_
prefix ie required
// in ./.env -->these are dummies
VUE_APP_INFURA_KEY=7cd6581wth84a5e9084450a8c9a90e8j
VUE_APP_FORTMATIC_KEY=pk_live_5CYC964AFEDW4B62
VUE_APP_PORTIS_ID=01801ec8-5ec5-4070-aeff-4a955ea4bccb
....
// const infuraKey = process.env.VUE_APP_INFURA_KEY;
Or Laravel
The MIX_
prefix is required
// in ./.env
MIX_INFURA_KEY=7cd6581wth84a5e9084450a8c9a90e8j
MIX_FORTMATIC_KEY=pk_live_5CYC964AFEDW4B62
MIX_PORTIS_ID=01801ec8-5ec5-4070-aeff-4a955ea4bccb
....
Contributing
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :D
Author
vue3-web3modal © envatic, Released under the MIT License. Authored and maintained by envatic with help from contributors (list).