pull/1194/head
Peer Richelsen 2021-11-20 13:17:38 +00:00
parent 8589c8cab7
commit 631d512f05
4 changed files with 167 additions and 193 deletions

143
components/ConnectWeb3.tsx Normal file
View File

@ -0,0 +1,143 @@
import { ExternalProvider, JsonRpcFetchFunc, Web3Provider } from "@ethersproject/providers";
import { useWeb3React, Web3ReactProvider } from "@web3-react/core";
import { InjectedConnector } from "@web3-react/injected-connector";
import { WalletConnectConnector } from "@web3-react/walletconnect-connector";
import { useEffect, useState } from "react";
import classNames from "@lib/classNames";
import useLocalStorage from "@lib/hooks/useLocalStorage";
import { useLocale } from "@lib/hooks/useLocale";
import Button from "@components/ui/Button";
const injected = new InjectedConnector({ supportedChainIds: [1, 3, 4, 5, 42] });
const wcConnector = new WalletConnectConnector({
infuraId: "517bf3874a6848e58f99fa38ccf9fce4",
});
const ConnectorNames = {
Injected: "injected",
WalletConnect: "walletconnect",
};
const W3Operations = {
Connect: "connect",
Disconnect: "disconnect",
};
function getLibrary(provider: ExternalProvider | JsonRpcFetchFunc) {
const library = new Web3Provider(provider);
// library.pollingInterval = 12000;
return library;
}
export default function ConnectWeb3() {
return (
<Web3ReactProvider getLibrary={getLibrary}>
<Web3Component />
</Web3ReactProvider>
);
}
function Web3Component() {
const { t } = useLocale();
const web3React = useWeb3React();
const [, setLoaded] = useState(false);
const [latestOp, setLatestOp] = useLocalStorage("latest_op", "");
const [latestConnector, setLatestConnector] = useLocalStorage("latest_connector", "");
// console.log(web3React);
useEffect(() => {
if (latestOp == "connect" && latestConnector == "injected") {
injected
.isAuthorized()
.then((isAuthorized) => {
setLoaded(true);
if (isAuthorized && !web3React.active && !web3React.error) {
web3React.activate(injected);
}
})
.catch(() => {
setLoaded(true);
});
} else if (latestOp == "connect" && latestConnector == "walletconnect") {
web3React.activate(wcConnector);
}
}, []);
const getTruncatedAddress = (address: string | null | undefined) => {
if (address && address.startsWith("0x")) {
return address.substr(0, 4) + "..." + address.substr(address.length - 4);
}
return address;
};
const getNetwork = (chainId: number | undefined) => {
switch (chainId) {
case 1:
return "Mainnet";
case 3:
return "Ropsten";
case 4:
return "Rinkeby";
case 5:
return "Goerli";
case 42:
return "Kovan";
default:
return `unknown network ${chainId}`;
}
};
return (
<>
{!web3React.active ? (
<>
<div className="transition-opacity opacity-0 group-hover:opacity-100 space-x-2">
<Button
onClick={() => {
setLatestConnector(ConnectorNames.Injected);
setLatestOp(W3Operations.Connect);
web3React.activate(injected);
}}
color="secondary">
<img className="h-5 mr-1" src="/integrations/metamask.svg" />
MetaMask
</Button>
<Button
onClick={() => {
setLatestConnector(ConnectorNames.WalletConnect);
setLatestOp(W3Operations.Connect);
web3React.activate(wcConnector);
}}
color="secondary">
<img className="h-5 mr-1" src="/integrations/walletconnect.svg" />
WalletConnect
</Button>
</div>
</>
) : (
<>
<div className={classNames("fixed top-0 right-10 flex-col shadow dark:bg-gray-100")}>
<div className="flex-grow p-2 truncate">
<h3 className="text-green-500">{getNetwork(web3React.chainId)}</h3>
<p className="text-black mb-2">{getTruncatedAddress(web3React.account)}</p>
</div>
<div className="bg-white p-2">
<Button
onClick={() => {
setLatestOp(W3Operations.Disconnect);
web3React.deactivate();
}}
color="warn">
{t("disconnect")}
</Button>
</div>
</div>
</>
)}
</>
);
}

View File

