2024-03-10 19:39:15 -05:00
|
|
|
import { useEffect, useState } from 'react';
|
2024-03-07 21:27:37 -06:00
|
|
|
import { useSDK } from '@metamask/sdk-react';
|
2024-03-07 10:58:55 -06:00
|
|
|
import { Web3 } from 'web3';
|
2024-03-07 21:27:37 -06:00
|
|
|
import Button from 'react-bootstrap/Button';
|
|
|
|
// import './App.css';
|
|
|
|
import DAOArtifact from './assets/DAO.json';
|
2024-03-10 19:39:15 -05:00
|
|
|
// import work1Artifact from './assets/Work1.json';
|
|
|
|
|
|
|
|
const contracts = {
|
|
|
|
'0x539': { // Hardhat
|
2024-03-12 17:53:04 -05:00
|
|
|
DAO: '0x8d914D38dD301FC4606f5aa9fEcF8A76389020d3',
|
|
|
|
Work1: '0x050C420Cc4995B41217Eba1B54B82Fd5687e9139',
|
2024-03-10 19:39:15 -05:00
|
|
|
},
|
|
|
|
'0xaa36a7': { // Sepolia
|
|
|
|
DAO: '0x8d914D38dD301FC4606f5aa9fEcF8A76389020d3',
|
|
|
|
Work1: '0x050C420Cc4995B41217Eba1B54B82Fd5687e9139',
|
|
|
|
},
|
|
|
|
};
|
2024-02-21 18:01:41 -06:00
|
|
|
|
|
|
|
function App() {
|
2024-03-07 21:27:37 -06:00
|
|
|
const {
|
|
|
|
sdk, connected, provider, chainId, account, balance,
|
|
|
|
} = useSDK();
|
|
|
|
|
|
|
|
const [DAO, setDAO] = useState();
|
2024-03-10 19:39:15 -05:00
|
|
|
// const [work1, setWork1] = useState();
|
|
|
|
// const [work1Price, setWork1Price] = useState();
|
2024-03-07 21:27:37 -06:00
|
|
|
const [balanceEther, setBalanceEther] = useState();
|
|
|
|
const [reputation, setReputation] = useState();
|
2024-03-10 19:39:15 -05:00
|
|
|
const [totalReputation, setTotalReputation] = useState();
|
2024-03-12 17:53:04 -05:00
|
|
|
const [posts, setPosts] = useState([]);
|
|
|
|
const [validationPools, setValidationPools] = useState([]);
|
2024-03-10 11:55:59 -05:00
|
|
|
|
2024-03-10 19:39:15 -05:00
|
|
|
// const watchReputationToken = useCallback(async () => {
|
|
|
|
// await provider.request({
|
|
|
|
// method: 'wallet_watchAsset',
|
|
|
|
// params: {
|
|
|
|
// type: 'ERC20',
|
|
|
|
// options: {
|
|
|
|
// address: DAOAddress,
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// });
|
|
|
|
// }, [provider]);
|
2024-03-07 21:27:37 -06:00
|
|
|
|
|
|
|
useEffect(() => {
|
2024-03-10 19:39:15 -05:00
|
|
|
if (!provider || !chainId || !account) return;
|
|
|
|
if (!contracts[chainId]) return;
|
2024-03-07 21:27:37 -06:00
|
|
|
const web3 = new Web3(provider);
|
2024-03-10 19:39:15 -05:00
|
|
|
const DAOContract = new web3.eth.Contract(DAOArtifact.abi, contracts[chainId].DAO);
|
|
|
|
// const work1Contract = new web3.eth.Contract(work1Artifact.abi, contracts[chainId].Work1);
|
|
|
|
|
|
|
|
// const fetchPrice = async () => {
|
|
|
|
// const priceWei = await work1Contract.methods.price().call();
|
|
|
|
// setWork1Price(web3.utils.fromWei(priceWei, 'ether'));
|
|
|
|
// };
|
2024-03-10 11:55:59 -05:00
|
|
|
|
|
|
|
const fetchReputation = async () => {
|
2024-03-10 19:39:15 -05:00
|
|
|
setReputation(await DAOContract.methods.balanceOf(account).call());
|
|
|
|
setTotalReputation(await DAOContract.methods.totalSupply().call());
|
2024-03-07 21:27:37 -06:00
|
|
|
};
|
2024-03-10 11:55:59 -05:00
|
|
|
|
2024-03-12 17:53:04 -05:00
|
|
|
const fetchPosts = async () => {
|
|
|
|
const count = await DAOContract.methods.postCount().call();
|
|
|
|
const promises = [];
|
|
|
|
for (let i = 0; i < count; i += 1) {
|
|
|
|
promises.push(DAOContract.methods.posts(i).call());
|
|
|
|
}
|
|
|
|
const fetchedPosts = await Promise.all(promises);
|
|
|
|
setPosts(fetchedPosts);
|
|
|
|
};
|
|
|
|
|
|
|
|
const fetchValidationPools = async () => {
|
|
|
|
const count = await DAOContract.methods.validationPoolCount().call();
|
|
|
|
const promises = [];
|
|
|
|
for (let i = 0; i < count; i += 1) {
|
|
|
|
promises.push(DAOContract.methods.validationPools(i).call());
|
|
|
|
}
|
|
|
|
const pools = await Promise.all(promises);
|
|
|
|
setValidationPools(pools);
|
2024-03-07 21:27:37 -06:00
|
|
|
};
|
2024-03-10 11:55:59 -05:00
|
|
|
|
2024-03-10 19:39:15 -05:00
|
|
|
// fetchPrice();
|
2024-03-10 11:55:59 -05:00
|
|
|
fetchReputation();
|
2024-03-12 17:53:04 -05:00
|
|
|
fetchPosts();
|
|
|
|
fetchValidationPools();
|
2024-03-10 19:39:15 -05:00
|
|
|
// setWork1(work1Contract);
|
2024-03-07 21:27:37 -06:00
|
|
|
setDAO(DAOContract);
|
2024-03-10 11:55:59 -05:00
|
|
|
|
|
|
|
DAOContract.events.ValidationPoolInitiated({ fromBlock: 'latest' }).on('data', (event) => {
|
|
|
|
console.log('event: validation pool initiated', event);
|
2024-03-12 17:53:04 -05:00
|
|
|
fetchPosts();
|
|
|
|
fetchValidationPools();
|
2024-03-10 11:55:59 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
DAOContract.events.ValidationPoolResolved({ fromBlock: 'latest' }).on('data', (event) => {
|
|
|
|
console.log('event: validation pool resolved', event);
|
2024-03-10 19:39:15 -05:00
|
|
|
fetchReputation();
|
2024-03-12 17:53:04 -05:00
|
|
|
fetchValidationPools();
|
2024-03-10 11:55:59 -05:00
|
|
|
});
|
2024-03-10 19:39:15 -05:00
|
|
|
}, [provider, account, chainId]);
|
2024-03-07 21:27:37 -06:00
|
|
|
|
|
|
|
useEffect(() => {
|
2024-03-10 19:39:15 -05:00
|
|
|
if (!provider || balance === undefined) return;
|
|
|
|
const web3 = new Web3(provider);
|
|
|
|
setBalanceEther(web3.utils.fromWei(balance, 'ether'));
|
2024-03-07 21:27:37 -06:00
|
|
|
}, [provider, balance]);
|
|
|
|
|
|
|
|
const connect = async () => {
|
|
|
|
try {
|
|
|
|
await sdk?.connect();
|
|
|
|
} catch (err) {
|
|
|
|
console.warn('failed to connect..', err);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const disconnect = async () => {
|
|
|
|
try {
|
|
|
|
sdk?.terminate();
|
|
|
|
} catch (err) {
|
|
|
|
console.warn('failed to disconnect..', err);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-03-12 17:53:04 -05:00
|
|
|
const addPost = async () => {
|
|
|
|
await DAO.methods.addPost(account).send({
|
|
|
|
from: account,
|
|
|
|
gas: 1000000,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const initiateValidationPool = async (postIndex) => {
|
2024-03-07 21:27:37 -06:00
|
|
|
const poolDuration = 0;
|
2024-03-12 17:53:04 -05:00
|
|
|
await DAO.methods.initiateValidationPool(postIndex, poolDuration).send({
|
2024-03-07 21:27:37 -06:00
|
|
|
from: account,
|
|
|
|
gas: 1000000,
|
|
|
|
value: 100,
|
2024-03-07 10:58:55 -06:00
|
|
|
});
|
2024-03-07 21:27:37 -06:00
|
|
|
};
|
2024-03-07 10:58:55 -06:00
|
|
|
|
2024-03-12 17:53:04 -05:00
|
|
|
const evaluateOutcome = async (poolIndex) => {
|
|
|
|
await DAO.methods.evaluateOutcome(poolIndex).send({
|
2024-03-07 21:27:37 -06:00
|
|
|
from: account,
|
|
|
|
gas: 1000000,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// const stakeAvailability = async () => { }
|
|
|
|
|
2024-03-10 11:55:59 -05:00
|
|
|
// const requestWork = async () => {
|
|
|
|
// work1.events.WorkAssigned(() => {
|
|
|
|
// console.log('event callback');
|
|
|
|
// });
|
|
|
|
// await work1.methods.requestWork().send({
|
|
|
|
// from: account,
|
|
|
|
// gas: 1000000,
|
|
|
|
// });
|
|
|
|
// };
|
2024-03-07 10:58:55 -06:00
|
|
|
|
2024-02-21 18:01:41 -06:00
|
|
|
return (
|
|
|
|
<>
|
2024-03-07 21:27:37 -06:00
|
|
|
{!connected && <Button onClick={() => connect()}>Connect</Button>}
|
|
|
|
|
|
|
|
{connected && (
|
|
|
|
<>
|
|
|
|
<div>
|
2024-03-10 19:39:15 -05:00
|
|
|
{!contracts[chainId] && (
|
|
|
|
<div>
|
|
|
|
Please switch MetaMask to Sepolia testnet!
|
|
|
|
</div>
|
|
|
|
)}
|
2024-03-07 21:27:37 -06:00
|
|
|
<div>
|
|
|
|
{chainId && `Chain ID: ${chainId}`}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
{`Account: ${account}`}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
{`Balance: ${balanceEther} ETH`}
|
|
|
|
</div>
|
|
|
|
<div>
|
2024-03-10 19:39:15 -05:00
|
|
|
{`Your REP: ${reputation}`}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
{`Total REP: ${totalReputation}`}
|
2024-03-07 21:27:37 -06:00
|
|
|
</div>
|
|
|
|
<Button onClick={() => disconnect()}>Disconnect</Button>
|
|
|
|
</div>
|
|
|
|
<div>
|
2024-03-12 17:53:04 -05:00
|
|
|
{`Posts count: ${posts.length}`}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
<table className="table">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>ID</th>
|
|
|
|
<th>Author</th>
|
|
|
|
<th>Actions</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{posts.map((post) => (
|
|
|
|
<tr key={post.id}>
|
|
|
|
<td>{post.id.toString()}</td>
|
|
|
|
<td>{post.author}</td>
|
|
|
|
<td>
|
|
|
|
<Button onClick={() => initiateValidationPool(post.id)}>
|
|
|
|
Initiate Validation Pool
|
|
|
|
</Button>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
))}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
2024-03-07 21:27:37 -06:00
|
|
|
</div>
|
|
|
|
<div>
|
2024-03-12 17:53:04 -05:00
|
|
|
<Button onClick={() => addPost()}>Add Post</Button>
|
2024-03-07 21:27:37 -06:00
|
|
|
</div>
|
|
|
|
<div>
|
2024-03-12 17:53:04 -05:00
|
|
|
{`Validation Pool Count: ${validationPools.length}`}
|
2024-03-07 21:27:37 -06:00
|
|
|
</div>
|
2024-03-10 11:55:59 -05:00
|
|
|
<div>
|
2024-03-12 17:53:04 -05:00
|
|
|
<table className="table">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>ID</th>
|
|
|
|
<th>Post ID</th>
|
|
|
|
<th>Fee</th>
|
|
|
|
<th>Duration</th>
|
|
|
|
<th>End Time</th>
|
|
|
|
<th>Status</th>
|
|
|
|
<th>Actions</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{validationPools.map((pool) => (
|
|
|
|
<tr key={pool.id}>
|
|
|
|
<td>{pool.id.toString()}</td>
|
|
|
|
<td>{pool.postIndex.toString()}</td>
|
|
|
|
<td>{pool.fee.toString()}</td>
|
|
|
|
<td>{pool.duration.toString()}</td>
|
|
|
|
<td>{new Date(Number(pool.endTime) * 1000).toLocaleString()}</td>
|
|
|
|
<td>
|
|
|
|
{pool.resolved && (pool.outcome ? 'Accepted' : 'Rejected')}
|
|
|
|
{!pool.resolved && new Date() < new Date(Number(pool.endTime) * 1000) && 'In Progress'}
|
|
|
|
{!pool.resolved && new Date() >= new Date(Number(pool.endTime) * 1000) && 'Ready to Evaluate'}
|
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
{!pool.resolved && (
|
|
|
|
<Button onClick={() => evaluateOutcome(pool.id)}>
|
|
|
|
Evaluate Outcome
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
))}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
2024-03-10 11:55:59 -05:00
|
|
|
</div>
|
2024-03-07 21:27:37 -06:00
|
|
|
<div>
|
2024-03-10 19:39:15 -05:00
|
|
|
{ /* `Work1 Price: ${work1Price} ETH` */ }
|
2024-03-07 21:27:37 -06:00
|
|
|
</div>
|
|
|
|
<div>
|
2024-03-10 11:55:59 -05:00
|
|
|
{ /* <Button onClick={() => requestWork()}>Request Work</Button> */ }
|
2024-03-07 21:27:37 -06:00
|
|
|
</div>
|
|
|
|
</>
|
2024-03-07 10:58:55 -06:00
|
|
|
)}
|
2024-02-21 18:01:41 -06:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default App;
|