first commit
|
@ -1,25 +0,0 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
.env
|
11
.gitpod.yml
|
@ -1,11 +0,0 @@
|
|||
# This configuration file was automatically generated by Gitpod.
|
||||
# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml)
|
||||
# and commit this file to your remote git repository to share the goodness with others.
|
||||
|
||||
# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart
|
||||
|
||||
tasks:
|
||||
- init: npm install && npm run build
|
||||
command: npm run start
|
||||
|
||||
|
10
README.md
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Hardhat-Tailwind-React Ethers Starter Kit
|
||||
Ikuti langkah-langkah di bawah ini untuk mengunduh, menginstal, dan menjalankan proyek ini.
|
||||
Langkah-langkah di bawah ini untuk mengunduh, dan menjalankan proyek ini.
|
||||
|
||||
## Dependencies
|
||||
Install
|
||||
|
@ -11,15 +11,15 @@ Install
|
|||
|
||||
|
||||
## Step 1. Clone the project
|
||||
`git clone <PROJECT NAME>`
|
||||
`git clone <NAMA PROJECT>`
|
||||
|
||||
## Step 2. Install dependencies
|
||||
```sh
|
||||
$ cd <PROJECT NAME>
|
||||
$ yarn install # or npm install
|
||||
$ cd <NAMA PROJECT>
|
||||
$ yarn install # atau npm install
|
||||
```
|
||||
## Step 3. Start Hardhat Node
|
||||
Buka terminal dan jalankan perintah di bawah ini.
|
||||
Buka terminal dan jalankan perintah di bawah ini untuk node lokal.
|
||||
```sh
|
||||
$ yarn hardhat node
|
||||
```
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.82b44b3f.css",
|
||||
"main.js": "/static/js/main.ed7d9119.js",
|
||||
"static/media/gambar2.png": "/static/media/gambar2.7b305f6850ce809a4b77.png",
|
||||
"static/media/gambar1.png": "/static/media/gambar1.296084dbca65a169b9ef.png",
|
||||
"static/media/crowd.png": "/static/media/crowd.8559590cdbd5fdf9d435.png",
|
||||
"static/media/block.png": "/static/media/block.28912e0d5fb5aac2a32a.png",
|
||||
"static/media/logo.png": "/static/media/logo.c113459be1a6e40014fa.png",
|
||||
"index.html": "/index.html",
|
||||
"main.82b44b3f.css.map": "/static/css/main.82b44b3f.css.map",
|
||||
"main.ed7d9119.js.map": "/static/js/main.ed7d9119.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.82b44b3f.css",
|
||||
"static/js/main.ed7d9119.js"
|
||||
]
|
||||
}
|
BIN
build/crowd.png
Before Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 3.8 KiB |
|
@ -1 +0,0 @@
|
|||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>BlockXStarter</title><script defer="defer" src="/static/js/main.ed7d9119.js"></script><link href="/static/css/main.82b44b3f.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 9.4 KiB |
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
|
@ -1,107 +0,0 @@
|
|||
/*! Moment Duration Format v2.2.2
|
||||
* https://github.com/jsmreese/moment-duration-format
|
||||
* Date: 2018-02-16
|
||||
*
|
||||
* Duration format plugin function for the Moment.js library
|
||||
* http://momentjs.com/
|
||||
*
|
||||
* Copyright 2018 John Madhavan-Reese
|
||||
* Released under the MIT license
|
||||
*/
|
||||
|
||||
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @remix-run/router v1.6.2
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* React Router DOM v6.11.2
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* React Router v6.11.2
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* [js-sha3]{@link https://github.com/emn178/js-sha3}
|
||||
*
|
||||
* @version 0.8.0
|
||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||
* @copyright Chen, Yi-Cyuan 2015-2018
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/** @license React v16.13.1
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
//! moment.js
|
||||
|
||||
//! moment.js locale configuration
|
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 244 KiB |
Before Width: | Height: | Size: 268 KiB |
Before Width: | Height: | Size: 10 KiB |
|
@ -1,75 +0,0 @@
|
|||
{
|
||||
"_format": "hh-sol-cache-2",
|
||||
"files": {
|
||||
"C:\\Users\\Achmad Sodiq\\Downloads\\flashdisk file faiz\\blockxstarter\\crowdfunding\\src\\contracts\\Crowdfunding.sol": {
|
||||
"lastModificationDate": 1718855249272,
|
||||
"contentHash": "e277a93f7addf6e03effa83c29c6f46e",
|
||||
"sourceName": "src/contracts/Crowdfunding.sol",
|
||||
"solcConfig": {
|
||||
"version": "0.8.11",
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 200
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi",
|
||||
"evm.bytecode",
|
||||
"evm.deployedBytecode",
|
||||
"evm.methodIdentifiers",
|
||||
"metadata"
|
||||
],
|
||||
"": [
|
||||
"ast"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"imports": [],
|
||||
"versionPragmas": [
|
||||
"^0.8.7"
|
||||
],
|
||||
"artifacts": [
|
||||
"Crowdfunding"
|
||||
]
|
||||
},
|
||||
"E:\\blockxstarter super final git\\blockxstarter\\crowdfunding\\src\\contracts\\Crowdfunding.sol": {
|
||||
"lastModificationDate": 1719969053251,
|
||||
"contentHash": "ed6a87ec28f0e0260fc567ac6fffa946",
|
||||
"sourceName": "src/contracts/Crowdfunding.sol",
|
||||
"solcConfig": {
|
||||
"version": "0.8.11",
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 200
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi",
|
||||
"evm.bytecode",
|
||||
"evm.deployedBytecode",
|
||||
"evm.methodIdentifiers",
|
||||
"metadata"
|
||||
],
|
||||
"": [
|
||||
"ast"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"imports": [],
|
||||
"versionPragmas": [
|
||||
"^0.8.7"
|
||||
],
|
||||
"artifacts": [
|
||||
"Crowdfunding"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// This file is included to deal with issues regarding react-scripts v5.0.0 and web3
|
||||
// Provided from Web3 documentation -> https://github.com/ChainSafe/web3.js#troubleshooting-and-known-issues
|
||||
|
||||
const webpack = require('webpack');
|
||||
|
||||
module.exports = function override(config) {
|
||||
const fallback = config.resolve.fallback || {};
|
||||
Object.assign(fallback, {
|
||||
"crypto": require.resolve("crypto-browserify"),
|
||||
"stream": require.resolve("stream-browserify"),
|
||||
"assert": require.resolve("assert"),
|
||||
"http": require.resolve("stream-http"),
|
||||
"https": require.resolve("https-browserify"),
|
||||
"os": require.resolve("os-browserify"),
|
||||
"url": require.resolve("url")
|
||||
})
|
||||
config.resolve.fallback = fallback;
|
||||
config.plugins = (config.plugins || []).concat([
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
Buffer: ['buffer', 'Buffer']
|
||||
})
|
||||
])
|
||||
return config;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
require('@nomiclabs/hardhat-waffle')
|
||||
require('@nomiclabs/hardhat-etherscan')
|
||||
require('dotenv').config()
|
||||
|
||||
const { API_URL, PRIVATE_KEY, ETHERSCAN_API_KEY } = process.env
|
||||
|
||||
module.exports = {
|
||||
defaultNetwork: 'sepolia',
|
||||
networks: {
|
||||
sepolia: {
|
||||
url: API_URL,
|
||||
accounts: [`0x${PRIVATE_KEY}`]
|
||||
},
|
||||
},
|
||||
etherscan: {
|
||||
apiKey: ETHERSCAN_API_KEY
|
||||
},
|
||||
solidity: {
|
||||
version: '0.8.11',
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200,
|
||||
},
|
||||
},
|
||||
},
|
||||
paths: {
|
||||
sources: './src/contracts',
|
||||
artifacts: './src/abis',
|
||||
},
|
||||
mocha: {
|
||||
timeout: 40000,
|
||||
},
|
||||
}
|
26
index.html
|
@ -1,26 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
||||
<!-- Material Icons Link -->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/icon?family=Material+Icons"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<!-- Font Awesome Link -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
|
||||
integrity="sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w=="
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
74
package.json
|
@ -1,74 +0,0 @@
|
|||
{
|
||||
"name": "crowdfunding",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"start": "react-app-rewired start",
|
||||
"build": "react-app-rewired build",
|
||||
"test": "react-app-rewired test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nomiclabs/hardhat-ethers": "^2.1.0",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.3",
|
||||
"@reduxjs/toolkit": "^1.9.5",
|
||||
"ethereum-waffle": "^3.4.4",
|
||||
"ethers": "^5.6.9",
|
||||
"hardhat": "^2.10.1",
|
||||
"ipfs-http-client": "^57.0.3",
|
||||
"moment": "^2.29.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-google-recaptcha": "^3.1.0",
|
||||
"react-hooks-global-state": "^1.0.2",
|
||||
"react-icons": "^4.3.1",
|
||||
"react-identicons": "^1.2.5",
|
||||
"react-moment": "^1.1.2",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-router-dom": "6",
|
||||
"react-scripts": "5.0.0",
|
||||
"react-toastify": "^10.0.5",
|
||||
"react-typed": "^2.0.12",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomiclabs/hardhat-etherscan": "^3.1.8",
|
||||
"@openzeppelin/contracts": "^4.5.0",
|
||||
"@tailwindcss/forms": "0.4.0",
|
||||
"assert": "^2.0.0",
|
||||
"autoprefixer": "10.4.2",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-stage-2": "^6.24.1",
|
||||
"babel-preset-stage-3": "^6.24.1",
|
||||
"babel-register": "^6.26.0",
|
||||
"buffer": "^6.0.3",
|
||||
"chai": "^4.3.6",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"dotenv": "^16.0.0",
|
||||
"https-browserify": "^1.0.0",
|
||||
"mnemonics": "^1.1.3",
|
||||
"os-browserify": "^0.3.0",
|
||||
"postcss": "8.4.5",
|
||||
"process": "^0.11.10",
|
||||
"react-app-rewired": "^2.1.11",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"stream-http": "^3.2.0",
|
||||
"tailwindcss": "3.0.18",
|
||||
"url": "^0.11.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
BIN
public/crowd.png
Before Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 3.8 KiB |
|
@ -1,43 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>BlockXStarter</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 9.4 KiB |
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"address": "0xf17828b611D2b4601EDc2C361cB67B1de112b5e5"
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"_format": "hh-sol-dbg-1",
|
||||
"buildInfo": "..\\..\\..\\build-info\\61fd3f84cc5c7185fe7b64e3f4c1e380.json"
|
||||
}
|
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 244 KiB |
Before Width: | Height: | Size: 268 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 9.3 KiB |
|
@ -1,20 +0,0 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap');
|
||||
|
||||
* html {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
|
@ -1,270 +0,0 @@
|
|||
import abi from '../abis/src/contracts/Crowdfunding.sol/Crowdfunding.json'
|
||||
import address from '../abis/contractAddress.json'
|
||||
import { getGlobalState, setGlobalState } from '../store'
|
||||
import { ethers } from 'ethers'
|
||||
|
||||
const { ethereum } = window
|
||||
const contractAddress = address.address
|
||||
const contractAbi = abi.abi
|
||||
let tx
|
||||
|
||||
const connectWallet = async () => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
const accounts = await ethereum.request({ method: 'eth_requestAccounts' })
|
||||
setGlobalState('connectedAccount', accounts[0]?.toLowerCase())
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const isWallectConnected = async () => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
const accounts = await ethereum.request({ method: 'eth_accounts' })
|
||||
setGlobalState('connectedAccount', accounts[0]?.toLowerCase())
|
||||
|
||||
window.ethereum.on('chainChanged', (chainId) => {
|
||||
window.location.reload()
|
||||
})
|
||||
|
||||
window.ethereum.on('accountsChanged', async () => {
|
||||
setGlobalState('connectedAccount', accounts[0]?.toLowerCase())
|
||||
await isWallectConnected()
|
||||
})
|
||||
|
||||
if (accounts.length) {
|
||||
setGlobalState('connectedAccount', accounts[0]?.toLowerCase())
|
||||
} else {
|
||||
alert('Harap sambungkan dompet.')
|
||||
console.log('Tidak ada akun yang ditemukan.')
|
||||
}
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getEtheriumContract = async () => {
|
||||
const connectedAccount = getGlobalState('connectedAccount')
|
||||
|
||||
if (connectedAccount) {
|
||||
const provider = new ethers.providers.Web3Provider(ethereum)
|
||||
const signer = provider.getSigner()
|
||||
const contract = new ethers.Contract(contractAddress, contractAbi, signer)
|
||||
|
||||
return contract
|
||||
} else {
|
||||
return getGlobalState('contract')
|
||||
}
|
||||
}
|
||||
|
||||
const createProject = async ({
|
||||
title,
|
||||
description,
|
||||
imageURL,
|
||||
cost,
|
||||
expiresAt,
|
||||
category,
|
||||
}) => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
|
||||
const contract = await getEtheriumContract()
|
||||
cost = ethers.utils.parseEther(cost)
|
||||
tx = await contract.createProject(title, description, imageURL, category, cost, expiresAt)
|
||||
await tx.wait()
|
||||
await loadProjects()
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateProject = async ({
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
imageURL,
|
||||
expiresAt,
|
||||
}) => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
|
||||
const contract = await getEtheriumContract()
|
||||
tx = await contract.updateProject(id, title, description, imageURL, expiresAt)
|
||||
await tx.wait()
|
||||
await loadProject(id)
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteProject = async (id) => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
const contract = await getEtheriumContract()
|
||||
await contract.deleteProject(id)
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const loadProjects = async () => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
|
||||
const contract = await getEtheriumContract()
|
||||
const projects = await contract.getProjects()
|
||||
const stats = await contract.stats()
|
||||
|
||||
setGlobalState('stats', structureStats(stats))
|
||||
setGlobalState('projects', structuredProjects(projects))
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const loadProject = async (id) => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
const contract = await getEtheriumContract()
|
||||
const project = await contract.getProject(id)
|
||||
const comments = await contract.getComments(id)
|
||||
|
||||
setGlobalState('project', { ...structuredProjects([project])[0], comments: structuredComments(comments) })
|
||||
} catch (error) {
|
||||
alert(JSON.stringify(error.message))
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const backProject = async (id, amount) => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
const connectedAccount = getGlobalState('connectedAccount')
|
||||
const contract = await getEtheriumContract()
|
||||
amount = ethers.utils.parseEther(amount)
|
||||
|
||||
tx = await contract.backProject(id, {
|
||||
from: connectedAccount,
|
||||
value: amount._hex,
|
||||
})
|
||||
|
||||
await tx.wait()
|
||||
await getBackers(id)
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getBackers = async (id) => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
const contract = await getEtheriumContract()
|
||||
let backers = await contract.getBackers(id)
|
||||
|
||||
setGlobalState('backers', structuredBackers(backers))
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const payoutProject = async (id) => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
const connectedAccount = getGlobalState('connectedAccount')
|
||||
const contract = await getEtheriumContract()
|
||||
|
||||
tx = await contract.payOutProject(id, {
|
||||
from: connectedAccount,
|
||||
})
|
||||
|
||||
await tx.wait()
|
||||
await getBackers(id)
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const addComment = async (id, comment) => {
|
||||
try {
|
||||
if (!ethereum) return alert('Silahkan install Metamask')
|
||||
const contract = await getEtheriumContract()
|
||||
|
||||
tx = await contract.addComment(id, comment)
|
||||
await tx.wait()
|
||||
await loadProject(id)
|
||||
} catch (error) {
|
||||
reportError(error)
|
||||
}
|
||||
}
|
||||
|
||||
const structuredBackers = (backers) =>
|
||||
backers
|
||||
.map((backer) => ({
|
||||
owner: backer.owner.toLowerCase(),
|
||||
refunded: backer.refunded,
|
||||
timestamp: new Date(backer.timestamp.toNumber() * 1000).toJSON(),
|
||||
contribution: parseInt(backer.contribution._hex) / 10 ** 18,
|
||||
}))
|
||||
.reverse()
|
||||
|
||||
const structuredComments = (comments) =>
|
||||
comments
|
||||
.map((comment) => ({
|
||||
commenter: comment.commenter.toLowerCase(),
|
||||
comment: comment.comment,
|
||||
timestamp: new Date(comment.timestamp.toNumber() * 1000).toJSON(),
|
||||
}))
|
||||
.reverse()
|
||||
|
||||
const structuredProjects = (projects) =>
|
||||
projects
|
||||
.map((project) => ({
|
||||
id: project.id.toNumber(),
|
||||
owner: project.owner.toLowerCase(),
|
||||
title: project.title,
|
||||
description: project.description,
|
||||
timestamp: new Date(project.timestamp.toNumber()).getTime(),
|
||||
expiresAt: new Date(project.expiresAt.toNumber()).getTime(),
|
||||
date: toDate(project.expiresAt.toNumber() * 1000),
|
||||
imageURL: project.imageURL,
|
||||
category: project.category,
|
||||
raised: parseInt(project.raised._hex) / 10 ** 18,
|
||||
cost: parseInt(project.cost._hex) / 10 ** 18,
|
||||
backers: project.backers.toNumber(),
|
||||
status: project.status,
|
||||
}))
|
||||
.reverse()
|
||||
|
||||
const toDate = (timestamp) => {
|
||||
const date = new Date(timestamp)
|
||||
const dd = date.getDate() > 9 ? date.getDate() : `0${date.getDate()}`
|
||||
const mm =
|
||||
date.getMonth() + 1 > 9 ? date.getMonth() + 1 : `0${date.getMonth() + 1}`
|
||||
const yyyy = date.getFullYear()
|
||||
return `${yyyy}-${mm}-${dd}`
|
||||
}
|
||||
|
||||
const structureStats = (stats) => ({
|
||||
totalProjects: stats.totalProjects.toNumber(),
|
||||
totalBacking: stats.totalBacking.toNumber(),
|
||||
totalDonations: parseInt(stats.totalDonations._hex) / 10 ** 18,
|
||||
})
|
||||
|
||||
const reportError = (error) => {
|
||||
console.log(error.message)
|
||||
}
|
||||
|
||||
export {
|
||||
connectWallet,
|
||||
isWallectConnected,
|
||||
createProject,
|
||||
updateProject,
|
||||
deleteProject,
|
||||
loadProjects,
|
||||
loadProject,
|
||||
backProject,
|
||||
getBackers,
|
||||
payoutProject,
|
||||
addComment,
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
import moment from 'moment';
|
||||
import { createGlobalState } from 'react-hooks-global-state';
|
||||
|
||||
const { setGlobalState, useGlobalState, getGlobalState } = createGlobalState({
|
||||
createModal: 'scale-0',
|
||||
updateModal: 'scale-0',
|
||||
deleteModal: 'scale-0',
|
||||
backModal: 'scale-0',
|
||||
connectedAccount: '',
|
||||
projects: [],
|
||||
project: null,
|
||||
stats: null,
|
||||
backers: [],
|
||||
});
|
||||
|
||||
const truncate = (text, startChars, endChars, maxLength) => {
|
||||
if (text.length > maxLength) {
|
||||
let start = text.substring(0, startChars);
|
||||
let end = text.substring(text.length - endChars, text.length);
|
||||
while (start.length + end.length < maxLength) {
|
||||
start = start + '.';
|
||||
}
|
||||
return start + end;
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
const daysRemaining = (expiresAt) => {
|
||||
const now = moment();
|
||||
const expiryDate = moment(Number(expiresAt + '000'));
|
||||
|
||||
const timeDifference = expiryDate.diff(now);
|
||||
|
||||
if (timeDifference <= 0) {
|
||||
return '0 hari';
|
||||
}
|
||||
|
||||
const days = expiryDate.diff(now, 'days');
|
||||
return days <= 1 ? `${days + 1} hari` : `${days + 1} hari`;
|
||||
};
|
||||
|
||||
export {
|
||||
useGlobalState,
|
||||
setGlobalState,
|
||||
getGlobalState,
|
||||
truncate,
|
||||
daysRemaining,
|
||||
};
|
|
@ -1,35 +0,0 @@
|
|||
module.exports = {
|
||||
content: ['./src/**/*.{js,jsx,ts,tsx}'],
|
||||
mode: 'jit',
|
||||
darkMode: false,
|
||||
theme: {
|
||||
fontFamily: {
|
||||
display: ['Open Sans', 'sans-serif'],
|
||||
body: ['Open Sans', 'sans-serif'],
|
||||
},
|
||||
extend: {
|
||||
screens: {
|
||||
mf: '990px',
|
||||
},
|
||||
keyframes: {
|
||||
'slide-in': {
|
||||
'0%': {
|
||||
'-webkit-transform': 'translateX(120%)',
|
||||
transform: 'translateX(120%)',
|
||||
},
|
||||
'100%': {
|
||||
'-webkit-transform': 'translateX(0%)',
|
||||
transform: 'translateX(0%)',
|
||||
},
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
'slide-in': 'slide-in 0.5s ease-out',
|
||||
},
|
||||
},
|
||||
},
|
||||
variants: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [require('@tailwindcss/forms')],
|
||||
}
|