2021-09-06 22:36:09 +00:00
|
|
|
import { computed, watchEffect, ref, watch } from "@nuxtjs/composition-api";
|
2021-07-21 20:53:46 +00:00
|
|
|
|
|
|
|
import MainnetSVG from "~/assets/icons/mainnet.svg?inline";
|
|
|
|
import PolygonSVG from "~/assets/icons/polygon.svg?inline";
|
2021-10-08 15:49:24 +00:00
|
|
|
import ArbitrumSVG from "~/assets/icons/arbitrum.svg?inline";
|
2021-10-17 13:01:25 +00:00
|
|
|
import AvalancheSVG from "~/assets/icons/avalanche.svg?inline";
|
2022-04-19 11:02:26 +00:00
|
|
|
import OptimismSVG from "~/assets/icons/optimism.svg?inline";
|
2021-10-08 15:49:24 +00:00
|
|
|
|
2021-07-27 21:43:51 +00:00
|
|
|
import { useModal } from "./useModal";
|
|
|
|
import { useNotification } from "./useNotification";
|
2021-09-03 13:59:09 +00:00
|
|
|
import { useWeb3 } from "@instadapp/vue-web3";
|
2021-09-06 22:36:09 +00:00
|
|
|
import { useCookies } from "./useCookies";
|
2021-07-21 20:53:46 +00:00
|
|
|
|
|
|
|
export enum Network {
|
|
|
|
Mainnet = "mainnet",
|
2021-10-08 15:49:24 +00:00
|
|
|
Polygon = "polygon",
|
2021-10-17 12:57:51 +00:00
|
|
|
Arbitrum = "arbitrum",
|
2022-04-19 11:02:26 +00:00
|
|
|
Avalanche = "avalanche",
|
|
|
|
Optimism = "optimism",
|
2021-07-21 20:53:46 +00:00
|
|
|
}
|
|
|
|
|
2021-07-28 21:38:15 +00:00
|
|
|
export const networks = [
|
2021-07-21 20:53:46 +00:00
|
|
|
{ id: "mainnet", chainId: 1, name: "Mainnet", icon: MainnetSVG },
|
2021-10-08 15:49:24 +00:00
|
|
|
{ id: "polygon", chainId: 137, name: "Polygon", icon: PolygonSVG },
|
2021-10-17 12:57:51 +00:00
|
|
|
{ id: "arbitrum", chainId: 42161, name: "Arbitrum", icon: ArbitrumSVG },
|
2021-10-17 13:01:25 +00:00
|
|
|
{ id: "avalanche", chainId: 43114, name: "Avalanche", icon: AvalancheSVG },
|
2022-04-19 11:02:26 +00:00
|
|
|
{ id: "optimism", chainId: 10, name: "Optimism", icon: OptimismSVG },
|
2021-07-21 20:53:46 +00:00
|
|
|
];
|
|
|
|
|
2021-08-14 12:30:55 +00:00
|
|
|
export const activeNetworkId = ref<Network>();
|
2021-07-28 21:38:15 +00:00
|
|
|
export const activeNetwork = computed(
|
2021-07-21 20:53:46 +00:00
|
|
|
() => networks.find(n => n.id === activeNetworkId.value) || networks[0]
|
|
|
|
);
|
|
|
|
|
|
|
|
export function useNetwork() {
|
2021-07-27 21:43:51 +00:00
|
|
|
const { showWarning } = useNotification();
|
2021-08-31 19:23:47 +00:00
|
|
|
const { account, chainId } = useWeb3();
|
2021-07-27 21:43:51 +00:00
|
|
|
const { showNetworksMismatchDialog } = useModal();
|
2021-09-06 22:36:09 +00:00
|
|
|
const { get: getCookie, set: setCookie } = useCookies();
|
2021-07-27 21:43:51 +00:00
|
|
|
|
|
|
|
const networkMismatch = computed(
|
2021-08-31 19:23:47 +00:00
|
|
|
() => chainId.value != activeNetwork.value?.chainId
|
2021-07-27 21:43:51 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
const checkForNetworkMismatch = () => {
|
|
|
|
if (networkMismatch.value) {
|
|
|
|
showNetworksMismatchDialog();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
async function switchToMainnet() {
|
|
|
|
if (window.ethereum) {
|
|
|
|
const chainData = {
|
|
|
|
chainId: "0x1"
|
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
|
|
await window.ethereum.request({
|
|
|
|
method: "wallet_switchEthereumChain",
|
|
|
|
params: [chainData]
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
return Promise.reject(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function switchToPolygon() {
|
|
|
|
if (window.ethereum) {
|
|
|
|
const chainId = "0x89";
|
|
|
|
|
|
|
|
try {
|
|
|
|
await window.ethereum.request({
|
|
|
|
method: "wallet_switchEthereumChain",
|
|
|
|
params: [{ chainId }]
|
|
|
|
});
|
|
|
|
} catch (switchError) {
|
|
|
|
// 4902 error code indicates that the chain has not been added to MetaMask.
|
|
|
|
if (switchError.code === 4902) {
|
|
|
|
try {
|
|
|
|
const chainData = {
|
|
|
|
chainId,
|
|
|
|
chainName: "Matic(Polygon) Mainnet",
|
|
|
|
nativeCurrency: {
|
|
|
|
name: "Matic",
|
|
|
|
symbol: "MATIC",
|
|
|
|
decimals: 18
|
|
|
|
},
|
|
|
|
rpcUrls: ["https://rpc-mainnet.matic.network"],
|
|
|
|
blockExplorerUrls: ["https://polygonscan.com/"]
|
|
|
|
};
|
|
|
|
await window.ethereum.request({
|
|
|
|
method: "wallet_addEthereumChain",
|
|
|
|
params: [chainData, account.value]
|
|
|
|
});
|
|
|
|
} catch (addError) {
|
|
|
|
return Promise.reject(addError);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return Promise.reject(switchError);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-08 15:49:24 +00:00
|
|
|
async function switchToArbitrum() {
|
|
|
|
if (window.ethereum) {
|
|
|
|
const chainId = "0xa4b1";
|
|
|
|
|
|
|
|
try {
|
|
|
|
await window.ethereum.request({
|
|
|
|
method: "wallet_switchEthereumChain",
|
|
|
|
params: [{ chainId }]
|
|
|
|
});
|
|
|
|
} catch (switchError) {
|
|
|
|
// 4902 error code indicates that the chain has not been added to MetaMask.
|
|
|
|
if (switchError.code === 4902) {
|
|
|
|
try {
|
|
|
|
const chainData = {
|
|
|
|
chainId,
|
|
|
|
chainName: 'Arbitrum One',
|
|
|
|
nativeCurrency: {
|
|
|
|
name: 'Ethereum',
|
|
|
|
symbol: 'ETH',
|
|
|
|
decimals: 18,
|
|
|
|
},
|
|
|
|
rpcUrls: ['https://arb1.arbitrum.io/rpc'],
|
|
|
|
blockExplorerUrls: ['https://arbiscan.io'],
|
|
|
|
};
|
|
|
|
await window.ethereum.request({
|
|
|
|
method: "wallet_addEthereumChain",
|
|
|
|
params: [chainData, account.value]
|
|
|
|
});
|
|
|
|
} catch (addError) {
|
|
|
|
return Promise.reject(addError);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return Promise.reject(switchError);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-17 12:57:51 +00:00
|
|
|
async function switchToAvalanche() {
|
|
|
|
if (window.ethereum) {
|
|
|
|
const chainId = '0xa86a'
|
|
|
|
|
|
|
|
try {
|
|
|
|
await window.ethereum.request({
|
|
|
|
method: 'wallet_switchEthereumChain',
|
|
|
|
params: [{ chainId }],
|
|
|
|
})
|
|
|
|
} catch (switchError) {
|
|
|
|
// 4902 error code indicates that the chain has not been added to MetaMask.
|
|
|
|
if (switchError.code === 4902) {
|
|
|
|
try {
|
|
|
|
const chainData = {
|
|
|
|
chainId,
|
|
|
|
chainName: 'Avalanche Network',
|
|
|
|
nativeCurrency: {
|
|
|
|
name: 'Avalanche',
|
|
|
|
symbol: 'AVAX',
|
|
|
|
decimals: 18,
|
|
|
|
},
|
|
|
|
rpcUrls: ['https://api.avax.network/ext/bc/C/rpc'],
|
|
|
|
blockExplorerUrls: ['https://cchain.explorer.avax.network/'],
|
|
|
|
}
|
|
|
|
await window.ethereum.request({
|
|
|
|
method: 'wallet_addEthereumChain',
|
|
|
|
params: [chainData, account.value],
|
|
|
|
})
|
|
|
|
} catch (addError) {
|
|
|
|
return Promise.reject(addError)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return Promise.reject(switchError)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-19 11:02:26 +00:00
|
|
|
async function switchToOptimism() {
|
|
|
|
if (window.ethereum) {
|
|
|
|
const chainId = '0xa'
|
|
|
|
|
|
|
|
try {
|
|
|
|
await window.ethereum.request({
|
|
|
|
method: 'wallet_switchEthereumChain',
|
|
|
|
params: [{ chainId }],
|
|
|
|
})
|
|
|
|
} catch (switchError) {
|
|
|
|
// 4902 error code indicates that the chain has not been added to MetaMask.
|
|
|
|
if (switchError.code === 4902) {
|
|
|
|
try {
|
|
|
|
const chainData = {
|
|
|
|
chainId,
|
|
|
|
chainName: 'Optimism Network',
|
|
|
|
nativeCurrency: {
|
|
|
|
name: 'Ethereum',
|
|
|
|
symbol: 'ETH',
|
|
|
|
decimals: 18,
|
|
|
|
},
|
|
|
|
rpcUrls: ['https://mainnet.optimism.io'],
|
|
|
|
blockExplorerUrls: ['https://optimistic.etherscan.io'],
|
|
|
|
}
|
|
|
|
await window.ethereum.request({
|
|
|
|
method: 'wallet_addEthereumChain',
|
|
|
|
params: [chainData, account.value],
|
|
|
|
})
|
|
|
|
} catch (addError) {
|
|
|
|
return Promise.reject(addError)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return Promise.reject(switchError)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-27 21:43:51 +00:00
|
|
|
async function switchNetwork() {
|
|
|
|
try {
|
|
|
|
if (activeNetworkId.value === "mainnet") {
|
|
|
|
await switchToMainnet();
|
2021-10-08 15:49:24 +00:00
|
|
|
} else if (activeNetworkId.value === "arbitrum") {
|
|
|
|
await switchToArbitrum();
|
2021-10-17 12:57:51 +00:00
|
|
|
} else if (activeNetworkId.value === "avalanche") {
|
|
|
|
await switchToAvalanche();
|
2022-04-19 11:02:26 +00:00
|
|
|
} else if (activeNetworkId.value === "optimism") {
|
|
|
|
await switchToOptimism();
|
2021-07-27 21:43:51 +00:00
|
|
|
} else {
|
|
|
|
await switchToPolygon();
|
|
|
|
}
|
|
|
|
return Promise.resolve();
|
|
|
|
} catch (error) {
|
|
|
|
showWarning("Failed to switch network");
|
|
|
|
return Promise.reject(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
watch(activeNetworkId, () => {
|
2021-09-06 22:36:09 +00:00
|
|
|
setCookie("network", activeNetworkId.value);
|
2021-08-18 20:20:45 +00:00
|
|
|
});
|
2021-07-27 21:43:51 +00:00
|
|
|
|
2021-09-06 22:36:09 +00:00
|
|
|
watchEffect(() => {
|
2021-08-18 20:20:45 +00:00
|
|
|
if (activeNetworkId.value) {
|
|
|
|
return;
|
|
|
|
}
|
2021-07-27 21:43:51 +00:00
|
|
|
|
2021-09-06 22:36:09 +00:00
|
|
|
const savedNetwork = getCookie("network");
|
|
|
|
|
|
|
|
if ((Object.values(Network) as any[]).includes(savedNetwork)) {
|
|
|
|
activeNetworkId.value = savedNetwork as Network;
|
|
|
|
} else {
|
|
|
|
activeNetworkId.value = Network.Mainnet;
|
|
|
|
}
|
2021-08-31 19:23:47 +00:00
|
|
|
// refreshWeb3()
|
2021-08-18 20:20:45 +00:00
|
|
|
});
|
2021-07-27 21:43:51 +00:00
|
|
|
|
2021-07-21 20:53:46 +00:00
|
|
|
return {
|
2021-07-27 21:43:51 +00:00
|
|
|
networkMismatch,
|
2021-07-21 20:53:46 +00:00
|
|
|
networks,
|
|
|
|
activeNetworkId,
|
2021-07-27 21:43:51 +00:00
|
|
|
activeNetwork,
|
|
|
|
switchNetwork,
|
|
|
|
checkForNetworkMismatch
|
2021-07-21 20:53:46 +00:00
|
|
|
};
|
|
|
|
}
|