Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): testnet faucet page with recaptcha #344

Merged
merged 55 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
a9a6451
feat(ui-ux): testnet faucet page
chloezxyy Nov 2, 2023
bbaa14d
feat(ui-ux): add recaptcha v2
chloezxyy Nov 3, 2023
903a20e
fix(ui-ux): hide /faucet navigation and page if not in Testnet env
chloezxyy Nov 3, 2023
86e53db
feat(server): nestjs setup
lykalabrada Nov 6, 2023
7abc99f
remove nvmrc
lykalabrada Nov 6, 2023
e089e23
fix(ui-ux): evmAddress input and captcha validation
chloezxyy Nov 6, 2023
ae3a8e3
code refactor
chloezxyy Nov 7, 2023
c60bf7d
Merge branch 'main' into chloe/testnet-faucet-ui
chloezxyy Nov 7, 2023
77f546f
code cleanup
chloezxyy Nov 7, 2023
dced78a
Merge branch 'chloe/testnet-faucet-ui' of https://github.com/Birthday…
chloezxyy Nov 7, 2023
23175ef
feature(api): added api for faucet to allocate fund to user (#346)
fullstackninja864 Nov 8, 2023
41e8aa7
fix lint
Nov 8, 2023
207daac
fix typo
Nov 8, 2023
4081d0a
fix lint
Nov 8, 2023
0f8186c
fix ci
Nov 8, 2023
e356202
fix ci
Nov 8, 2023
ebced18
fix ci
Nov 8, 2023
9d56e3c
fix ci
Nov 8, 2023
d0d75e6
fix ci
Nov 8, 2023
b4b0b41
fix ci
Nov 8, 2023
caa2c47
fix ci
Nov 8, 2023
90111e1
fix ci
Nov 8, 2023
d1f4d05
merged lyka/api-setup branch
nattadex Nov 8, 2023
532d82b
moved faucet dir to apps/web
nattadex Nov 8, 2023
e70ff48
changed to getRpcUrl instead of getBaseUrl
nattadex Nov 8, 2023
1588039
api testing
nattadex Nov 9, 2023
f763bff
fixed the cors issue
nattadex Nov 9, 2023
098866a
removed comment
nattadex Nov 9, 2023
65d90ad
print out transaction hash or error
nattadex Nov 9, 2023
1b1327a
merge main
nattadex Nov 9, 2023
9fcd32d
ran prettier
nattadex Nov 9, 2023
b50c1c5
removed unused code
nattadex Nov 9, 2023
baeef45
fixed lint issues
nattadex Nov 9, 2023
792ab66
Merge branch 'main' into chloe/testnet-faucet-ui
chloezxyy Nov 17, 2023
659439d
add import { NestFactory } from '@nestjs/core';
chloezxyy Nov 17, 2023
7373182
fix import problems
chloezxyy Nov 17, 2023
912f623
feat: use user input wallet address
chloezxyy Nov 17, 2023
beb6078
fix: use current connection
chloezxyy Nov 20, 2023
ef41a8f
fix: cors
chloezxyy Nov 20, 2023
4f4832d
fix: use MetascanServerApp
chloezxyy Nov 20, 2023
e9592dd
fix: update allowedHeaders MetascanServerApp
chloezxyy Nov 21, 2023
6425835
feat(server): recaptcha guard on faucet route
chloezxyy Nov 22, 2023
3e1abe8
feat(ui-ux): handle recaptcha validation when sending funds
chloezxyy Nov 22, 2023
c245272
add recaptcha public site key in /web/.env file
chloezxyy Nov 22, 2023
e35a18a
fix format
chloezxyy Nov 22, 2023
078b434
fix(server): private validateRecaptcha guard method
chloezxyy Nov 23, 2023
0875318
Merge branch 'main' into chloe/testnet-faucet-ui
chloezxyy Nov 24, 2023
a0e87eb
update comments
chloezxyy Nov 24, 2023
39585f8
feat(ui-ux): added ux for faucet (#357)
nattadex Nov 24, 2023
2b07d1b
fixed package.json
fullstackninja864 Nov 24, 2023
c74ce55
updated ethers version
fullstackninja864 Nov 24, 2023
4c19bdc
UI fixes
fullstackninja864 Nov 24, 2023
671ccad
fix lint
fullstackninja864 Nov 24, 2023
f34bdcc
hide faucet page
fullstackninja864 Nov 24, 2023
d0f59dc
remove log
fullstackninja864 Nov 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
NEXT_PUBLIC_RPC_URL_MAINNET="https://blockscout.mainnet.ocean.jellyfishsdk.com"
NEXT_PUBLIC_RPC_URL_TESTNET="https://blockscout.testnet.ocean.jellyfishsdk.com"
NEXT_PUBLIC_RPC_URL_CHANGI="https://blockscout.changi.ocean.jellyfishsdk.com"
NEXT_PUBLIC_RPC_URL_CHANGI="https://blockscout.changi.ocean.jellyfishsdk.com"

pierregee marked this conversation as resolved.
Show resolved Hide resolved
NEXT_PUBLIC_RECAPTCHA_SITE_KEY="6LeeoO8oAAAAALPSYZr1_Itr9bBzzQBVDjgjMT0-"
4 changes: 2 additions & 2 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ const securityHeaders = [
value:
`default-src 'none';` +
`base-uri 'self';` +
`child-src 'self' app.netlify.com;` +
`child-src 'self' app.netlify.com https://www.google.com;` +
`form-action 'none';` +
`frame-ancestors 'none';` +
`img-src 'self' images.prismic.io data:;` +
`media-src 'self';` +
`object-src 'none';` +
`script-src 'self' app.netlify.com netlify-cdp-loader.netlify.app ${
`script-src 'self' app.netlify.com netlify-cdp-loader.netlify.app https://www.google.com/recaptcha/ https://www.gstatic.com ${
process.env.NODE_ENV === "development" ? `'unsafe-eval'` : ""
};` +
`style-src 'self' fonts.googleapis.com 'unsafe-inline';` +
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"lodash": "^4.17.21",
"react-code-blocks": "0.0.9-0",
"react-dropzone": "^14.2.3",
"react-google-recaptcha": "^3.1.0",
"react-qr-code": "^2.0.11",
"recharts": "^2.7.1",
"viem": "^1.1.0",
Expand All @@ -40,6 +41,7 @@
"@tailwindcss/line-clamp": "^0.4.4",
"@testing-library/cypress": "^9.0.0",
"@types/node": "18.16.3",
"@types/react-google-recaptcha": "^2.1.7",
"@types/recharts": "^1.8.24",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.6.0",
Expand Down
37 changes: 34 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions src/hooks/useMenuNavigationHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { NetworkConnection } from "@contexts/Environment";
import { useNetwork } from "@contexts/NetworkContext";

export interface MenuItem {
label: string;
pathname: string;
testId: string;
childPaths: string[];
imagePath: string;
}

// To hide /faucet navigation menu item if not in testnet
export default function useMenuNavigationHelper({
menu,
}: {
menu: MenuItem[];
}) {
const { connection } = useNetwork();

return connection !== NetworkConnection.TestNet
? menu.filter((item) => item.label !== "Faucet")
: menu;
}
22 changes: 18 additions & 4 deletions src/layouts/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import Link from "@components/commons/Link";
import { useRouter } from "next/router";
import React, { useEffect, useState } from "react";
import Container from "@components/commons/Container";
import { FiXCircle, FiMenu } from "react-icons/fi";
import { FiMenu, FiXCircle } from "react-icons/fi";
import Image from "next/image";
import { getTopLevelRoute } from "shared/urlHelper";
import useMenuNavigationHelper, {
MenuItem,
} from "@hooks/useMenuNavigationHelper";
import {
HeaderNetworkMenu,
HeaderNetworkMenuMobile,
} from "./HeaderNetworkMenu";

const MenuItems = [
export const MenuItems: MenuItem[] = [
{
label: "Blocks",
pathname: "/blocks",
Expand Down Expand Up @@ -40,6 +43,13 @@ const MenuItems = [
childPaths: ["/token"],
imagePath: "/menu/Tokens.svg",
},
{
label: "Faucet",
pathname: "/faucet",
testId: "Desktop.HeaderLink.Faucet",
childPaths: ["/faucet"],
imagePath: "/menu/Transactions.svg",
},
];

export default function Header(): JSX.Element {
Expand Down Expand Up @@ -96,9 +106,11 @@ export default function Header(): JSX.Element {
}

function DesktopNavbar({ currentPath }: { currentPath: string }): JSX.Element {
const filteredMenuItems = useMenuNavigationHelper({ menu: MenuItems });

return (
<div className="bg-white-50 rounded-3xl">
{MenuItems.map((item) => (
{filteredMenuItems.map((item) => (
<HeaderLink
label={item.label}
pathname={item.pathname}
Expand All @@ -119,6 +131,8 @@ function MobileNavbar({
isOpen: boolean;
onClose: () => void;
}): JSX.Element {
const filteredMenuItems = useMenuNavigationHelper({ menu: MenuItems });

return (
<>
<div
Expand Down Expand Up @@ -156,7 +170,7 @@ function MobileNavbar({
/>
</div>
<div className="mt-4">
{MenuItems.map((item) => (
{filteredMenuItems.map((item) => (
<HeaderMobileLink
label={item.label}
imagePath={item.imagePath}
Expand Down
2 changes: 1 addition & 1 deletion src/layouts/components/HeaderNetworkMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export function HeaderNetworkMenuMobile(): JSX.Element {
<a
key={item}
className={clsx(
"flex items-center justify-between cursor-pointer py-3 justify-between flex-1",
"flex items-center justify-between cursor-pointer py-3 flex-1",
{ "mb-16": index === networks.length - 1 }
)}
href={`/?network=${item}`}
Expand Down
20 changes: 20 additions & 0 deletions src/layouts/components/SectionTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import clsx from "clsx";

export default function SectionTitle({
title,
}: {
title: string;
}): JSX.Element {
return (
<div className="flex flex-col items-center text-center mt-[88px] md:mt-24 mx-1 md:mx-[148px] lg:mx-0 mb-6">
<span
className={clsx(
"font-semibold text-white-50 text-[32px] leading-10 -tracking-[0.01em]",
"md:text-5xl md:leading-[56px] md:-tracking-[0.02em]"
)}
>
{title}
</span>
</div>
);
}
43 changes: 43 additions & 0 deletions src/layouts/components/TextInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useState } from "react";
pierregee marked this conversation as resolved.
Show resolved Hide resolved
import { Combobox } from "@headlessui/react";
import clsx from "clsx";

export default function TextInput(): JSX.Element {
const [isFocused, setIsFocused] = useState<boolean>(false);

const transitionClass = "transition duration-300 ease-in";

return (
<Combobox>
<div
className={clsx(
"relative group flex w-full rounded-lg p-[1px] bg-black-500 focus-within:bg-lightBlue black-gradient-1-shadow backdrop-blur-[6px]",
transitionClass
)}
data-testid="search-bar-container"
>
{!isFocused && (
<div
className={clsx(
" opacity-0 rounded-lg transition brand-gradient-1 group-hover:opacity-100",
transitionClass
)}
/>
)}

<div className="relative flex w-full px-8 py-[22px] rounded-lg bg-black-500 black-gradient-1">
<Combobox.Button as="div" className="flex w-full gap-2">
<Combobox.Input
as="input"
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
placeholder="0xxxxxxx"
className="h-full w-full focus:outline-none bg-transparent caret-lightBlue placeholder-white-700 placeholder-opacity-50 text-white-50 text-xl tracking-[0.01em]"
data-testid="wallet_address_input"
/>
</Combobox.Button>
</div>
</div>
</Combobox>
);
}
55 changes: 55 additions & 0 deletions src/pages/faucet/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import Container from "@components/commons/Container";
import GradientCardContainer from "@components/commons/GradientCardContainer";
import Button from "@components/commons/Button";
import ReCAPTCHA from "react-google-recaptcha";
import { useEffect, useState } from "react";
import { useNetwork } from "@contexts/NetworkContext";
import { NetworkConnection } from "@contexts/Environment";
import { useRouter } from "next/router";
import TextInput from "../../layouts/components/TextInput";
import SectionTitle from "../../layouts/components/SectionTitle";

// hide this page if not on testnet
export default function Faucet() {
const { connection } = useNetwork();
const router = useRouter();

const [isCaptchaSuccessful, setIsCaptchaSuccess] = useState(false);
function onChange() {
setIsCaptchaSuccess(true);
}

useEffect(() => {
if (connection !== NetworkConnection.TestNet) {
router.push(`/404?network=${connection}`);
}
}, [connection]);

return (
<Container className="px-1 md:px-0 mt-12">
<SectionTitle title="Testnet Faucet" />
<GradientCardContainer>
<div data-testid="blocks-list" className="p-5 md:p-10">
<div className="flex flex-col md:flex-row py-6 md:py-4 justify-between md:items-center relative">
<h1 className="font-bold text-2xl text-white-50">Wallet Address</h1>
</div>
<TextInput />
<div className="py-6 flex gap-x-4 flex-row justify-end">
<ReCAPTCHA
sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY || ""}
onChange={() => onChange()}
className="text-center items-center"
/>
<Button
testId="send_tokens_btn"
label="Send Tokens"
customStyle="font-medium text-sm md:text-base !py-2 !px-4 md:!py-3 md:!px-8 disabled:opacity-50 disabled:cursor-not-allowed"
disabled={!isCaptchaSuccessful}
onClick={() => {}}
pierregee marked this conversation as resolved.
Show resolved Hide resolved
/>
</div>
</div>
</GradientCardContainer>
</Container>
);
}
Loading