Skip to content

Latest commit

 

History

History
500 lines (267 loc) · 42.7 KB

README_detailed.md

File metadata and controls

500 lines (267 loc) · 42.7 KB

Project Setup Guidelines for All Users

This is a User Guide for users who want to know how the program runs or functions, who are interested in code development particularly Blockchain Technology.

To run CryptoLends project locally, feel free to follow the steps below to set up both the frontend and backend components of the project. You must have Visual Studio Code, Git or Hardhat installed beforehand. There are tons of resources available online that guide on how to install these tools.

Frontend Commands

Clone CryptoLends Repository

Step 1: Initialize Git Repository

git init

Purpose: Initializes a new Git repository in your project directory. This is the first step in setting up version control.

Step 2: Add Remote Repository

git remote add origin https://github.com/TheDaniel3131/CryptoLends.git

Purpose: Links your local Git repository to the remote repository on GitHub. Replace the URL with the correct remote repository URL if different.

Step 3: Pull Latest Changes

git pull origin main

Purpose: Fetches and merges the latest changes from the main branch of the remote repository into your local repository.

Step 4: Install Dependencies

npm install

or

npm i

Purpose: Installs all the necessary dependencies for the project as defined in the package.json file.

Step 5: Start the Frontend Development Server

cd cl_ui
npm run dev

Purpose: Navigates to the frontend directory and starts the development server. This allows you to preview the application locally as you make changes.

Step 6: Add Frontend-Specific Tools or Packages

Make sure you are in "cl_ci" folder!

npx v0 add Sf3MALSwyYX

Purpose: Executes an npx command to add a specific package or tool (v0). Ensure that you have the correct permissions and context for this command.

Backend Commands

Step 1: Get Help with Hardhat

npx hardhat help

Purpose: Displays a list of available Hardhat commands and options. Use this command if you need guidance on how to use Hardhat features.

Step 2: Start a Local Blockchain Node

npx hardhat node

Purpose: Starts a local Ethereum blockchain node using Hardhat. This is crucial for local testing and deploying smart contracts before interacting with a live network.

Step 3: Run the Test Suite

npm run test

Purpose: Executes the project's test suite to validate the functionality of smart contracts. Ensure your test scripts are properly configured to cover all essential use cases.

Step 4: Compile Smart Contracts

npm run compile

Purpose: Compiles the Solidity smart contracts into bytecode and ABI using Hardhat. This step must be completed before testing or deploying your contracts.

Step 5: Deploy Smart Contracts

npm run deploy

Purpose: Runs the deployment script to deploy your smart contracts to a blockchain network. Make sure the deployment settings are correctly configured in the script.

For hardhat, you do not really have to run these commands if you clone the repository, but if you need these then here you go:

Misc:

Hardhat Commands:

Step 1: Initialize the Backend Project

npm init -y
  • Purpose: Initializes a new Node.js project with default settings by creating a package.json file.

Step 2: Install Hardhat as a Dev Dependency

npm install --save-dev hardhat
  • Purpose: Installs Hardhat as a development dependency, a tool for smart contract development.

Step 3: Initialize Hardhat

npx hardhat init
  • Purpose: Initializes the Hardhat environment, creating the basic directory structure and configuration files for smart contract development.

Step 4: Check Hardhat Version

npx hardhat --version
  • Purpose: Verifies the installed version of Hardhat, ensuring that the setup is correct.

System Architecture Overview

The project is a peer-to-peer lending platform where lenders and borrowers can transact in Ethereum. The system architecture includes several key pages:

The contact page features a form that allows users to send messages to other users based on the provided email address. This functionality is implemented using Formspree APIs.

The withdraw page includes a table for borrowers to convert loaned tokens into Ethereum. The withdrawal function calls a query function from Supabase, and the corresponding amount in the user_address table is deducted accordingly.

The lending page provides a table where lenders can submit lending requests, specifying the lending duration and interest rate. Submitted forms are sent to the backend and subsequently to a smart contract to insert the data into the lending list table. The lending status is updated to "active" to indicate that the amount is available for borrowing. Additionally, the user status is updated to reflect whether they are a lender or borrower. Borrowers cannot use the lending page functions until they have repaid their previous loans.

The borrowing page displays a list of available lending opportunities. Borrowers can view detailed information about each lending option and choose to borrow the amount if desired. When a borrower proceeds, the data is sent to the smart contract to update both the lender's and borrower's amounts, and the transaction is recorded in the Supabase table. The lending status changes from "active" to "pending" to notify the lender that their amount has been borrowed.

