Compare commits
No commits in common. "3f8d8f632d72b9bae5d716fc0faec08091e9fff5" and "e80e2c3907921f64582a4eb22d6d38c7e0de54f2" have entirely different histories.
3f8d8f632d
...
e80e2c3907
@ -40,7 +40,6 @@
|
|||||||
"@web3modal/react": "^2.0.0-beta.8",
|
"@web3modal/react": "^2.0.0-beta.8",
|
||||||
"airdrop-artifact": "file:./artifacts/contracts/Airdrop.sol/",
|
"airdrop-artifact": "file:./artifacts/contracts/Airdrop.sol/",
|
||||||
"create-react-app": "^5.0.1",
|
"create-react-app": "^5.0.1",
|
||||||
"eslint": "^8.29.0",
|
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
53
src/App.css
53
src/App.css
@ -1,54 +1,18 @@
|
|||||||
html {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
height: 100%;
|
|
||||||
font-family: Lato, "Helvetica Neue", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#root {
|
|
||||||
height: 100%;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App {
|
.App {
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 20% auto;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
grid-column: 1;
|
|
||||||
background-color: #5a6066;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-right: #8b8b8a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.connectorButton {
|
.App-logo {
|
||||||
|
height: 40vmin;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
main.main {
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
background-color: black;
|
.App-logo {
|
||||||
grid-column: 2;
|
animation: App-logo-spin infinite 20s linear;
|
||||||
padding: 10px;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.airdropPanel {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 30% auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.airdropSettings {
|
|
||||||
grid-column: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.addressList {
|
|
||||||
grid-column: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.App-header {
|
.App-header {
|
||||||
background-color: #282c34;
|
background-color: #282c34;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
@ -74,5 +38,6 @@ main.main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.addressError {
|
div.addressError {
|
||||||
background-color: #c52121;
|
background-color: #ff9191;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
56
src/App.tsx
56
src/App.tsx
@ -1,11 +1,12 @@
|
|||||||
import React, {useState} from "react";
|
import React, {useState} from 'react';
|
||||||
import "./App.css";
|
import logo from './logo.svg';
|
||||||
|
import './App.css';
|
||||||
|
|
||||||
import Web3 from "web3";
|
import Web3 from 'web3';
|
||||||
import { WagmiConfig, createClient, configureChains, mainnet, useConnect, useAccount, useDisconnect } from "wagmi"
|
import { WagmiConfig, createClient, configureChains, mainnet, useConnect, useAccount, useDisconnect } from 'wagmi'
|
||||||
|
|
||||||
import { MetaMaskConnector } from "wagmi/connectors/metaMask"
|
import { MetaMaskConnector } from 'wagmi/connectors/metaMask'
|
||||||
import { publicProvider } from "wagmi/providers/public"
|
import { publicProvider } from 'wagmi/providers/public'
|
||||||
|
|
||||||
const web3 = new Web3(Web3.givenProvider);
|
const web3 = new Web3(Web3.givenProvider);
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ const wagmiClient = createClient({
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
function Connector() {
|
function Profile() {
|
||||||
const { connect, connectors, error, isLoading, pendingConnector } =
|
const { connect, connectors, error, isLoading, pendingConnector } =
|
||||||
useConnect()
|
useConnect()
|
||||||
|
|
||||||
@ -42,28 +43,26 @@ function Connector() {
|
|||||||
const connectorName = connector?.name || "unknown connector";
|
const connectorName = connector?.name || "unknown connector";
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>Connected to {connectorName}!</div>
|
<div>Connected to {connectorName} address: {address}</div>
|
||||||
<div>Connected account: <b>{address}</b></div>
|
|
||||||
<button onClick={(_evt) => disconnect() }>Disconnect</button>
|
<button onClick={(_evt) => disconnect() }>Disconnect</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="connector">
|
<div>
|
||||||
<div>Not currently connected to a wallet. Connect to...</div>
|
<div>Connect to Airdrop App</div>
|
||||||
{connectors.map((connector) => (
|
{connectors.map((connector) => (
|
||||||
<button
|
<button
|
||||||
className="connectorButton"
|
|
||||||
disabled={!connector.ready}
|
disabled={!connector.ready}
|
||||||
key={connector.id}
|
key={connector.id}
|
||||||
onClick={() => connect({ connector })}
|
onClick={() => connect({ connector })}
|
||||||
>
|
>
|
||||||
{connector.name}
|
{connector.name}
|
||||||
{!connector.ready && " (unsupported)"}
|
{!connector.ready && ' (unsupported)'}
|
||||||
{isLoading &&
|
{isLoading &&
|
||||||
connector.id === pendingConnector?.id &&
|
connector.id === pendingConnector?.id &&
|
||||||
" (connecting)"}
|
' (connecting)'}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
@ -75,8 +74,6 @@ function Connector() {
|
|||||||
|
|
||||||
|
|
||||||
interface AddressesProps {
|
interface AddressesProps {
|
||||||
airdropButtonDisabled: boolean;
|
|
||||||
performAirdrop: any;
|
|
||||||
addressList: string[];
|
addressList: string[];
|
||||||
setAddressListFn: any;
|
setAddressListFn: any;
|
||||||
numTokens: number;
|
numTokens: number;
|
||||||
@ -86,7 +83,7 @@ interface AddressesProps {
|
|||||||
function Addresses(props: AddressesProps) {
|
function Addresses(props: AddressesProps) {
|
||||||
const [inputState, setInputState] = useState("");
|
const [inputState, setInputState] = useState("");
|
||||||
const [errorText, setErrorText] = useState("");
|
const [errorText, setErrorText] = useState("");
|
||||||
const { airdropButtonDisabled, performAirdrop, setAddressListFn, addressList, numTokens, setNumTokens } = props;
|
const { setAddressListFn, addressList, numTokens, setNumTokens } = props;
|
||||||
|
|
||||||
const save = () => {
|
const save = () => {
|
||||||
if (!web3.utils.isAddress(inputState)) {
|
if (!web3.utils.isAddress(inputState)) {
|
||||||
@ -113,21 +110,17 @@ function Addresses(props: AddressesProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="airdropSettings">
|
<div>
|
||||||
<p>Add an address to airdrop to:</p>
|
|
||||||
<div>
|
<div>
|
||||||
<input id="address" value={inputState} onChange={ (evt) => setInputState(evt.target.value) } ></input>
|
<input id="address" value={inputState} onChange={ (evt) => setInputState(evt.target.value) } ></input>
|
||||||
<div className="addressError">{errorText}</div>
|
<div className="addressError">{errorText}</div>
|
||||||
<button onClick={save}>Add address</button>
|
<button onClick={save}>Add address</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>Number of tokens:</div>
|
Number of tokens:
|
||||||
<input type="numeric" value={num} onChange={ (evt) => setNumTokens(parseInt(evt.target.value)) }></input>
|
<input type="numeric" value={num} onChange={ (evt) => setNumTokens(parseInt(evt.target.value)) }></input>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<button disabled={airdropButtonDisabled} onClick={performAirdrop} >Perform Airdrop!</button>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +134,7 @@ function AddressList({addressList}: AddressListProps) {
|
|||||||
<p>No addresses specified yet</p> :
|
<p>No addresses specified yet</p> :
|
||||||
addressList.map((addr: string) => <div key={addr} className="addressItem">{addr}</div>);
|
addressList.map((addr: string) => <div key={addr} className="addressItem">{addr}</div>);
|
||||||
return (
|
return (
|
||||||
<div className="addressList">
|
<div>
|
||||||
<h2>Addresses to airdrop to: </h2>
|
<h2>Addresses to airdrop to: </h2>
|
||||||
{ addresses }
|
{ addresses }
|
||||||
</div>
|
</div>
|
||||||
@ -185,17 +178,14 @@ function App() {
|
|||||||
return (
|
return (
|
||||||
<WagmiConfig client={wagmiClient}>
|
<WagmiConfig client={wagmiClient}>
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<div className="sidebar">
|
<Profile/>
|
||||||
|
|
||||||
<h1>Airdrop App</h1>
|
<h1>Airdrop App</h1>
|
||||||
<Connector/>
|
|
||||||
</div>
|
<p>Add an address to airdrop to:</p>
|
||||||
<main className="main">
|
<Addresses addressList={addressList} setAddressListFn={setAddressList} numTokens={numTokens} setNumTokens={setNumTokens}/>
|
||||||
<p>Enter your airdropping settings:</p>
|
<button disabled={airdropButtonDisabled} onClick={performAirdrop} >Perform Airdrop!</button>
|
||||||
<section className="airdropPanel">
|
|
||||||
<Addresses airdropButtonDisabled={airdropButtonDisabled} performAirdrop={() => performAirdrop()} addressList={addressList} setAddressListFn={setAddressList} numTokens={numTokens} setNumTokens={setNumTokens}/>
|
|
||||||
<AddressList addressList={addressList} />
|
<AddressList addressList={addressList} />
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</WagmiConfig>
|
</WagmiConfig>
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -6649,7 +6649,7 @@ eslint-webpack-plugin@^3.1.1:
|
|||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
schema-utils "^4.0.0"
|
schema-utils "^4.0.0"
|
||||||
|
|
||||||
eslint@^8.29.0, eslint@^8.3.0:
|
eslint@^8.3.0:
|
||||||
version "8.29.0"
|
version "8.29.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.29.0.tgz#d74a88a20fb44d59c51851625bc4ee8d0ec43f87"
|
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.29.0.tgz#d74a88a20fb44d59c51851625bc4ee8d0ec43f87"
|
||||||
integrity sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==
|
integrity sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==
|
||||||
@ -6923,7 +6923,15 @@ ethereum-cryptography@^1.0.3:
|
|||||||
"@scure/bip32" "1.1.0"
|
"@scure/bip32" "1.1.0"
|
||||||
"@scure/bip39" "1.1.0"
|
"@scure/bip39" "1.1.0"
|
||||||
|
|
||||||
ethereumjs-abi@^0.6.8, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git":
|
ethereumjs-abi@^0.6.8:
|
||||||
|
version "0.6.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae"
|
||||||
|
integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==
|
||||||
|
dependencies:
|
||||||
|
bn.js "^4.11.8"
|
||||||
|
ethereumjs-util "^6.0.0"
|
||||||
|
|
||||||
|
"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git":
|
||||||
version "0.6.8"
|
version "0.6.8"
|
||||||
resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0"
|
resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
Reference in New Issue
Block a user