Skip to content

Commit

Permalink
Merge pull request #4 from swellander/feat/list-requests
Browse files Browse the repository at this point in the history
Merged, any front end change is better than none, and I still don't know how to check how changes look without merging lol
  • Loading branch information
luloxi committed Dec 31, 2023
2 parents d522c93 + e251888 commit 3df3a7e
Show file tree
Hide file tree
Showing 9 changed files with 428 additions and 207 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 💸 EasyPay 💸
# 💸 Easy2Pay 💸

💸 dApp for requesting payments in a currency (like USD, ETH and BTC), and accept different type of valid tokens that share a common value using [Chainlink Price Feeds](https://docs.chain.link/data-feeds/price-feeds).

Expand All @@ -9,15 +9,15 @@

## Quickstart

To get started with EasyPay, follow the steps below:
To get started with Easy2Pay, follow the steps below:

1. Make sure you have the [foundry toolkit installed](https://book.getfoundry.sh/getting-started/installation).

2. Clone this repo & install dependencies

```
git clone https://github.com/luloxi/EasyPay.git
cd EasyPay
git clone https://github.com/luloxi/Easy2Pay.git
cd Easy2Pay
yarn install
```

Expand Down Expand Up @@ -47,7 +47,7 @@ Visit your app on: `http://localhost:3000`. You can interact with your smart con

Run smart contract test with `yarn hardhat:test`

- Edit your smart contract `EasyPay.sol` in `packages/hardhat/contracts`
- Edit your smart contract `Easy2Pay.sol` in `packages/hardhat/contracts`
- Edit your frontend in `packages/nextjs/pages`
- Edit your deployment scripts in `packages/hardhat/deploy`

Expand All @@ -65,7 +65,7 @@ Run smart contract test with `yarn hardhat:test`

## Contents

- [💸 EasyPay 💸](#-easypay-)
- [💸 Easy2Pay 💸](#-easypay-)
- [Quickstart](#quickstart)
- [🏗 About Scaffold-ETH 2](#-about-scaffold-eth-2)
- [Contents](#contents)
Expand Down
84 changes: 84 additions & 0 deletions packages/foundry/contracts/Easy2Pay.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

/**
@dev Struct to store payment requests
@variables amount: Amount of USD requested
@variables receiver: Address of payment receiver
@variables completed: Boolean to determine if payment was succesfully made
*/
struct PayRequest {
uint256 amount;
bool completed;
}

contract Easy2Pay {
address public owner;

/**
@dev Mapping to store PayRequest structs mapped to a unique requestId
*/
mapping(address receiver => PayRequest[]) public payRequests;

// Custom errors
error Easy2Pay__RequestDoesNotExist();
error Easy2Pay__InsufficientEther(
uint256 requestedAmount,
uint256 actualAmount
);
error Easy2Pay__PaymentAlreadyCompleted();
error Easy2Pay__FailedToSendEther();
error Easy2Pay__UnauthorizedAccess();

modifier onlyOwner() {
if (msg.sender != owner) revert Easy2Pay__UnauthorizedAccess();
_;
}

constructor() {
owner = msg.sender;
}

function requestPayment(uint256 _amount) public {
uint256 id = payRequests[msg.sender].length;
payRequests[msg.sender].push(PayRequest(_amount, false));
}

function getRequests(address receiver) public view returns(PayRequest[] memory) {
return payRequests[receiver];
}

function pay(address receiver, uint256 _requestId) public payable {
PayRequest storage request = payRequests[receiver][_requestId];

if (receiver == address(0))
revert Easy2Pay__RequestDoesNotExist();

if (request.amount > msg.value)
revert Easy2Pay__InsufficientEther(request.amount, msg.value);

if (request.completed) revert Easy2Pay__PaymentAlreadyCompleted();

request.completed = true;

// Call returns a boolean value indicating success or failure.
// This is the current recommended method to use to transfer ETH.
(bool sent, ) = receiver.call{value: msg.value}("");

if (!sent) revert Easy2Pay__FailedToSendEther();
}

// Function in case a payment is received where msg.data must be empty
receive() external payable {
if (msg.sender != address(0)) revert Easy2Pay__FailedToSendEther();
}

// Fallback function is called when msg.data is not empty
fallback() external payable {
if (msg.sender != address(0)) revert Easy2Pay__FailedToSendEther();
}

function setOwner(address _newOwner) public onlyOwner {
owner = _newOwner;
}
}
82 changes: 0 additions & 82 deletions packages/foundry/contracts/EasyPay.sol

This file was deleted.

6 changes: 3 additions & 3 deletions packages/foundry/script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "../contracts/EasyPay.sol";
import "../contracts/Easy2Pay.sol";
import "./DeployHelpers.s.sol";

contract DeployScript is ScaffoldETHDeploy {
Expand All @@ -15,10 +15,10 @@ contract DeployScript is ScaffoldETHDeploy {
);
}
vm.startBroadcast(deployerPrivateKey);
EasyPay easyPay = new EasyPay();
Easy2Pay easyPay = new Easy2Pay();
console.logString(
string.concat(
"EasyPay deployed at: ",
"Easy2Pay deployed at: ",
vm.toString(address(easyPay))
)
);
Expand Down
7 changes: 6 additions & 1 deletion packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback, useRef, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { Bars3Icon, BugAntIcon } from "@heroicons/react/24/outline";
import { BanknotesIcon, Bars3Icon, BugAntIcon } from "@heroicons/react/24/outline";
import { FaucetButton, RainbowKitCustomConnectButton } from "~~/components/scaffold-eth";
import { useOutsideClick } from "~~/hooks/scaffold-eth";

Expand All @@ -17,6 +17,11 @@ export const menuLinks: HeaderMenuLink[] = [
label: "Home",
href: "/",
},
{
label: "Payment Requests",
href: "/requests",
icon: <BanknotesIcon className="h-4 w-4" />,
},
{
label: "Debug Contracts",
href: "/debug",
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"react-copy-to-clipboard": "~5.1.0",
"react-dom": "~18.2.0",
"react-hot-toast": "~2.4.0",
"react-qr-code": "^2.0.12",
"use-debounce": "~8.0.4",
"usehooks-ts": "~2.9.1",
"viem": "1.19.9",
Expand Down
49 changes: 49 additions & 0 deletions packages/nextjs/pages/makePayment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import { useConnectModal } from "@rainbow-me/rainbowkit";
import type { NextPage } from "next";
import { useAccount } from "wagmi";
import { useScaffoldContractWrite } from "~~/hooks/scaffold-eth";

const Requests: NextPage = () => {
const { isConnected } = useAccount();
const [hasBeenCalled, setHasBeenCalled] = useState(false);
const { openConnectModal } = useConnectModal();
const searchParams = useSearchParams();
const recipient = searchParams.get("recipient") || undefined;
const amount = searchParams.get("amount") || undefined;
const requestId = searchParams.get("requestId") || undefined;
const { writeAsync: sendPaymentTx, isLoading } = useScaffoldContractWrite({
contractName: "Easy2Pay",
functionName: "pay",
args: [recipient, BigInt(requestId || "0")],
// for payable functions, expressed in eth
value: BigInt(amount || "0"),
// the number of block confirmations to wait for before considering transaction to be confirmed (default : 1).
blockConfirmations: 1,
// the callback function to execute when the transaction is confirmed.
onBlockConfirmation: txnreceipt => {
console.log("transaction blockhash", txnreceipt.blockHash);
},
});

useEffect(() => {
if (!isConnected) openConnectModal?.();
}, [isConnected, openConnectModal]);

useEffect(() => {
const sendPaymentTxAndHandleErr = async () => {
const response = await sendPaymentTx();
console.log({ response });
};

if (recipient && amount && requestId && !hasBeenCalled && !isLoading && isConnected) {
sendPaymentTxAndHandleErr();
setHasBeenCalled(true);
}
}, [recipient, amount, requestId, hasBeenCalled, isConnected]);

return <></>;
};

export default Requests;
Loading

0 comments on commit 3df3a7e

Please sign in to comment.