@ -1,170 +0,0 @@
import { ExternalProvider, JsonRpcFetchFunc, Web3Provider } from "@ethersproject/providers";
import { useWeb3React, Web3ReactProvider } from "@web3-react/core";
import { InjectedConnector } from "@web3-react/injected-connector";
import { WalletConnectConnector } from "@web3-react/walletconnect-connector";
import Image from "next/image";
import { useEffect, useState } from "react";
import classNames from "@lib/classNames";
import useLocalStorage from "@lib/hooks/useLocalStorage";
import { useLocale } from "@lib/hooks/useLocale";
import { List, ListItem, ListItemTitle, ListItemText } from "@components/List";
import { ShellSubHeading } from "@components/Shell";
import Button from "@components/ui/Button";
const injected = new InjectedConnector({ supportedChainIds: [1, 3, 4, 5, 42] });
const wcConnector = new WalletConnectConnector({
infuraId: "517bf3874a6848e58f99fa38ccf9fce4",
});
const ConnectorNames = {
Injected: "injected",
WalletConnect: "walletconnect",
};
const W3Operations = {
Connect: "connect",
Disconnect: "disconnect",
};
function getLibrary(provider: ExternalProvider | JsonRpcFetchFunc) {
const library = new Web3Provider(provider);
// library.pollingInterval = 12000;
return library;
}
export default function Web3Integration() {
return (
<Web3ReactProvider getLibrary={getLibrary}>
<Web3Component />
</Web3ReactProvider>
);
}
function Web3Component() {
const { t } = useLocale();
const web3React = useWeb3React();
const [, setLoaded] = useState(false);
const [latestOp, setLatestOp] = useLocalStorage("latest_op", "");
const [latestConnector, setLatestConnector] = useLocalStorage("latest_connector", "");
// console.log(web3React);
useEffect(() => {
if (latestOp == "connect" && latestConnector == "injected") {
injected
.isAuthorized()
.then((isAuthorized) => {
setLoaded(true);
if (isAuthorized && !web3React.active && !web3React.error) {
web3React.activate(injected);
}
})
.catch(() => {
setLoaded(true);
});
} else if (latestOp == "connect" && latestConnector == "walletconnect") {
web3React.activate(wcConnector);
}
}, []);
const getTruncatedAddress = (address: string | null | undefined) => {
if (address && address.startsWith("0x")) {
return address.substr(0, 4) + "..." + address.substr(address.length - 4);
}
return address;
};
const getNetwork = (chainId: number | undefined) => {
switch (chainId) {
case 1:
return "Mainnet";
case 3:
return "Ropsten";
case 4:
return "Rinkeby";
case 5:
return "Goerli";
case 42:
return "Kovan";
default:
return `unknown network ${chainId}`;
}
};
return (
<>
<>
<ShellSubHeading
title="Wallets" //{t("connect_a_wallet")}
subtitle="Enable Web3 features: Only offer bookings for DAO members, stake and slash coins for no-shows" //{t("to_use_web_3_features")}
className="mt-10"
/>
<div className="lg:pb-8 lg:col-span-9">
<List>
{!web3React.active ? (
<>
<ListItem className={classNames("flex-col")}>
<div className={classNames("flex flex-1 space-x-2 w-full p-3 items-center")}>
<Image width={40} height={40} src="/integrations/metamask.svg" alt="MetaMask" />
<div className="flex-grow pl-2 truncate">
<ListItemTitle component="h3">MetaMask</ListItemTitle>
<ListItemText component="p">Connect to MetaMask</ListItemText>
</div>
<Button
onClick={() => {
setLatestConnector(ConnectorNames.Injected);
setLatestOp(W3Operations.Connect);
web3React.activate(injected);
}}
color="secondary">
{t("connect")}
</Button>
</div>
</ListItem>
<ListItem className={classNames("flex-col")}>
<div className={classNames("flex flex-1 space-x-2 w-full p-3 items-center")}>
<Image width={40} height={40} src="/integrations/walletconnect.svg" alt="WalletConnect" />
<div className="flex-grow pl-2 truncate">
<ListItemTitle component="h3">WalletConnect</ListItemTitle>
<ListItemText component="p">Connect via WalletConnect</ListItemText>
</div>
<Button
onClick={() => {
setLatestConnector(ConnectorNames.WalletConnect);
setLatestOp(W3Operations.Connect);
web3React.activate(wcConnector);
}}
color="secondary">
{t("connect")}
</Button>
</div>
</ListItem>
</>
) : (
<>
<ListItem className={classNames("flex-col")}>
<div className={classNames("flex flex-1 space-x-2 w-full p-3 items-center")}>
<div className="flex-grow pl-2 truncate">
<ListItemTitle component="h3">{getNetwork(web3React.chainId)}</ListItemTitle>
<ListItemText component="p">{getTruncatedAddress(web3React.account)}</ListItemText>
</div>
<Button
onClick={() => {
setLatestOp(W3Operations.Disconnect);
web3React.deactivate();
}}
color="warn">
{t("disconnect")}
</Button>
</div>
</ListItem>
</>
)}
</List>
</div>
</>
</>
);
}