The about us page provides information about the platform and does not interact with any backend functionality.

The repay page features a table for borrowers to repay their loans, including interest. If the borrower has any outstanding loans, the details are displayed in the table. Upon repayment, the borrower's amount is deducted by the total repayment amount (principal plus interest), and the lender's amount is increased accordingly. The lending status updates from "pending" to "complete" to indicate that the repayment has been made. The statuses of the borrower and lender are also reset, allowing the borrower to use the lending page functions again.

The user profile page is displayed after the user logs into their MetaMask account. MetaMask integration is managed through APIs. Upon login, the system checks if the user's address exists in the Supabase table. If not, the address is inserted into the table. Users can view their profile details on this page.

Code Implementation Explanations with Screenshots

Database - Supabase

insert_address

The insert_address function is designed to add a new address to the user_address table if it doesn't already exist. It takes a single parameter, p_address, which is the address to be inserted. This query function will be used when user login and detected that the user address haven't existing in the user_address table.

insert_lending_list

The insert_lending_list function manages the insertion of new lending records into the lending_list table. It accepts parameters for address, amount, currency, duration_month, and rate. After performing the update, it uses GET DIAGNOSTICS to determine how many rows were affected by the operation. If the update was successful and affected rows, the function returns TRUE. Otherwise, it returns FALSE.This function will be used when the lender have submit the lending form on the lending page.

withdraw_token

The withdraw_token function is used to handle token withdrawals from user accounts. It takes two parameters: p_address, which represents the user’s address, and amount, the amount of tokens to be withdrawn.

The function first checks if the user’s account is frozen by querying the user_address table. If the account is frozen, it raises a notice stating that the withdrawal cannot be processed and returns FALSE. If the account is not frozen, it then checks whether the user has sufficient tokens available for withdrawal. If the user has enough tokens, the function updates the token_amount and withdraw_amount fields accordingly. After performing the update, it uses GET DIAGNOSTICS to determine how many rows were affected by the operation. If the update was successful and affected rows, the function returns TRUE. Otherwise, it returns FALSE. If the user does not have enough tokens, it raises a notice indicating insufficient funds and returns FALSE. This function will be used when the borrower withdraw the token to Ethereum on withdraw page.

loan_update_process

The loan_update_process function manages the process of updating loan-related information in the system. It accepts parameters such as lender, borrower, amount, currency, duration, start_date, end_date, and rate.

The function begins by calling update_loan, which updates the loan details in the system with the provided parameters. Following that, it calls loan_address_borrower_status_and_amount to adjust the status and amount related to the borrower’s address. It then calls loan_address_lender_status_and_amount to update the lender’s address status and amount.

If all operations complete successfully, the function returns TRUE. If any error occurs during these operations, the function catches the exception and returns FALSE, ensuring that any issues are handled gracefully. This function will be used when the borrower have process the repay action on repay page.

update_loan

The update_loan function is responsible for updating the status of a loan in the transaction_record table. It takes parameters such as lender, borrower, amount, currency, duration, start_date, end_date, and rate.

The function starts by attempting to update the status of rows in the transaction_record table where the specified parameters match an existing record with a status of 'Pending'. The UPDATE statement sets the status to 'Complete' for these records.

After performing the update, the function uses GET DIAGNOSTICS to check the number of rows affected by the operation. If at least one row was updated, it returns TRUE, indicating success. If no rows were updated, it returns FALSE, signaling that the update did not affect any records. This function helps manage the transition of loan records from 'Pending' to 'Complete' status efficiently.

loan_address_borrower_status_and_amount

The loan_address_borrower_status_and_amount function updates the status and amount for a borrower's account in the user_address table. It accepts three parameters: p_address (the borrower's address), amount (the loan amount), and interest_rate (the rate of interest).

The function begins by checking if the account associated with p_address has sufficient tokens to cover the loan amount adjusted by the interest rate. If the account has enough tokens, it proceeds to update the account by reducing the token_amount by the product of amount and interest_rate. It also decreases the borrowing_amount by the original amount and sets both borrow_status and lend_status to NULL, indicating the completion or cancellation of the borrowing process.

After performing the update, the function uses GET DIAGNOSTICS to check how many rows were affected. If at least one row was successfully updated, it returns TRUE. Otherwise, it returns FALSE. If the account does not have enough funds, the function raises a notice about an error and returns FALSE. This function helps manage the post-loan status and adjustments for a borrower's account.

