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

BIN
.github/demo-address-connected.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

24
.gitignore vendored Normal file
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
README.md Normal file
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
package.json Normal file
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"
]
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

88
public/index.html Normal file
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>

BIN
public/logo192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
public/logo512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

25
public/manifest.json Normal file
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"
}

BIN
public/metaIMG.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

3
public/robots.txt Normal file
View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

16
src/App.js Normal file
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;

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;

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
src/components/Footer.js Normal file
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
src/components/Navbar.js Normal file
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
src/index.js Normal file
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
src/styles/scroll.css Normal file
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
src/theme.js Normal file
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
yarn.lock Normal file

File diff suppressed because it is too large Load Diff