@fewcha/web3-react
Version:
Check the documentation at https://docs.fewcha.app/
266 lines (243 loc) • 7.43 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
// Copyright 2022 Fewcha. All rights reserved.
import React, { useContext, createContext, useState, useEffect, useRef } from "react";
import { v4 as uuidv4 } from "uuid";
import { wallets } from "./config/wallet";
import { PopupBackground, PopupBackgroundScreen, PopupBackgroundWrapper, PopupBackgroundBackground, ConnectWalletButton, Popup, PopupClose, PopupTitle, WalletList, WalletItem, WalletTitleWrapper, WalletIcon, WalletTitle, WalletDetected } from "./style/main";
import Web3 from "@fewcha/web3";
export const Web3Context = createContext(null);
export const useWeb3 = () => {
const {
account,
balance,
disconnect,
currentWallet,
isConnected,
network,
fewcha,
martian
} = useContext(Web3Context);
return {
account,
balance,
disconnect,
currentWallet,
isConnected,
network,
fewcha,
martian
};
};
const emptyAccount = {
address: "",
publicKey: ""
};
const Web3ReactProvider = ({
children
}) => {
const [account, setAccount] = useState(emptyAccount);
const [balance, setBalance] = useState("");
const [isConnected, setIsConnected] = useState(false);
const [network, setNetwork] = useState("");
const [popups, changePopups] = useState([]);
const [currentWallet, setCurrentWallet] = useState("fewcha");
const fewcha = new Web3();
const martian = new Web3(window.martian);
const popupBackgroundService = useRef(null);
const addPopup = ({
Component,
callback
}) => {
const key = uuidv4();
changePopups([...popups, {
key,
Component
}]);
if (callback) callback(key);
return key;
};
const removePopup = key => {
changePopups(popups.filter(popup => popup.key !== key));
};
const removeAll = () => {
changePopups([]);
};
const chooseWeb3 = async (walletCodename, callback) => {
callback && callback();
setCurrentWallet(walletCodename);
const account = await window[walletCodename].connect();
if (account.status === 200) {
setIsConnected(true);
switch (walletCodename) {
case "fewcha":
setAccount(_extends({}, emptyAccount, account.data));
break;
case "martian":
setAccount(_extends({}, emptyAccount, {
address: account.address,
publicKey: account.publicKey
}));
break;
}
}
};
const clear = () => {
setAccount(emptyAccount);
setNetwork("");
setBalance("0");
setIsConnected(false);
};
const connectedEvent = () => {
setIsConnected(true);
};
const disconnectedEvent = () => {
clear();
};
const changeAccount = event => {
const e = event;
if (e.detail) {
setAccount(e.detail);
}
};
const changeBalance = event => {
const e = event;
if (e.detail) {
setBalance(e.detail);
}
};
const changeNetwork = event => {
const e = event;
if (e.detail) {
setNetwork(e.detail);
}
};
const disconnect = () => {
fewcha && fewcha.action.disconnect();
martian && martian.action.disconnect();
};
useEffect(() => {
window.addEventListener("aptos#connected", connectedEvent);
window.addEventListener("aptos#disconnected", disconnectedEvent);
window.addEventListener("aptos#changeAccount", changeAccount);
window.addEventListener("aptos#changeBalance", changeBalance);
window.addEventListener("aptos#changeNetwork", changeNetwork);
return () => {
window.removeEventListener("aptos#connected", connectedEvent);
window.removeEventListener("aptos#disconnected", disconnectedEvent);
window.removeEventListener("aptos#changeAccount", changeAccount);
window.removeEventListener("aptos#changeBalance", changeBalance);
window.removeEventListener("aptos#changeNetwork", changeNetwork);
}; // eslint-disable-next-line
}, []);
const Component = popups.length > 0 ? popups[popups.length - 1].Component : () => /*#__PURE__*/React.createElement(React.Fragment, null);
return /*#__PURE__*/React.createElement(Web3Context.Provider, {
value: {
currentWallet,
setCurrentWallet,
chooseWeb3,
disconnect,
account,
balance,
isConnected,
addPopup,
removePopup,
removeAll,
network,
fewcha,
martian
}
}, children, popups.length > 0 && /*#__PURE__*/React.createElement(PopupBackground, {
onClick: e => {
if (e.target !== popupBackgroundService.current) return;
removePopup(popups[popups.length - 1].key);
}
}, /*#__PURE__*/React.createElement(PopupBackgroundScreen, null, /*#__PURE__*/React.createElement(PopupBackgroundWrapper, {
"aria-hidden": "true"
}, /*#__PURE__*/React.createElement(PopupBackgroundBackground, {
ref: popupBackgroundService
})), /*#__PURE__*/React.createElement("span", {
className: "sm:inline-block sm:align-middle sm:h-screen",
"aria-hidden": "true"
}, "\u200B"), /*#__PURE__*/React.createElement(Component, null))));
};
export default Web3ReactProvider;
export const ConnectWallet = ({
theme: _theme = "dark",
type: _type = "grid",
label: _label = "Connect Wallet"
}) => {
const {
addPopup,
isConnected
} = useContext(Web3Context);
if (isConnected) return null;
return /*#__PURE__*/React.createElement(ConnectWalletButton, {
onClick: () => {
const key = addPopup({
Component: () => /*#__PURE__*/React.createElement(SelectWalletPopup, {
popupKey: key,
type: _type
})
});
}
}, _label);
};
const SelectWalletPopup = ({
type,
popupKey
}) => {
const grid = type === "grid";
const {
removePopup,
chooseWeb3
} = useContext(Web3Context);
const [loading, setLoading] = useState(false);
const close = () => {
removePopup(popupKey);
};
return /*#__PURE__*/React.createElement(Popup, null, /*#__PURE__*/React.createElement(PopupClose, {
onClick: () => {
close();
}
}, /*#__PURE__*/React.createElement("svg", {
width: "24",
height: "24",
viewBox: "0 0 24 24",
fill: "none",
xmlns: "http://www.w3.org/2000/svg"
}, /*#__PURE__*/React.createElement("path", {
d: "M4 4L9 9",
stroke: "#BEC4CE",
strokeWidth: "2",
strokeMiterlimit: "10",
strokeLinecap: "round"
}), /*#__PURE__*/React.createElement("path", {
d: "M12 12L20 20",
stroke: "#BEC4CE",
strokeWidth: "2",
strokeMiterlimit: "10",
strokeLinecap: "round"
}), /*#__PURE__*/React.createElement("path", {
d: "M20 4L4 20",
stroke: "#BEC4CE",
strokeWidth: "2",
strokeMiterlimit: "10",
strokeLinecap: "round"
}))), /*#__PURE__*/React.createElement(PopupTitle, null, "Connect a wallet on Aptos to continue"), /*#__PURE__*/React.createElement(WalletList, {
grid: grid
}, wallets.map((item, index) => /*#__PURE__*/React.createElement(WalletItem, {
grid: grid,
key: index,
onClick: () => {
chooseWeb3(item.code, () => {
close();
});
}
}, /*#__PURE__*/React.createElement(WalletTitleWrapper, {
grid: grid
}, /*#__PURE__*/React.createElement(WalletIcon, {
grid: grid
}, " ", grid ? item.icon60 : item.icon36), /*#__PURE__*/React.createElement(WalletTitle, null, item.title)), window[item.code] && /*#__PURE__*/React.createElement(WalletDetected, {
grid: grid
}, "Detected")))));
};