loan_address_borrower_status_and_amount

The loan_address_lender_status_and_amount function is used to update the status and amounts for a lender's account in the user_address table. It takes three parameters: p_address (the lender's address), amount (the loan amount), and interest_rate (the interest rate applied).

The function begins by checking if the lender’s account exists in the user_address table. If the account is found, it updates the token_amount by adding the product of amount and interest_rate, which reflects the interest earned. It also decreases the lending_amount by the original amount, and sets both borrow_status and lend_status to NULL, indicating the completion or cancellation of the lending process.

After performing the update, the function uses GET DIAGNOSTICS to determine how many rows were affected. If at least one row was updated successfully, it returns TRUE. If no rows were affected, it returns FALSE. If the account is not found, the function raises a notice about an error and returns FALSE. This function ensures accurate adjustments to the lender’s account following a loan transaction.

transaction_process

The transaction_process function coordinates the various steps involved in processing a financial transaction between a lender and a borrower. It accepts parameters such as lender, borrower, amount, currency, duration_month, and rate.

The function begins by calling convert_token_process, which is responsible for handling the conversion or allocation of tokens related to the transaction. Next, it invokes update_address_borrower_status_and_amount to adjust the borrower’s account status and amount based on the transaction details. Similarly, it calls update_address_lender_status_and_amount to update the lender’s account status and amount.

After executing these steps, the function returns TRUE if everything completes successfully. If any errors occur during these operations, it catches the exception and returns FALSE, ensuring that the transaction process handles failures gracefully. This function will be used when the borrower borrow the lending amount on borrowing page.

convert_token_process

The convert_token_process function is designed to handle the creation of a new transaction record in the transaction_record table. It takes parameters including lender, borrower, amount, currency, duration_month, and rate.

The function begins by inserting a new row into the transaction_record table with the provided details. It records the lender’s and borrower’s addresses, the token amount involved in the transaction, the cryptocurrency type, the duration of the loan in months, and the interest rate. The lending_or_borrowing_start_date is set to the current timestamp, while the lending_or_borrowing_end_date is calculated by adding the duration in months to the current timestamp. The status of the transaction is initially set to 'Pending'.

update_address_borrower_status_and_amount

The update_address_borrower_status_and_amount function updates the status and amounts for a borrower's account in the user_address table. It accepts two parameters: p_address, which represents the borrower's address, and amount, the amount involved in the transaction.

The function updates the user_address table by setting the lend_status to false and the borrow_status to true, indicating that the account is now in a borrowing state. It also increases the token_amount by the specified amount, reflecting the addition of tokens to the account. Additionally, it updates the borrowing_amount by adding the same amount, representing the total borrowed amount.

update_address_lender_status_and_amount

The update_address_lender_status_and_amount function updates the status and amounts for a lender's account in the user_address table. It takes two parameters: p_address, representing the lender's address, and amount, the amount involved in the transaction.

The function performs an update operation on the user_address table, setting the lend_status to true and the borrow_status to false. This change reflects that the account is now in a lending state. It also decreases the token_amount by the specified amount, indicating the reduction of tokens available. Simultaneously, it increases the lending_amount by the same amount, representing the total amount lent out.

Backend

createUserAddress.tsx

The createUserAddress function is an asynchronous TypeScript function that interacts with a Supabase database to insert a new address into the user_address table. It takes one parameter, address, which represents the address to be added.

The function initializes a Supabase client using a URL and API key. For security reasons, it is advisable to use environment variables to store sensitive keys instead of hardcoding them.

The function calls the Supabase remote procedure function insert_address, passing the address as a parameter. If the RPC call returns an error, it logs the error message and returns false. If the insertion is successful and no errors are encountered, the function returns true, indicating that the address was successfully added to the database.

lendingListInsert.tsx

