Skip to content

Commit

Permalink
solana faucet UI
Browse files Browse the repository at this point in the history
solana faucet UI
  • Loading branch information
kranthicodes committed Jan 16, 2022
1 parent 9cf4013 commit ffad334
Show file tree
Hide file tree
Showing 14 changed files with 4,322 additions and 61 deletions.
Binary file added .DS_Store
Binary file not shown.
2 changes: 0 additions & 2 deletions .gitattributes

This file was deleted.

49 changes: 49 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="title" content="Solana Faucet" />
<meta
name="description"
content="Solana Faucet | Airdrop SOL to your devnet!"
/>

<!-- Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://kranthicodes.com" />
<meta property="og:title" content="Solana Faucet" />
<meta
property="og:description"
content="Solana Faucet | Airdrop SOL to your devnet!"
/>
<meta
property="og:image"
content="/solmeta.png"
/>

<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content="https://kranthicodes.com/" />
<meta property="twitter:title" content="Solana Faucet" />
<meta
property="twitter:description"
content="Solana Faucet | Airdrop SOL to your devnet!"
/>
<meta
property="twitter:image"
content="/solmeta.png"
/>
<title>Solana Faucet</title>
<script>
if (global === undefined) {
var global = window;
}
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
48 changes: 0 additions & 48 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,49 +1 @@
const {
Connection,
PublicKey,
clusterApiUrl,
Keypair,
LAMPORTS_PER_SOL,
Transaction,
Account,
} = require("@solana/web3.js");

const newPair = new Keypair();
const publicKey = new PublicKey(newPair._keypair.publicKey).toString();
const secretKey = newPair._keypair.secretKey;

const getWalletBalance = async () => {
try {
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const myWallet = await Keypair.fromSecretKey(secretKey);
const walletBalance = await connection.getBalance(
new PublicKey(myWallet.publicKey)
);
console.log(`=> For wallet address ${publicKey}`);
console.log(
` Wallet balance: ${parseInt(walletBalance) / LAMPORTS_PER_SOL}SOL`
);
} catch (err) {
console.log(err);
}
};
const airDropSol = async () => {
try {
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const walletKeyPair = await Keypair.fromSecretKey(secretKey);
console.log(`-- Airdropping 2 SOL --`);
const fromAirDropSignature = await connection.requestAirdrop(
new PublicKey(walletKeyPair.publicKey),
2 * LAMPORTS_PER_SOL
);
await connection.confirmTransaction(fromAirDropSignature);
} catch (err) {
console.log(err);
}
};
const driverFunction = async () => {
await getWalletBalance();
await airDropSol();
await getWalletBalance();
};
driverFunction();
33 changes: 25 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
{
"name": "sol-airdrop",
"name": "solana-airdrop",
"description": "Airdrop site for solana",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"@chakra-ui/icons": "^1.1.1",
"@chakra-ui/react": "^1.7.3",
"@emotion/react": "^11",
"@emotion/styled": "^11",
"@solana/web3.js": "^1.31.0",
"formik": "^2.2.9",
"framer-motion": "^4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"yup": "^0.32.11"
},
"devDependencies": {
"@types/react": "^17.0.33",
"@types/react-dom": "^17.0.10",
"@vitejs/plugin-react": "^1.0.7",
"typescript": "^4.4.4",
"vite": "^2.7.2"
},
"repository": {
"type": "git",
Expand All @@ -16,8 +36,5 @@
"bugs": {
"url": "https://github.com/kranthicodes/sol-airdrop/issues"
},
"homepage": "https://github.com/kranthicodes/sol-airdrop#readme",
"dependencies": {
"@solana/web3.js": "^1.31.0"
}
"homepage": "https://github.com/kranthicodes/sol-airdrop#readme"
}
Binary file added public/solmeta.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Box, ChakraProvider, Flex, Heading } from "@chakra-ui/react";
import React, { Dispatch, SetStateAction } from "react";
import AirDrop from "./components/AirDrop";