View File

@ -8,10 +8,10 @@ import useTheme from "@lib/hooks/useTheme";
import prisma from "@lib/prisma";
import { inferSSRProps } from "@lib/types/inferSSRProps";
import ConnectWeb3 from "@components/ConnectWeb3";
import EventTypeDescription from "@components/eventtype/EventTypeDescription";
import { HeadSeo } from "@components/seo/head-seo";
import Avatar from "@components/ui/Avatar";
import Button from "@components/ui/Button";
import { ssrInit } from "@server/lib/ssr";
@ -51,27 +51,30 @@ export default function User(props: inferSSRProps<typeof getServerSideProps>) {
{eventTypes.map((type) => (
<div
key={type.id}
className="group relative dark:bg-neutral-900 dark:border-0 dark:hover:border-neutral-600 bg-white hover:bg-gray-50 border border-neutral-200 hover:border-brand rounded-sm">
{!web3 && (
<ArrowRightIcon className="absolute transition-opacity h-4 w-4 right-3 top-3 text-black dark:text-white opacity-0 group-hover:opacity-100" />
)}
<Link href={`/${user.username}/${type.slug}`}>
<a className="flex items-center justify-between w-full px-6 py-4">
<div>
<h2 className="font-semibold text-neutral-900 dark:text-white">{type.title}</h2>
<EventTypeDescription eventType={type} />
</div>
{/* TODO: connect to MetaMask and validate token ownership */}
{web3 && (
<div className="transition-opacity opacity-0 group-hover:opacity-100">
<Button color="secondary">
<img className="h-5 mr-1" src="/integrations/metamask.svg" />
Connect to MetaMask
</Button>
className="group relative dark:bg-neutral-900 dark:border-0 dark:hover:border-neutral-600 bg-white hover:bg-gray-50 border border-neutral-200 hover:bordergs-brand rounded-sm">
{web3 ? (
<>
<span className="flex items-center justify-between w-full px-6 py-4">
<div>
<h2 className="font-semibold text-neutral-900 dark:text-white">{type.title}</h2>
<EventTypeDescription eventType={type} />
</div>
)}
</a>
</Link>
<ConnectWeb3 />
</span>
</>
) : (
<>
<ArrowRightIcon className="absolute transition-opacity h-4 w-4 right-3 top-3 text-black dark:text-white opacity-0 group-hover:opacity-100" />
<Link href={`/${user.username}/${type.slug}`}>
<a className="flex items-center justify-between w-full px-6 py-4">
<div>
<h2 className="font-semibold text-neutral-900 dark:text-white">{type.title}</h2>
<EventTypeDescription eventType={type} />
</div>
</a>
</Link>
</>
)}
</div>
))}
</div>

View File

@ -32,7 +32,6 @@ import ConnectIntegration from "@components/integrations/ConnectIntegrations";
import DisconnectIntegration from "@components/integrations/DisconnectIntegration";
import IntegrationListItem from "@components/integrations/IntegrationListItem";
import SubHeadingTitleWithConnections from "@components/integrations/SubHeadingTitleWithConnections";
import Web3Integration from "@components/integrations/Web3Integration";
import { Alert } from "@components/ui/Alert";
import Button from "@components/ui/Button";
import Switch from "@components/ui/Switch";
@ -533,7 +532,6 @@ export default function IntegrationsPage() {
<CalendarListContainer />
<WebhookListContainer />
<IframeEmbedContainer />
<Web3Integration />
</ClientSuspense>
</Shell>
);