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

Frontend cleanup #10

Merged
merged 6 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,5 @@ if neither error:
```
return the secret contract's own pubkey
```

This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](./LICENCE) file for details.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useState } from "react";
import { useGlobalState } from "../services/store/store";
import { useGlobalState } from "../../services/store/store";
import type { NextPage } from "next";
import { useScaffoldWatchContractEvent, useScaffoldWriteContract } from "~~/hooks/scaffold-eth";
import { convertToBigint } from "~~/utils/convert";
import { convertToBigint } from "~~/utils/helpers";

interface AccountCreationRequest {
secret: string;
Expand All @@ -11,12 +11,12 @@ interface AccountCreationRequest {
const CreateAccount: NextPage = () => {
const [confirmation, setConfirmation] = useState<AccountCreationRequest | undefined>();
const { writeContractAsync } = useScaffoldWriteContract("NunyaBusiness");
// const encoder: TextEncoder = new global.TextEncoder();
// const decoder: TextDecoder = new global.TextDecoder();

const { secret, setSecret } = useGlobalState();
const openRequests = new Map<bigint, AccountCreationRequest>();

// create new nunya account for the given secret ////////////////////////////

const handleCreateAccount = async (event: React.FormEvent) => {
event.preventDefault();
if (!secret) {
Expand All @@ -28,7 +28,7 @@ const CreateAccount: NextPage = () => {
const requestId = await writeContractAsync({
functionName: "newSecretUser",
value: 30000000n,
// TODO args: [encoder.encode(secret) ...
// FIXME encrypt parameters before sending
args: [secret],
});
console.log("⚡ Requesting new account", requestId, secret);
Expand All @@ -40,6 +40,8 @@ const CreateAccount: NextPage = () => {
openRequests.set(convertToBigint(requestId), { secret });
};

// wait for the event confirming the account creation ///////////////////////

useScaffoldWatchContractEvent({
contractName: "NunyaBusiness",
eventName: "AccountCreated",
Expand All @@ -53,7 +55,6 @@ const CreateAccount: NextPage = () => {
// TODO UI feedback
return console.error("No request ID returned", log);
}
// FIXME args.requestId is bigint, but the return type of writeContractAsync(...) is `0x{string}`
const request = openRequests.get(log.args.requestId);
if (!request) {
// TODO UI feedback
Expand All @@ -69,7 +70,7 @@ const CreateAccount: NextPage = () => {
<>
<h2 className="text-center text-2xl mt-8">Create Account</h2>
<form onSubmit={handleCreateAccount} className="flex flex-col items-center mb-8 mx-5 space-y-4">
<div className="flex flex-col space-y-3">
<section className="flex flex-col space-y-3">
<input
className="border bg-base-100 p-3 w-full rounded-md shadow focus:outline-none focus:ring-2 focus:ring-blue-500"
type="text"
Expand All @@ -83,13 +84,13 @@ const CreateAccount: NextPage = () => {
>
Create Account
</button>
</div>
</section>
</form>
{confirmation ? (
<>
<section>
<h3>Account creation confirmed</h3>
<p>Secret: {confirmation.secret}.</p>
</>
</section>
) : (
<></>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { useState } from "react";
import { PaymentReference, useGlobalState } from "../services/store/store";
import { PaymentReference, useGlobalState } from "../../services/store/store";
import type { NextPage } from "next";
import QRCode from "qrcode.react";
import { useScaffoldWatchContractEvent, useScaffoldWriteContract } from "~~/hooks/scaffold-eth";
import { convertToBigint } from "~~/utils/convert";
import { MAX_GAS_PER_BLOCK, convertToBigint } from "~~/utils/helpers";
import { SupportedCurrencies, createPaymentLink } from "~~/utils/link";

const CreatePaymentReference: NextPage = () => {
const [desiredReference, setDesiredReference] = useState("");
const [amount, setAmount] = useState<number>(0);
const [currency, setCurrency] = useState<SupportedCurrencies>("ETH");
const { writeContractAsync } = useScaffoldWriteContract("NunyaBusiness");
// const encoder: TextEncoder = new global.TextEncoder();
// const decoder: TextDecoder = new global.TextDecoder();

const { secret, setSecret, references, addReference } = useGlobalState();
const openRequests = new Map<bigint, PaymentReference>();

// create payment reference /////////////////////////////////////////////////

const handleCreatePaymentReference = async (event: React.FormEvent) => {
event.preventDefault();
const requestId = await writeContractAsync({
functionName: "createPaymentReference",
// value: parseEther(returnAmount),
// FIXME: estimate the amount of gas required for forward fees
value: MAX_GAS_PER_BLOCK,
// FIXME args: [encoder.encode(secret) ...
args: [secret, desiredReference],
});
Expand All @@ -31,9 +31,12 @@ const CreatePaymentReference: NextPage = () => {
// TODO UI feedback
return console.error("No request ID returned.");
}
// FIXME returned requestId should be bigint but return type of writeContractAsync(...) is `0x{string}`
openRequests.set(convertToBigint(requestId), { amount, currency, reference: "loading..." });
};

// watch for an event that confirms that the reference has been created /////

useScaffoldWatchContractEvent({
contractName: "NunyaBusiness",
eventName: "PaymentReferenceCreated",
Expand All @@ -47,7 +50,6 @@ const CreatePaymentReference: NextPage = () => {
// TODO UI feedback
return console.error("No request ID returned", log);
}
// FIXME args.requestId is bigint, but the return type of writeContractAsync(...) is `0x{string}`
const request = openRequests.get(log.args.requestId);
if (!request) {
// TODO UI feedback
Expand All @@ -69,7 +71,7 @@ const CreatePaymentReference: NextPage = () => {
<>
<h2 className="text-center text-2xl mt-8">Create Payment Reference</h2>
<form onSubmit={handleCreatePaymentReference} className="flex flex-col items-center mb-8 mx-5 space-y-4">
<div className="flex flex-col space-y-3">
<section className="flex flex-col space-y-3">
<input
className="border bg-base-100 p-3 w-full rounded-md shadow focus:outline-none focus:ring-2 focus:ring-blue-500"
type="text"
Expand Down Expand Up @@ -123,30 +125,30 @@ const CreatePaymentReference: NextPage = () => {
>
Create New Payment Reference
</button>
</div>
{references.length > 0 ? (
<section>
<h3>Created payment references</h3>
<ul>
{references.map((ref, index) => (
<li key={index}>
<p className="text-center">
Reference: {ref.reference}, amount: {ref.amount}, currency: {ref.currency}, payment link:{" "}
<a href={createPaymentLink(ref)} target="_blank">
{createPaymentLink(ref)}
</a>
</p>
<p className="text-center">
QR code: <QRCode value={createPaymentLink(ref)} size={256} />
</p>
</li>
))}
</ul>
</section>
) : (
<></>
)}
</section>
</form>
{references.length > 0 ? (
<section>
<h3>Created payment references</h3>
<ul>
{references.map((ref, index) => (
<li key={index}>
<p className="text-center">
Reference: {ref.reference}, amount: {ref.amount}, currency: {ref.currency}, payment link:{" "}
<a href={createPaymentLink(ref)} target="_blank">
{createPaymentLink(ref)}
</a>
</p>
<p className="text-center">
QR code: <QRCode value={createPaymentLink(ref)} size={256} />
</p>
</li>
))}
</ul>
</section>
) : (
<></>
)}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useState } from "react";
import { useGlobalState } from "../services/store/store";
import { useGlobalState } from "../../services/store/store";
import type { NextPage } from "next";
import { formatEther, parseEther } from "viem";
import { useScaffoldWatchContractEvent, useScaffoldWriteContract } from "~~/hooks/scaffold-eth";
import { convertToBigint } from "~~/utils/convert";
import { convertToBigint } from "~~/utils/helpers";

interface WithdrawalRequest {
amount: string;
Expand All @@ -15,8 +15,6 @@ const Withdraw: NextPage = () => {
const [address, setReturnAddress] = useState("");
const [confirmation, setConfirmation] = useState<WithdrawalRequest | undefined>();
const { writeContractAsync } = useScaffoldWriteContract("NunyaBusiness");
// const encoder: TextEncoder = new global.TextEncoder();
// const decoder: TextDecoder = new global.TextDecoder();

const { secret, setSecret } = useGlobalState();
const openRequests = new Map<bigint, WithdrawalRequest>();
Expand All @@ -27,13 +25,14 @@ const Withdraw: NextPage = () => {
// const encryptedSecret: ArrayBuffer = await encrypt(encoder.encode(secret));
const requestId = await writeContractAsync({
functionName: "withdrawTo",
// TODO args: [encoder.encode(secret) ...
args: [secret, parseEther(amount), convertToBigint(address), "ETH"],
// FIXME encrypt parameters
args: [secret, parseEther(amount), address, "ETH"],
});
console.log("⚡ Requesting new account", requestId, secret, parseEther(amount), address);
console.log("⚡ Withdrawal requested. ", requestId, secret, parseEther(amount), address);
if (!requestId) {
return console.error("No request ID returned.");
}
// FIXME returned requestId should be bigint but return type of writeContractAsync(...) is `0x{string}`
openRequests.set(convertToBigint(requestId), { amount, address: convertToBigint(address) });
};

Expand All @@ -50,7 +49,6 @@ const Withdraw: NextPage = () => {
// TODO UI feedback
return console.error("No request ID returned", log);
}
// FIXME args.requestId is bigint, but the return type of writeContractAsync(...) is `0x{string}`
const request = openRequests.get(log.args.requestId);
if (!request) {
// TODO UI feedback
Expand Down
5 changes: 3 additions & 2 deletions packages/nextjs/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { ThemeProvider } from "~~/components/ThemeProvider";
import "~~/styles/globals.css";
import { getMetadata } from "~~/utils/scaffold-eth/getMetadata";

// Has side effect of setting HTML header metadata like thumbnail.jpg
export const metadata = getMetadata({
title: "Scaffold-ETH 2 App",
description: "Built with 🏗 Scaffold-ETH 2",
title: "Nunya.business",
description: "Receive business payments without revealing to other what you've earned.",
});

const ScaffoldEthApp = ({ children }: { children: React.ReactNode }) => {
Expand Down
30 changes: 8 additions & 22 deletions packages/nextjs/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,27 @@
"use client";

import CreateAccount from "./createAccount";
import CreatePaymentReference from "./createPaymentReference";
import Withdraw from "./withdraw";
import CreateAccount from "./_components/createAccount";
import CreatePaymentReference from "./_components/createPaymentReference";
import Withdraw from "./_components/withdraw";
import type { NextPage } from "next";

declare global {
interface Window {
temp: unknown;
}
}

const Home: NextPage = () => {
return (
<>
<div className="bg-base-200 min-h-screen flex flex-col justify-center py-10 w-full">
<h1 className="text-center">
<h1 className="text-center mb-12">
<span className="block text-5xl font-bold">Nunya.business</span>
<span className="block text-3xl bg-base-100 mb-4">Receive Business Payments</span>
<span className="block text-3xl mb-4">Receive Business Payments</span>
<p className="block bg-base-100 my-2 p-2 font-medium text-base">
... without revealing to other what you&apos;ve earned.
</p>
</h1>
<div className="flex justify-center items-center space-x-2 flex-col sm:flex-row mb-8">
<p className="my-2 font-medium text-base">... without revealing to other clients what you&apos;ve earned.</p>
</div>

<p className="text-base">Create a payment link and add it to your invoice to start receiving payments.</p>

<CreateAccount></CreateAccount>
<CreatePaymentReference></CreatePaymentReference>
<Withdraw></Withdraw>

{/* Uncomment if needed
<Link href="/debug" passHref className="link text-blue-500 hover:underline">
Debug
</Link>
<BugAntIcon className="h-8 w-8 fill-secondary" />
<MagnifyingGlassIcon className="h-8 w-8 fill-secondary" />
*/}
</div>
</>
);
Expand Down
Loading
Loading