The lendingListInsert function is an asynchronous TypeScript function designed to interact with a Supabase database to insert a new lending record into the lending_list table. It takes parameters including address (the lender's address), amount (the lending amount), currency (the type of currency), duration (the duration of the loan in months), and interest_rate (the interest rate).

The function creates a Supabase client using a URL and API key. For security reasons, it is best to store sensitive information like API keys in environment variables rather than hardcoding them.

The function then calls the Supabase remote procedure function insert_lending_list, passing the provided details as parameters. If the RPC call encounters an error, it logs the error message and returns false. If the operation completes successfully and data is returned, the function returns true. If no data is returned and an unexpected response is encountered, it logs a message and returns false. This ensures that the lending record is accurately inserted and any issues are handled properly.

transactionProcess

The transactionProcess function is an asynchronous TypeScript function that manages the transaction process between a lender and a borrower. It interacts with a Supabase database by invoking a remote procedure function named transaction_process.

The function takes parameters such as lender (the lender's address), borrower (the borrower's address), amount (the amount involved in the transaction), currency (the type of currency), durationMonth (the duration of the loan in months), and rate (the interest rate).

The Supabase client is initialized using a URL and API key, which should ideally be stored securely in environment variables rather than hardcoded.

The function calls the transaction_process RPC function with the provided parameters. If the RPC call results in an error, it logs the error message and returns false. If the call is successful and there are no errors, the function returns true, indicating that the transaction process was completed successfully.

withdrawToken.tsx

The withdrawToken function is an asynchronous TypeScript function that facilitates the withdrawal of tokens from a user's account by interacting with a Supabase database. It utilizes a remote procedure function named withdraw_token.

The function accepts two parameters: address, which is the user's address from which tokens will be withdrawn, and amount, which specifies the quantity of tokens to be withdrawn.

A Supabase client is created using a URL and API key, which are recommended to be stored securely in environment variables rather than being hardcoded.

The function calls the withdraw_token RPC function with the provided address and amount. If an error occurs during the RPC call, the function logs the error message and returns false. If the call is successful and data is returned, the function returns true. If the function returns no data and an unexpected response is encountered, it logs the issue and returns false. This ensures that the token withdrawal process is handled appropriately and errors are managed effectively.

Frontend

Connect.tsx

The Connect component is a React functional component that integrates with a web3 wallet and interacts with a Supabase database to update a user's address. This component uses hooks from the wagmi library for wallet connectivity and the createUserAddress function for database operations.

The component first imports necessary modules and functions, including useAccount from wagmi and createUserAddress from a Supabase query module.

Inside the Connect component, the useAccount hook is used to retrieve the connection status (isConnected) and the user's wallet address (address). The useEffect hook monitors these values, triggering a function to handle address updates when the wallet is connected and an address is available.

The handleAddressUpdate function asynchronously calls createUserAddress with the user's wallet address. If the address is successfully updated in the database, it logs a success message; otherwise, it logs an error.

The component renders a button (w3m-button) that displays "Connected" if the wallet is connected, or "Connect Wallet" if it is not. The button also has different states for loading and balance visibility.

This setup ensures that user addresses are updated in the database whenever a wallet connection is established, improving user experience by keeping the address information up-to-date.

Cashout.tsx

The CashOutPage component is a user-friendly interface designed to manage financial details, focusing on lending loans and withdrawals. It features two main sectionsl, dashboard and lending loans. Dashboard has displays total funds available for withdrawal and active lending loans using Card components. Each card provides a snapshot of the user’s financial status. Lending loans presents a detailed table of lending loans with attributes like asset type, amount, term, interest rate, and status. This section includes badges to indicate loan status and buttons for withdrawal actions.

The component uses Tailwind CSS for styling, ensuring responsiveness and a clean design. It also incorporates a custom CoinsIcon for thematic enhancement. While currently static, the page is designed to handle dynamic data and user interactions effectively.

Lending.tsx

The LendingPage component in React allows users to lend cryptocurrency assets by integrating with Ethereum through wagmi. The component uses hooks like useAccount, useSimulateContract, useWriteContract, and useWaitForTransactionReceipt for managing user transactions and blockchain interactions.

State variables include amount, contract, term, rate, and message, which handle user input and transaction status. The handleSubmit function validates inputs, simulates the transaction, and then executes it. The form includes fields for wallet address, cryptocurrency type, amount, term, and interest rate.

The UI features a form for submitting lending details, sections explaining the benefits and process, and an FAQ. This setup ensures a smooth lending process by managing user inputs and blockchain confirmations efficiently.

ContactUs.tsx

The ContactForm component, built with React and Formspree, facilitates user inquiries and support requests. It integrates Formspree for handling form submissions, and React Toastify for user notifications.

Upon form submission, the handleFormSubmit function prevents the default form behavior and processes the submission using Formspree's handleSubmit method. It also handles errors by logging them and providing user feedback via Toastify notifications.

The form includes fields for name, email, and subject, all of which are required. Each field has corresponding validation error messages displayed using ValidationError from Formspree. The submit button is disabled during the submission process to prevent multiple submissions.

The component is styled using Tailwind CSS, ensuring a responsive and clean design with a focus on user experience.

BDashBoard.tsx

The BDashboard.tsx file is an integral part of the loan management interface, designed to streamline the process of viewing and interacting with loan data. This React component effectively combines functionality and user experience enhancements to create a comprehensive dashboard.

At its core, the component employs React's useState and useEffect hooks to handle dynamic data. Upon initial render, it fetches loan data from the Supabase database's lending_list table. This asynchronous operation ensures that users are presented with up-to-date information. In the event of a data fetch error, the component logs the issue for debugging purposes.

The dashboard features robust data handling capabilities. Users can search for specific loans, filter results based on loan status and duration, and sort data by criteria such as ID, amount, and interest rate. This flexibility is facilitated through a combination of search inputs, filter checkboxes, and sorting dropdown menus.

The user interface of the BDashboard is thoughtfully designed to enhance usability. It includes a search bar for quick loan lookups, sortable tables for clear data presentation, and filter options for refined searches. Each loan entry is displayed with key details—such as ID, status, amount, and interest rate—alongside action buttons that direct users to more detailed loan views.

Overall, the BDashboard.tsx component is a well-crafted tool that integrates React's state management and UI components to deliver a functional and user-friendly loan management dashboard. Its design emphasizes ease of use and efficient data handling, making it a valuable asset in any loan management system.

BDetails.tsx

The BDetails.tsx component provides a detailed and interactive loan management interface within a React application. It is designed to fetch, display, and interact with loan details using various hooks and UI components.

The component starts by importing necessary modules and defining several SVG icons for visual elements. These icons include LockIcon, PercentIcon, ReceiptIcon, WalletIcon, ClockIcon, and ChevronDownIcon, which enhance the UI by providing intuitive visual cues.

The BDetails component itself is a functional React component that manages loan details, user interactions, and contract transactions. It uses useState and useEffect hooks to handle state and side effects. Upon loading, it fetches loan details from the Supabase database based on a loan ID obtained from the URL search parameters. If an error occurs during data fetching, it is logged and displayed to the user.

The component integrates with the Ethereum blockchain using the wagmi library for smart contract interactions. It simulates and writes transactions to borrow tokens, updating the state based on transaction confirmation and success. If the transaction is confirmed, it inserts the borrowing entry into the database and notifies the user through a toast message.

In the user interface, the component presents loan details in a structured format, including lender wallet address, loan amount, duration, cryptocurrency type, interest rate, and status. It also includes a borrow button that triggers the borrowing process, ensuring that the user’s wallet is connected and the necessary details are available.

Additionally, the component features a "How it Works" section that explains the borrowing process in three steps: connecting a wallet, choosing loan terms, and accessing crypto liquidity. There is also a "Frequently Asked Questions" section with collapsible triggers for common queries, enhancing user experience and providing valuable information.

Overall, the BDetails.tsx component is a comprehensive solution for managing loan details and interactions, combining React’s state management with blockchain functionality and user-friendly design.

AboutUs.tsx

The AboutUsPage component presents a well-structured and engaging overview of the CryptoLends platform. It effectively introduces the platform's mission, highlights its core features, and provides an overview of the team behind it.

In terms of icons, the page uses a set of distinct and relevant icons to illustrate key features such as low interest rates, fast approvals, and secure transactions. However, it’s important to ensure that the icons used, such as CurrencyIcon and CoinsIcon, are chosen based on their specific context and intended meaning to avoid any confusion.

The team section includes placeholders for team member avatars, which is a good practice for maintaining layout consistency. It’s crucial to confirm that the placeholder-user.png file is correctly placed in the public folder so that the images load properly. Additionally, the use of AvatarFallback ensures that there is always a fallback display if the image fails to load.

For accessibility, consider adding aria-label attributes to interactive elements like buttons to improve the page’s usability for screen readers and assistive technologies.

The page layout appears responsive, utilizing both grid and flexbox techniques to adapt to different screen sizes. Testing on various devices will help ensure that all elements are displayed as intended across different screen resolutions.

Overall, the AboutUsPage is both informative and user-friendly, featuring clear sections and a layout that effectively communicates the values and team behind CryptoLends.

References

Repository: CryptoLends