export default function App() {

return (
<ChakraProvider>
<Flex
h="100vh"
display="flex"
w="100vw"
bg="radial-gradient(ellipse farthest-side at 76% 77%, rgba(245, 228, 212, 0.25) 4%, rgba(255, 255, 255, 0) calc(4% + 1px)), radial-gradient(circle at 76% 40%, #fef6ec 4%, rgba(255, 255, 255, 0) 4.18%), linear-gradient(135deg, #ff0000 0%, #000036 100%), radial-gradient(ellipse at 28% 0%, #ffcfac 0%, rgba(98, 149, 144, 0.5) 100%), linear-gradient(180deg, #cd6e8a 0%, #f5eab0 69%, #d6c8a2 70%, #a2758d 100%); background-blend-mode: normal, normal, screen, overlay, normal"
direction="column"
justify="center"
align="center"
>
<Box mb={8}>
<Heading as="h1" color="#0d004d" fontSize="3rem">
Solana Airdrop App
</Heading>
</Box>
<AirDrop />
</Flex>
</ChakraProvider>
);
}
145 changes: 145 additions & 0 deletions src/components/AirDrop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import {
Button,
Box,
Input,
FormControl,
FormErrorMessage,
Alert,
AlertIcon,
AlertTitle,
AlertDescription,
} from "@chakra-ui/react";
import { Form, Formik, Field } from "formik";
import React from "react";
import * as yup from "yup";
import {
PublicKey,
Connection,
clusterApiUrl,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";
const ERROR_INIT_STATE = {
walletAddress: "",
solValue: "",
};
type FormTypes = {
walletAddress: string;
solValue: number | string;
};
export default function AirDrop() {
const [status, setStatus] = React.useState<
"info" | "success" | "error" | "warning"
>("info");
const airDropSubmitHandler = async (values: FormTypes, actions) => {
const { walletAddress, solValue } = values;
try {
setStatus("warning");
const publicKey = new PublicKey(walletAddress);
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const fromAirDropSignature = await connection.requestAirdrop(
publicKey,
+solValue * LAMPORTS_PER_SOL
);
await connection.confirmTransaction(fromAirDropSignature);
setStatus("success");
actions.resetForm();
} catch (error) {
if (error?.message === "Invalid public key input") {
actions.setErrors({ walletAddress: "Invalid Solana Wallet Address." });
} else {
actions.setErrors({ walletAddress: error?.message || "Error" });
}
setStatus("error");
}
setTimeout(() => {
setStatus("info");
}, 6000);
};
return (
<Formik
initialValues={ERROR_INIT_STATE}
validationSchema={airdropValidator}
onSubmit={airDropSubmitHandler}
>
{({ handleSubmit }) => (
<Form onSubmit={handleSubmit}>
{status !== "info" ? (
<Alert status={status}>
<AlertIcon />
{status === "success"
? "Airdrop Successful!"
: status === "error"
? "Airdrop failed!"
: "Airdropping..."}
</Alert>
) : null}
<Box mt={4} display="flex" flexDirection="column" alignItems="center">
<Field
name="walletAddress"
render={({ field, form: { errors, touched } }) => {
return (
<FormControl
isInvalid={errors?.walletAddress && touched?.walletAddress}
>
<Input
{...field}
w="24rem"
placeholder="Solana Wallet Address"
variant="filled"
css={{ "::placeholder": { color: "#09101D" } }}
type="text"
/>
<FormErrorMessage>{errors?.walletAddress}</FormErrorMessage>
</FormControl>
);
}}
/>
<Field
name="solValue"
render={({ field, form: { errors, touched } }) => {
return (
<FormControl
isInvalid={errors?.solValue && touched?.solValue}
>
<Input
{...field}
w="24rem"
placeholder="Example: 1 SOL"
mt={2}
variant="filled"
css={{ "::placeholder": { color: "#09101D" } }}
type="number"
/>
<FormErrorMessage>{errors?.solValue}</FormErrorMessage>
</FormControl>
);
}}
/>

<Button
type="submit"
borderRadius="4px"
mt="4"
p="12px 40px"
color="#fff"
_hover={{ bgColor: "#0d004d" }}
bgColor="#0d004d"
h="44px"
fontSize="1.1rem"
letterSpacing="1px"
>
Send
</Button>
</Box>
</Form>
)}
</Formik>
);
}
const airdropValidator = yup.object().shape({
walletAddress: yup.string().required("Wallet Address is required."),
solValue: yup
.number()
.max(2, "Max SOL Airdrop per Txn is 2.")
.required("SOL Value is required"),
});
3 changes: 3 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare interface Window {
solana: any;
}
4 changes: 4 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(<App />,document.getElementById('root'))
20 changes: 20 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ESNext",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"module": "ESNext",
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"baseUrl": ".",
"types": ["node"]
},
"include": ["src"],
}
7 changes: 7 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()]
})
Loading

0 comments on commit ffad334

Please sign in to comment.