Initial commit from Create Eth App
This commit is contained in:
25
.gitignore
vendored
Normal file
25
.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
coverage
|
||||
|
||||
# production
|
||||
build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env*
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# subgraph
|
||||
packages/subgraph/build/
|
||||
packages/subgraph/src/types/
|
||||
135
README.md
Normal file
135
README.md
Normal file
@@ -0,0 +1,135 @@
|
||||
This project was bootstrapped with [Create Eth App](https://github.com/paulrberg/create-eth-app).
|
||||
|
||||
## Project Structure
|
||||
|
||||
The default template is a monorepo created with [Yarn Workspaces](https://classic.yarnpkg.com/en/docs/workspaces/).
|
||||
|
||||
Workspaces makes it possible to setup multiple packages in such a way that we only need to run `yarn install` once to install all of them in
|
||||
a single pass. Dependencies are hoisted at the root.
|
||||
|
||||
```
|
||||
my-eth-app
|
||||
├── README.md
|
||||
├── node_modules
|
||||
├── package.json
|
||||
├── .gitignore
|
||||
└── packages
|
||||
├── contracts
|
||||
│ ├── README.json
|
||||
│ ├── package.json
|
||||
│ └── src
|
||||
│ ├── abis
|
||||
│ │ ├── erc20.json
|
||||
│ │ └── ownable.json
|
||||
│ ├── addresses.js
|
||||
│ └── index.js
|
||||
├── react-app
|
||||
│ ├── README.md
|
||||
│ ├── node_modules
|
||||
│ ├── package.json
|
||||
│ ├── public
|
||||
│ │ ├── favicon.ico
|
||||
│ │ ├── index.html
|
||||
│ │ ├── logo192.png
|
||||
│ │ ├── logo512.png
|
||||
│ │ ├── manifest.json
|
||||
│ │ └── robots.txt
|
||||
│ └── src
|
||||
│ ├── App.css
|
||||
│ ├── App.js
|
||||
│ ├── App.test.js
|
||||
│ ├── ethereumLogo.svg
|
||||
│ ├── index.css
|
||||
│ ├── index.js
|
||||
│ ├── serviceWorker.js
|
||||
│ └── setupTests.js
|
||||
└── subgraph
|
||||
├── README.md
|
||||
├── abis
|
||||
│ └── erc20.json
|
||||
├── package.json
|
||||
├── schema.graphql
|
||||
├── src
|
||||
│ └── mappings
|
||||
│ ├── tokens.ts
|
||||
│ └── transfers.ts
|
||||
└── subgraph.yaml
|
||||
```
|
||||
|
||||
Owing to this dependency on Yarn Workspaces, Create Eth App can't be used with npm.
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### React App
|
||||
|
||||
#### `yarn react-app:start`
|
||||
|
||||
Runs the React app in development mode.<br>
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will automatically reload if you make changes to the code.<br>
|
||||
You will see the build errors and lint warnings in the console.
|
||||
|
||||
#### `yarn react-app:test`
|
||||
|
||||
Runs the React test watcher in an interactive mode.<br>
|
||||
By default, runs tests related to files changed since the last commit.
|
||||
|
||||
[Read more about testing React.](https://facebook.github.io/create-react-app/docs/running-tests)
|
||||
|
||||
#### `yarn react-app:build`
|
||||
|
||||
Builds the React app for production to the `build` folder.<br />
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.<br />
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the React documentation on [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
#### `yarn react-app:eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `react-app:eject`, you can’t go back!**
|
||||
|
||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` the React app at any time. This command will
|
||||
remove the single build dependency from your React package.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right
|
||||
into the `react-app` package so you have full control over them. All of the commands except `react-app:eject` will still work,
|
||||
but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
||||
|
||||
You don’t have to ever use `react-app:eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
||||
|
||||
### Subgraph
|
||||
|
||||
The Graph is a tool for for indexing events emitted on the Ethereum blockchain. It provides you with an easy-to-use GraphQL API. <br/>
|
||||
|
||||
To learn more, check out the [The Graph documentation](https://thegraph.com/docs).
|
||||
|
||||
#### `yarn subgraph:codegen`
|
||||
|
||||
Generates AssemblyScript types for smart contract ABIs and the subgraph schema.
|
||||
|
||||
#### `yarn subgraph:build`
|
||||
|
||||
Compiles the subgraph to WebAssembly.
|
||||
|
||||
#### `yarn subgraph:auth`
|
||||
|
||||
Before deploying your subgraph, you need to sign up on the
|
||||
[Graph Explorer](https://thegraph.com/explorer/). There, you will be given an access token. Drop it in the command
|
||||
below:
|
||||
|
||||
```sh
|
||||
GRAPH_ACCESS_TOKEN=your-access-token-here yarn subgraph:auth
|
||||
```
|
||||
|
||||
#### `yarn subgraph:deploy`
|
||||
|
||||
Deploys the subgraph to the official Graph Node.<br/>
|
||||
|
||||
Replace `paulrberg/create-eth-app` in the package.json script with your subgraph's name.
|
||||
|
||||
You may also want to [read more about the hosted service](https://thegraph.com/docs/quick-start#hosted-service).
|
||||
27
package.json
Normal file
27
package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "@my-app/monorepo",
|
||||
"version": "1.0.0",
|
||||
"keywords": [
|
||||
"ethereum",
|
||||
"react",
|
||||
"workspaces",
|
||||
"yarn"
|
||||
],
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"subgraph:auth": "yarn workspace @my-app/subgraph auth",
|
||||
"subgraph:codegen": "yarn workspace @my-app/subgraph codegen",
|
||||
"subgraph:build": "yarn workspace @my-app/subgraph build",
|
||||
"subgraph:deploy": "yarn workspace @my-app/subgraph deploy",
|
||||
"react-app:build": "yarn workspace @my-app/react-app build",
|
||||
"react-app:eject": "yarn workspace @my-app/react-app eject",
|
||||
"react-app:ipfs": "yarn workspace @my-app/react-app ipfs",
|
||||
"react-app:start": "yarn workspace @my-app/react-app start",
|
||||
"react-app:test": "yarn workspace @my-app/react-app test"
|
||||
},
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
5
packages/contracts/README.md
Normal file
5
packages/contracts/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## @my-app/contracts
|
||||
|
||||
A minimalist, opinionated structure for managing smart contract ABIs and addresses.
|
||||
|
||||
[Read more about Application Binary Interfaces (ABIs) here](https://ethereum.stackexchange.com/questions/234/what-is-an-abi-and-why-is-it-needed-to-interact-with-contracts).
|
||||
5
packages/contracts/package.json
Normal file
5
packages/contracts/package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "@my-app/contracts",
|
||||
"version": "1.0.0",
|
||||
"main": "./src/index.js"
|
||||
}
|
||||
9
packages/contracts/src/abis.js
Normal file
9
packages/contracts/src/abis.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import erc20Abi from "./abis/erc20.json";
|
||||
import ownableAbi from "./abis/ownable.json";
|
||||
|
||||
const abis = {
|
||||
erc20: erc20Abi,
|
||||
ownable: ownableAbi,
|
||||
};
|
||||
|
||||
export default abis;
|
||||
222
packages/contracts/src/abis/erc20.json
Normal file
222
packages/contracts/src/abis/erc20.json
Normal file
@@ -0,0 +1,222 @@
|
||||
[
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"payable": true,
|
||||
"stateMutability": "payable",
|
||||
"type": "fallback"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
81
packages/contracts/src/abis/ownable.json
Normal file
81
packages/contracts/src/abis/ownable.json
Normal file
@@ -0,0 +1,81 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "previousOwner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnershipTransferred",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "isOwner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "renounceOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
5
packages/contracts/src/addresses.js
Normal file
5
packages/contracts/src/addresses.js
Normal file
@@ -0,0 +1,5 @@
|
||||
// This address points to a dummy ERC-20 contract. Replace it with your own smart contracts.
|
||||
const addresses = {
|
||||
ceaErc20: "0xa6dF0C88916f3e2831A329CE46566dDfBe9E74b7",
|
||||
};
|
||||
export default addresses;
|
||||
4
packages/contracts/src/index.js
Normal file
4
packages/contracts/src/index.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as abis } from "./abis";
|
||||
export { default as addresses } from "./addresses";
|
||||
|
||||
export * from "./addresses";
|
||||
75
packages/react-app/README.md
Normal file
75
packages/react-app/README.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# @my-app/react-app
|
||||
|
||||
This package is a fork of the default app built with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `yarn start`
|
||||
|
||||
Runs the app in development mode.<br>
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will automatically reload if you make changes to the code.<br>
|
||||
You will see the build errors and lint warnings in the console.
|
||||
|
||||
### `yarn test`
|
||||
|
||||
Runs the test watcher in an interactive mode.<br>
|
||||
By default, runs tests related to files changed since the last commit.
|
||||
|
||||
[Read more about testing.](https://facebook.github.io/create-react-app/docs/running-tests)
|
||||
|
||||
### `yarn build`
|
||||
|
||||
Builds the app for production to the `build` folder.<br />
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.<br />
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the React documentation on [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `yarn react-app:eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
|
||||
|
||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` the React app at any time. This command will
|
||||
remove the single build dependency from your React package.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right
|
||||
into your project so you have full control over them. All of the commands except `eject` will still work, but
|
||||
they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
||||
|
||||
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
|
||||
|
||||
### `yarn build` fails to minify
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
|
||||
49
packages/react-app/package.json
Normal file
49
packages/react-app/package.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "@my-app/react-app",
|
||||
"version": "1.0.0",
|
||||
"homepage": "./",
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@my-app/contracts": "^1.0.0",
|
||||
"@apollo/client": "^3.5.10",
|
||||
"@ethersproject/contracts": "^5.6.0",
|
||||
"@ethersproject/providers": "^5.6.0",
|
||||
"@testing-library/dom": "^8.11.3",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.4",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/react": "^17.0.40",
|
||||
"@usedapp/core": "^1.1.5",
|
||||
"ethers": "^5.7.0",
|
||||
"graphql": "^16.3.0",
|
||||
"ipfs-deploy": "^11.2.0",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-scripts": "4.0.3",
|
||||
"styled-components": "^5.3.3"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"build": "react-scripts build",
|
||||
"eject": "react-scripts eject",
|
||||
"ipfs": "yarn build && ipfs-deploy build/",
|
||||
"start": "react-scripts start",
|
||||
"test": "react-scripts test"
|
||||
}
|
||||
}
|
||||
BIN
packages/react-app/public/favicon.ico
Normal file
BIN
packages/react-app/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 305 B |
43
packages/react-app/public/index.html
Normal file
43
packages/react-app/public/index.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!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-eth-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>Ethereum App</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>
|
||||
BIN
packages/react-app/public/logo192.png
Normal file
BIN
packages/react-app/public/logo192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
BIN
packages/react-app/public/logo512.png
Normal file
BIN
packages/react-app/public/logo512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
25
packages/react-app/public/manifest.json
Normal file
25
packages/react-app/public/manifest.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"short_name": "Eth App",
|
||||
"name": "Create Eth 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"
|
||||
}
|
||||
2
packages/react-app/public/robots.txt
Normal file
2
packages/react-app/public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
91
packages/react-app/src/App.js
vendored
Normal file
91
packages/react-app/src/App.js
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { Contract } from "@ethersproject/contracts";
|
||||
import { shortenAddress, useCall, useEthers, useLookupAddress } from "@usedapp/core";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { Body, Button, Container, Header, Image, Link } from "./components";
|
||||
import logo from "./ethereumLogo.png";
|
||||
|
||||
import { addresses, abis } from "@my-app/contracts";
|
||||
import GET_TRANSFERS from "./graphql/subgraph";
|
||||
|
||||
function WalletButton() {
|
||||
const [rendered, setRendered] = useState("");
|
||||
|
||||
const { ens } = useLookupAddress();
|
||||
const { account, activateBrowserWallet, deactivate, error } = useEthers();
|
||||
|
||||
useEffect(() => {
|
||||
if (ens) {
|
||||
setRendered(ens);
|
||||
} else if (account) {
|
||||
setRendered(shortenAddress(account));
|
||||
} else {
|
||||
setRendered("");
|
||||
}
|
||||
}, [account, ens, setRendered]);
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
console.error("Error while connecting wallet:", error.message);
|
||||
}
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (!account) {
|
||||
activateBrowserWallet();
|
||||
} else {
|
||||
deactivate();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{rendered === "" && "Connect Wallet"}
|
||||
{rendered !== "" && rendered}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
function App() {
|
||||
// Read more about useDapp on https://usedapp.io/
|
||||
const { error: contractCallError, value: tokenBalance } =
|
||||
useCall({
|
||||
contract: new Contract(addresses.ceaErc20, abis.erc20),
|
||||
method: "balanceOf",
|
||||
args: ["0x3f8CB69d9c0ED01923F11c829BaE4D9a4CB6c82C"],
|
||||
}) ?? {};
|
||||
|
||||
const { loading, error: subgraphQueryError, data } = useQuery(GET_TRANSFERS);
|
||||
|
||||
useEffect(() => {
|
||||
if (subgraphQueryError) {
|
||||
console.error("Error while querying subgraph:", subgraphQueryError.message);
|
||||
return;
|
||||
}
|
||||
if (!loading && data && data.transfers) {
|
||||
console.log({ transfers: data.transfers });
|
||||
}
|
||||
}, [loading, subgraphQueryError, data]);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Header>
|
||||
<WalletButton />
|
||||
</Header>
|
||||
<Body>
|
||||
<Image src={logo} alt="ethereum-logo" />
|
||||
<p>
|
||||
Edit <code>packages/react-app/src/App.js</code> and save to reload.
|
||||
</p>
|
||||
<Link href="https://reactjs.org">
|
||||
Learn React
|
||||
</Link>
|
||||
<Link href="https://usedapp.io/">Learn useDapp</Link>
|
||||
<Link href="https://thegraph.com/docs/quick-start">Learn The Graph</Link>
|
||||
</Body>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
10
packages/react-app/src/App.test.js
Normal file
10
packages/react-app/src/App.test.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import { render } from "@testing-library/react";
|
||||
import React from "react";
|
||||
|
||||
import App from "./App";
|
||||
|
||||
test("renders learn react link", () => {
|
||||
const { getByText } = render(<App />);
|
||||
const linkElement = getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
55
packages/react-app/src/components/index.js
vendored
Executable file
55
packages/react-app/src/components/index.js
vendored
Executable file
@@ -0,0 +1,55 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
export const Body = styled.div`
|
||||
align-items: center;
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: calc(10px + 2vmin);
|
||||
justify-content: center;
|
||||
margin-top: 40px;
|
||||
`;
|
||||
|
||||
export const Button = styled.button`
|
||||
background-color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
color: #282c34;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
margin: 0px 20px;
|
||||
padding: 12px 24px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
`;
|
||||
|
||||
export const Container = styled.div`
|
||||
background-color: #282c34;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh);
|
||||
`;
|
||||
|
||||
export const Header = styled.header`
|
||||
align-items: center;
|
||||
background-color: #282c34;
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
min-height: 70px;
|
||||
`;
|
||||
|
||||
export const Image = styled.img`
|
||||
height: 40vmin;
|
||||
margin-bottom: 16px;
|
||||
pointer-events: none;
|
||||
`;
|
||||
|
||||
export const Link = styled.a.attrs({
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer",
|
||||
})`
|
||||
color: #61dafb;
|
||||
margin-top: 8px;
|
||||
`;
|
||||
BIN
packages/react-app/src/ethereumLogo.png
Normal file
BIN
packages/react-app/src/ethereumLogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 211 KiB |
15
packages/react-app/src/graphql/subgraph.js
vendored
Normal file
15
packages/react-app/src/graphql/subgraph.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { gql } from "@apollo/client";
|
||||
|
||||
// See more example queries on https://thegraph.com/explorer/subgraph/paulrberg/create-eth-app
|
||||
const GET_TRANSFERS = gql`
|
||||
{
|
||||
transfers(first: 10) {
|
||||
id
|
||||
from
|
||||
to
|
||||
value
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default GET_TRANSFERS;
|
||||
11
packages/react-app/src/index.css
Normal file
11
packages/react-app/src/index.css
Normal file
@@ -0,0 +1,11 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
|
||||
"Droid Sans", "Helvetica Neue", sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
}
|
||||
37
packages/react-app/src/index.js
vendored
Normal file
37
packages/react-app/src/index.js
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
import "./index.css";
|
||||
|
||||
import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client";
|
||||
import { DAppProvider, Mainnet } from "@usedapp/core";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
import App from "./App";
|
||||
|
||||
// IMPORTANT, PLEASE READ
|
||||
// To avoid disruptions in your app, change this to your own Infura project id.
|
||||
// https://infura.io/register
|
||||
const INFURA_PROJECT_ID = "529670718fd74cd2a041466303daecd7";
|
||||
const config = {
|
||||
readOnlyChainId: Mainnet.chainId,
|
||||
readOnlyUrls: {
|
||||
[Mainnet.chainId]: "https://mainnet.infura.io/v3/" + INFURA_PROJECT_ID,
|
||||
},
|
||||
}
|
||||
|
||||
// You should replace this url with your own and put it into a .env file
|
||||
// See all subgraphs: https://thegraph.com/explorer/
|
||||
const client = new ApolloClient({
|
||||
cache: new InMemoryCache(),
|
||||
uri: "https://api.thegraph.com/subgraphs/name/paulrberg/create-eth-app",
|
||||
});
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<DAppProvider config={config}>
|
||||
<ApolloProvider client={client}>
|
||||
<App />
|
||||
</ApolloProvider>
|
||||
</DAppProvider>
|
||||
</React.StrictMode>,
|
||||
document.getElementById("root"),
|
||||
);
|
||||
5
packages/react-app/src/setupTests.js
vendored
Normal file
5
packages/react-app/src/setupTests.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
76
packages/subgraph/README.md
Normal file
76
packages/subgraph/README.md
Normal file
@@ -0,0 +1,76 @@
|
||||
## @my-app/subgraph
|
||||
|
||||
The Graph is a tool for for indexing events emitted on the Ethereum blockchain. It provides you with an easy-to-use GraphQL API.
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### Subgraph
|
||||
|
||||
#### `yarn codegen`
|
||||
|
||||
Generates AssemblyScript types for smart contract ABIs and the subgraph schema.
|
||||
|
||||
#### `yarn build`
|
||||
|
||||
Compiles the subgraph to WebAssembly.
|
||||
|
||||
#### `yarn auth`
|
||||
|
||||
Before deploying your subgraph, you need to sign up on the
|
||||
[Graph Explorer](https://thegraph.com/explorer/). There, you will be given an access token. Drop it in the command
|
||||
below:
|
||||
|
||||
```sh
|
||||
GRAPH_ACCESS_TOKEN=your-access-token-here yarn subgraph:auth
|
||||
```
|
||||
|
||||
#### `yarn deploy`
|
||||
|
||||
Deploys the subgraph to the official Graph Node.<br/>
|
||||
|
||||
Replace `paulrberg/create-eth-app` in the package.json script with your subgraph's name.
|
||||
|
||||
You may also want to [read more about the hosted service](https://thegraph.com/docs/quick-start#hosted-service).
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn The Graph, check out the [The Graph documentation](https://thegraph.com/docs).
|
||||
|
||||
---
|
||||
|
||||
1. Generate types
|
||||
2. Build distributable files
|
||||
3. Deploy to the remote API
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [The Graph documentation](https://thegraph.com/docs).<br/>
|
||||
|
||||
Also consider joining [The Graph Discord server](https://discord.gg/vtvv7FP), where you can seek out help.
|
||||
|
||||
## Common Errors
|
||||
|
||||
### Failed to Compile
|
||||
|
||||
> ✖ Failed to compile subgraph: Failed to compile data source mapping: Import file 'src/types/schema.ts' not found.
|
||||
> Error: Failed to compile data source mapping: Import file 'src/types/schema.ts' not found.
|
||||
|
||||
Run the `yarn subgraph` and this error will go away.
|
||||
|
||||
### No Access Token
|
||||
|
||||
> ✖ No access token provided
|
||||
|
||||
Make sure that you followed the instructions listed above for [yarn auth](#yarn-auth).
|
||||
|
||||
### Failed to Deploy
|
||||
|
||||
> ✖ Failed to deploy to Graph node https://api.thegraph.com/deploy/: Invalid account name or access token
|
||||
|
||||
Make sure that you:
|
||||
|
||||
1. Signed up on the [Graph Explorer](https://thegraph.com/explorer)
|
||||
2. Followed the instructions listed above for [yarn auth](#yarn-auth)
|
||||
3. Replaced `paulrberg/create-eth-app` with your subgraph's name
|
||||
15
packages/subgraph/package.json
Normal file
15
packages/subgraph/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "@my-app/subgraph",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@graphprotocol/graph-cli": "0.28.0",
|
||||
"@graphprotocol/graph-ts": "0.26.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"auth": "graph auth https://api.thegraph.com/ $GRAPH_ACCESS_TOKEN",
|
||||
"build": "graph build",
|
||||
"codegen": "graph codegen --output-dir src/types/",
|
||||
"deploy": "graph deploy paulrberg/create-eth-app --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/"
|
||||
}
|
||||
}
|
||||
13
packages/subgraph/schema.graphql
Normal file
13
packages/subgraph/schema.graphql
Normal file
@@ -0,0 +1,13 @@
|
||||
type Token @entity {
|
||||
id: ID!
|
||||
decimals: Int
|
||||
name: String
|
||||
symbol: String
|
||||
}
|
||||
|
||||
type Transfer @entity {
|
||||
id: ID!
|
||||
from: String!
|
||||
to: String!
|
||||
value: BigInt!
|
||||
}
|
||||
21
packages/subgraph/src/mappings/tokens.ts
Normal file
21
packages/subgraph/src/mappings/tokens.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { Token } from "../types/schema";
|
||||
|
||||
export function addToken(address: string): void {
|
||||
let token: Token | null = Token.load(address);
|
||||
if (token != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
token = new Token(address);
|
||||
if (address == "0xa6dF0C88916f3e2831A329CE46566dDfBe9E74b7") {
|
||||
token.decimals = 18;
|
||||
token.name = "CeaErc20";
|
||||
token.symbol = "CEAERC20";
|
||||
} else {
|
||||
token.decimals = 0;
|
||||
token.name = null;
|
||||
token.symbol = null;
|
||||
}
|
||||
|
||||
token.save();
|
||||
}
|
||||
19
packages/subgraph/src/mappings/transfers.ts
Normal file
19
packages/subgraph/src/mappings/transfers.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Address } from "@graphprotocol/graph-ts";
|
||||
|
||||
import { Transfer as TransferEvent } from "../types/CeaErc20/erc20";
|
||||
import { Transfer } from "../types/schema";
|
||||
import { addToken } from "./tokens";
|
||||
|
||||
export function handleTransfer(event: TransferEvent): void {
|
||||
let transactionHash: string = event.transaction.hash.toHex();
|
||||
let transfer = new Transfer(transactionHash);
|
||||
transfer.from = event.params.from.toHex();
|
||||
transfer.to = event.params.to.toHex();
|
||||
transfer.value = event.params.value;
|
||||
transfer.save();
|
||||
|
||||
let to: Address | null = event.transaction.to;
|
||||
if (to) {
|
||||
addToken(to.toHex());
|
||||
}
|
||||
}
|
||||
26
packages/subgraph/subgraph.yaml
Normal file
26
packages/subgraph/subgraph.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
specVersion: 0.0.4
|
||||
description: Subgraph that indexes the blockchain data
|
||||
repository: https://github.com/sablierhq/sablier-subgraph
|
||||
schema:
|
||||
file: ./schema.graphql
|
||||
dataSources:
|
||||
- kind: ethereum/contract
|
||||
name: CeaErc20
|
||||
network: mainnet
|
||||
source:
|
||||
abi: erc20
|
||||
address: "0xa6dF0C88916f3e2831A329CE46566dDfBe9E74b7"
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.6
|
||||
abis:
|
||||
- name: erc20
|
||||
file: ../contracts/src/abis/erc20.json
|
||||
entities:
|
||||
- Token
|
||||
- Transfer
|
||||
eventHandlers:
|
||||
- event: Transfer(indexed address,indexed address,uint256)
|
||||
handler: handleTransfer
|
||||
file: ./src/mappings/transfers.ts
|
||||
language: wasm/assemblyscript
|
||||
Reference in New Issue
Block a user