init: impersonator functional

This commit is contained in:
CodinMaster
2021-08-22 03:44:44 +05:30
commit 4852cf8ee7
20 changed files with 13403 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

+24
View File
@@ -0,0 +1,24 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
.env
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+15
View File
@@ -0,0 +1,15 @@
# 🎭 Impersonator 🕵️‍♂️
### Login into DApps by impersonating any Ethereum address via WalletConnect! <br />
<hr />
## Website:
**[https://apoorvlathey.com/impersonator/](https://apoorvlathey.com/impersonator/)**
## Screenshots:
![demo-by-address](./.github/demo-address-connected.png)
(PS: Users won't be able to transact (obviously) as no private keys are being used here)
+50
View File
@@ -0,0 +1,50 @@
{
"name": "impersonator",
"version": "0.1.0",
"homepage": ".",
"private": true,
"dependencies": {
"@chakra-ui/icons": "^1.0.14",
"@chakra-ui/react": "^1.6.5",
"@emotion/react": "^11",
"@emotion/styled": "^11",
"@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-brands-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.15",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@walletconnect/client": "^1.6.2",
"ethereum-checksum-address": "^0.0.6",
"framer-motion": "^4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"react-simple-code-editor": "^0.11.0",
"web-vitals": "^1.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

+88
View File
@@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script
async
src="https://www.googletagmanager.com/gtag/js?id=UA-69758040-5"
></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "UA-69758040-5");
</script>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<!-- Primary Meta Tags -->
<title>Impersonator</title>
<meta name="title" content="Impersonator" />
<meta
name="description"
content="Impersonate any Ethereum Account and Login into DApps via WalletConnect!"
/>
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://apoorvlathey.com/impersonator/" />
<meta property="og:title" content="Impersonator" />
<meta
property="og:description"
content="Impersonate any Ethereum Account and Login into DApps via WalletConnect!"
/>
<meta
property="og:image"
content="https://apoorvlathey.com/impersonator/metaIMG.PNG"
/>
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta
property="twitter:url"
content="https://apoorvlathey.com/impersonator/"
/>
<meta property="twitter:title" content="Impersonator" />
<meta
property="twitter:description"
content="Impersonate any Ethereum Account and Login into DApps via WalletConnect!"
/>
<meta
property="twitter:image"
content="https://apoorvlathey.com/impersonator/metaIMG.PNG"
/>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+25
View File
@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

+3
View File
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
+16
View File
@@ -0,0 +1,16 @@
import React from "react";
import Body from "./components/Body/index";
import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
function App() {
return (
<div>
<Navbar />
<Body />
<Footer />
</div>
);
}
export default App;
+250
View File
@@ -0,0 +1,250 @@
import React, { useState, useEffect } from "react";
import {
Container,
Input,
FormControl,
useColorMode,
FormLabel,
Button,
Box,
Avatar,
Text,
Link,
VStack,
Spacer,
Select,
} from "@chakra-ui/react";
import WalletConnect from "@walletconnect/client";
import networkInfo from "./networkInfo";
function Body() {
const { colorMode } = useColorMode();
const bgColor = { light: "white", dark: "gray.700" };
const [address, setAddress] = useState("");
const [uri, setUri] = useState("");
const [chainIdIndex, setChainIdIndex] = useState(0);
const [connector, setConnector] = useState();
const [peerMeta, setPeerMeta] = useState();
const [isConnected, setIsConnected] = useState(false);
useEffect(() => {
const session = getCachedSession();
if (session) {
let _connector = new WalletConnect({ session });
setConnector(_connector);
setAddress(_connector.accounts[0]);
setUri(_connector.uri);
setPeerMeta(_connector.peerMeta);
setIsConnected(true);
const chainId = _connector.chainId.chainID;
for (let i = 0; i < networkInfo.length; i++) {
if (networkInfo[i].chainID == chainId) {
setChainIdIndex(i);
break;
}
}
}
}, []);
useEffect(() => {
if (connector) {
subscribeToEvents();
}
}, [connector]);
const getCachedSession = () => {
const local = localStorage ? localStorage.getItem("walletconnect") : null;
let session = null;
if (local) {
try {
session = JSON.parse(local);
} catch (error) {
throw error;
}
}
return session;
};
const initWalletConnect = async () => {
try {
let _connector = new WalletConnect({ uri });
if (!_connector.connected) {
await _connector.createSession();
}
setConnector(_connector);
setUri(_connector.uri);
} catch (err) {
throw err;
}
};
const subscribeToEvents = () => {
console.log("ACTION", "subscribeToEvents");
if (connector) {
connector.on("session_request", (error, payload) => {
console.log("EVENT", "session_request");
if (error) {
throw error;
}
console.log("SESSION_REQUEST", payload.params);
setPeerMeta(payload.params[0].peerMeta);
});
connector.on("session_update", (error) => {
console.log("EVENT", "session_update");
if (error) {
throw error;
}
});
connector.on("call_request", async (error, payload) => {
console.log("EVENT", "call_request", "method", payload.method);
console.log("EVENT", "call_request", "params", payload.params);
// if (error) {
// throw error;
// }
// await getAppConfig().rpcEngine.router(payload, this.state, this.bindedSetState);
});
connector.on("connect", (error, payload) => {
console.log("EVENT", "connect");
if (error) {
throw error;
}
// this.setState({ connected: true });
});
connector.on("disconnect", (error, payload) => {
console.log("EVENT", "disconnect");
if (error) {
throw error;
}
// this.resetApp();
});
}
};
const approveSession = () => {
console.log("ACTION", "approveSession");
if (connector) {
let chainId = networkInfo[chainIdIndex].chainID;
if (!chainId) {
chainId = 1; // default to ETH Mainnet if no network selected
}
connector.approveSession({ chainId, accounts: [address] });
setIsConnected(true);
}
};
const rejectSession = () => {
console.log("ACTION", "rejectSession");
if (connector) {
connector.rejectSession();
setPeerMeta(null);
}
};
const killSession = () => {
console.log("ACTION", "killSession");
if (connector) {
connector.killSession();
setPeerMeta(null);
setIsConnected(false);
}
};
return (
<Container my="16" minW={["0", "0", "2xl", "2xl"]}>
<FormControl>
<FormLabel>Enter Address to Impersonate</FormLabel>
<Input
placeholder="Address"
aria-label="address"
value={address}
onChange={(e) => setAddress(e.target.value)}
bg={bgColor[colorMode]}
isDisabled={isConnected}
/>
</FormControl>
<FormControl my={4}>
<FormLabel>WalletConnect URI</FormLabel>
<Input
placeholder="wc:xyz123"
aria-label="uri"
value={uri}
onChange={(e) => setUri(e.target.value)}
bg={bgColor[colorMode]}
isDisabled={isConnected}
/>
</FormControl>
<Select
mb={4}
placeholder="Select Network"
variant="filled"
_hover={{ cursor: "pointer" }}
value={chainIdIndex}
onChange={(e) => {
setChainIdIndex(e.target.value);
}}
isDisabled={isConnected}
>
{networkInfo.map((network, i) => (
<option value={i} key={i}>
{network.name}
</option>
))}
</Select>
<Button onClick={initWalletConnect} isDisabled={isConnected}>
Connect
</Button>
{peerMeta && (
<>
<Box mt={4} fontSize={24} fontWeight="semibold">
{isConnected ? "✅ Connected To:" : "⚠ Allow to Connect"}
</Box>
<VStack>
<Avatar src={peerMeta.icons[0]} alt={peerMeta.name} />
<Text fontWeight="bold">{peerMeta.name}</Text>
<Text fontSize="sm">{peerMeta.description}</Text>
<Link href={peerMeta.url} textDecor="underline">
{peerMeta.url}
</Link>
{!isConnected && (
<Box pt={6}>
<Button onClick={approveSession} mr={10}>
Approve ✔
</Button>
<Button onClick={rejectSession}>Reject ❌</Button>
</Box>
)}
{isConnected && (
<Box pt={6}>
<Button onClick={killSession}>Disconnect ☠</Button>
</Box>
)}
</VStack>
</>
)}
</Container>
);
}
export default Body;
+48
View File
@@ -0,0 +1,48 @@
const networkInfo = [
{
chainID: 1,
name: "Ethereum Mainnet",
},
{
chainID: 137,
name: "Polygon",
},
{
chainID: 56,
name: "Binance Smart Chain",
},
{
chainID: 10,
name: "Optimistic Ethereum",
},
{
chainID: 250,
name: "Fantom Opera",
},
{
chainID: 43114,
name: "Avalanche",
},
{
chainID: 100,
name: "xDAI",
},
{
chainID: 42,
name: "Kovan Testnet",
},
{
chainID: 3,
name: "Ropsten Testnet",
},
{
chainID: 4,
name: "Rinkeby Testnet",
},
{
chainID: 5,
name: "Goerli Testnet",
},
];
export default networkInfo;
+59
View File
@@ -0,0 +1,59 @@
import React from "react";
import {
useColorMode,
Flex,
HStack,
VStack,
Heading,
Spacer,
Link,
Text,
} from "@chakra-ui/react";
import { ExternalLinkIcon } from "@chakra-ui/icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faGithub,
faLinkedin,
faTwitter,
} from "@fortawesome/free-brands-svg-icons";
const Social = ({ icon, link }) => {
return (
<Link href={link} isExternal>
<FontAwesomeIcon icon={icon} size="lg" />
</Link>
);
};
function Footer() {
const { colorMode } = useColorMode();
const underlineColor = { light: "gray.500", dark: "gray.400" };
return (
<Flex py="4" borderTop="2px" borderTopColor={underlineColor[colorMode]}>
<Spacer flex="1" />
<VStack>
<Heading size="md">
Built by:{" "}
<Link href="https://apoorvlathey.com/" isExternal>
<Text decoration="underline" display="inline">
Apoorv Lathey
</Text>{" "}
<ExternalLinkIcon />
</Link>
</Heading>
<HStack spacing={8} mt={10}>
<Social icon={faTwitter} link="https://twitter.com/apoorvlathey" />
<Social icon={faGithub} link="https://github.com/CodinMaster" />
<Social
icon={faLinkedin}
link="https://www.linkedin.com/in/apoorvlathey/"
/>
</HStack>
</VStack>
<Spacer flex="1" />
</Flex>
);
}
export default Footer;
+29
View File
@@ -0,0 +1,29 @@
import React from "react";
import { Button, useColorMode, Flex, Heading, Spacer } from "@chakra-ui/react";
import { SunIcon, MoonIcon } from "@chakra-ui/icons";
function Navbar() {
const { colorMode, toggleColorMode } = useColorMode();
const underlineColor = { light: "gray.500", dark: "gray.400" };
return (
<Flex
py="4"
px={["2", "4", "10", "10"]}
borderBottom="2px"
borderBottomColor={underlineColor[colorMode]}
>
<Spacer flex="1" />
<Heading maxW={["302px", "4xl", "4xl", "4xl"]}>
🎭 Impersonator 🕵️
</Heading>
<Flex flex="1" justifyContent="flex-end">
<Button onClick={toggleColorMode} rounded="full" h="40px" w="40px">
{colorMode === "light" ? <MoonIcon /> : <SunIcon />}
</Button>
</Flex>
</Flex>
);
}
export default Navbar;
+12
View File
@@ -0,0 +1,12 @@
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { ChakraProvider } from "@chakra-ui/react";
import theme from "./theme";
ReactDOM.render(
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>,
document.getElementById("root")
);
+18
View File
@@ -0,0 +1,18 @@
.scroll::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
border-radius: 10px;
background-color: rgba(0, 0, 0, 0);
}
.scroll::-webkit-scrollbar {
width: 12px;
background-color: rgba(0, 0, 0, 0);
}
.scroll::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background-color: #2a8ed6;
}
+10
View File
@@ -0,0 +1,10 @@
import { extendTheme } from "@chakra-ui/react";
const config = {
initialColorMode: "dark",
useSystemColorMode: false,
};
const theme = extendTheme({ config });
export default theme;
+12756
View File
File diff suppressed because it is too large Load Diff