progress with UI contract interaction
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 41s
Details
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 41s
Details
This commit is contained in:
parent
c909f43310
commit
395092b1fd
|
@ -11,12 +11,13 @@ module.exports = {
|
|||
ignorePatterns: ['dist', '.eslintrc.cjs', 'vite.config.js'],
|
||||
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
||||
settings: { react: { version: '18.2' } },
|
||||
plugins: ['react-refresh'],
|
||||
plugins: ['react-refresh', '@stylistic'],
|
||||
rules: {
|
||||
'react/jsx-no-target-blank': 'off',
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
'no-console': 0
|
||||
},
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,13 +10,17 @@
|
|||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@metamask/sdk-react": "^0.16.0",
|
||||
"axios": "^1.6.7",
|
||||
"backend": "file://../backend",
|
||||
"bootstrap": "^5.3.3",
|
||||
"bootswatch": "^5.3.3",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.10.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"web3": "^4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@stylistic/eslint-plugin": "^1.6.3",
|
||||
"@types/react": "^18.2.56",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
|
|
|
@ -1,58 +1,138 @@
|
|||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSDK } from '@metamask/sdk-react';
|
||||
import { Web3 } from 'web3';
|
||||
import './App.css';
|
||||
import Button from 'react-bootstrap/Button';
|
||||
// import './App.css';
|
||||
import DAOArtifact from './assets/DAO.json';
|
||||
import work1Artifact from './assets/Work1.json';
|
||||
|
||||
const work1Address = '0xa513E6E4b8f2a923D98304ec87F64353C4D5C853';
|
||||
const DAOAddress = '0x0165878A594ca255338adfa4d48449f69242Eb8F';
|
||||
|
||||
function App() {
|
||||
// react state to store and show the connected account
|
||||
const [connectedAccounts, setConnectedAccounts] = useState([]);
|
||||
const {
|
||||
sdk, connected, provider, chainId, account, balance,
|
||||
} = useSDK();
|
||||
|
||||
async function connectMetamask() {
|
||||
// instantiate Web3 with the injected provider
|
||||
const web3 = new Web3(window.ethereum);
|
||||
const [work1, setWork1] = useState();
|
||||
const [DAO, setDAO] = useState();
|
||||
const [work1Price, setWork1Price] = useState();
|
||||
const [balanceEther, setBalanceEther] = useState();
|
||||
const [reputation, setReputation] = useState();
|
||||
const [validationPoolCount, setValidationPoolCount] = useState();
|
||||
|
||||
// request user to connect accounts (Metamask will prompt)
|
||||
await window.ethereum.request({ method: 'eth_requestAccounts' });
|
||||
useEffect(() => {
|
||||
if (!provider) return;
|
||||
const web3 = new Web3(provider);
|
||||
const work1Contract = new web3.eth.Contract(work1Artifact.abi, work1Address);
|
||||
const DAOContract = new web3.eth.Contract(DAOArtifact.abi, DAOAddress);
|
||||
const getPrice = async () => {
|
||||
const priceWei = await work1Contract.methods.price().call();
|
||||
setWork1Price(web3.utils.fromWei(priceWei, 'ether'));
|
||||
};
|
||||
const getReputation = async () => {
|
||||
setReputation(await DAOContract.methods.valueOf(0).call());
|
||||
};
|
||||
const getValidationPoolCount = async () => {
|
||||
setValidationPoolCount(await DAOContract.methods.validationPoolCount().call());
|
||||
};
|
||||
getPrice();
|
||||
getReputation();
|
||||
getValidationPoolCount();
|
||||
setWork1(work1Contract);
|
||||
setDAO(DAOContract);
|
||||
}, [provider]);
|
||||
|
||||
// get the connected accounts
|
||||
const accounts = await web3.eth.getAccounts();
|
||||
useEffect(() => {
|
||||
if (provider && balance) {
|
||||
const web3 = new Web3(provider);
|
||||
setBalanceEther(web3.utils.fromWei(balance, 'ether'));
|
||||
}
|
||||
}, [provider, balance]);
|
||||
|
||||
// show the first connected account in the react page
|
||||
setConnectedAccounts(accounts);
|
||||
}
|
||||
const connect = async () => {
|
||||
try {
|
||||
await sdk?.connect();
|
||||
} catch (err) {
|
||||
console.warn('failed to connect..', err);
|
||||
}
|
||||
};
|
||||
|
||||
async function disconnectMetamask() {
|
||||
await window.ethereum.request({
|
||||
method: 'wallet_revokePermissions',
|
||||
params: [
|
||||
{
|
||||
eth_accounts: {},
|
||||
},
|
||||
],
|
||||
const disconnect = async () => {
|
||||
try {
|
||||
sdk?.terminate();
|
||||
} catch (err) {
|
||||
console.warn('failed to disconnect..', err);
|
||||
}
|
||||
};
|
||||
|
||||
const initiateValidationPool = async () => {
|
||||
const subscription = await DAO.events.ValidationPoolInitiated({ fromBlock: 'latest' });
|
||||
subscription.once('data', (event) => console.log('event: validation pool initiated', event));
|
||||
const poolDuration = 0;
|
||||
await DAO.methods.initiateValidationPool(account, poolDuration).send({
|
||||
from: account,
|
||||
gas: 1000000,
|
||||
value: 100,
|
||||
});
|
||||
};
|
||||
|
||||
setConnectedAccounts([]);
|
||||
}
|
||||
const evaluateOutcome = async () => {
|
||||
await DAO.methods.evaluateOutcome(0).send({
|
||||
from: account,
|
||||
gas: 1000000,
|
||||
});
|
||||
};
|
||||
|
||||
// const stakeAvailability = async () => { }
|
||||
|
||||
const requestWork = async () => {
|
||||
work1.events.WorkAssigned(() => {
|
||||
console.log('event callback');
|
||||
});
|
||||
await work1.methods.requestWork().send({
|
||||
from: account,
|
||||
gas: 1000000,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{!window.ethereum && (
|
||||
<>
|
||||
Please download Metamask
|
||||
</>
|
||||
)}
|
||||
{window.ethereum && (
|
||||
<>
|
||||
{/* Button to trigger Metamask connection */}
|
||||
<button type="button" onClick={() => connectMetamask()}>Connect to Metamask</button>
|
||||
{!connected && <Button onClick={() => connect()}>Connect</Button>}
|
||||
|
||||
{/* Button to disconnect Metamask */}
|
||||
<button type="button" onClick={() => disconnectMetamask()}>Disconnect from Metamask</button>
|
||||
|
||||
{/* Display the connected account */}
|
||||
{connectedAccounts.map(
|
||||
(connectedAccount) => <h2 key={connectedAccount}>{connectedAccount}</h2>,
|
||||
)}
|
||||
</>
|
||||
{connected && (
|
||||
<>
|
||||
<div>
|
||||
<div>
|
||||
{chainId && `Chain ID: ${chainId}`}
|
||||
</div>
|
||||
<div>
|
||||
{`Account: ${account}`}
|
||||
</div>
|
||||
<div>
|
||||
{`Balance: ${balanceEther} ETH`}
|
||||
</div>
|
||||
<div>
|
||||
{`REP: ${reputation}`}
|
||||
</div>
|
||||
<Button onClick={() => disconnect()}>Disconnect</Button>
|
||||
</div>
|
||||
<div>
|
||||
{`Validation Pool Count: ${validationPoolCount}`}
|
||||
</div>
|
||||
<div>
|
||||
<Button onClick={() => initiateValidationPool()}>Initiate Validation Pool</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button onClick={() => evaluateOutcome()}>Evaluate Outcome</Button>
|
||||
</div>
|
||||
<div>
|
||||
{`Work1 Price: ${work1Price} ETH`}
|
||||
</div>
|
||||
<div>
|
||||
<Button onClick={() => requestWork()}>Request Work</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,28 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { MetaMaskProvider } from '@metamask/sdk-react';
|
||||
import App from './App';
|
||||
import './index.css';
|
||||
// import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import 'bootswatch/dist/slate/bootstrap.min.css';
|
||||
// import './index.css';
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
<MetaMaskProvider
|
||||
debug={false}
|
||||
sdkOptions={{
|
||||
dappMetadata: {
|
||||
name: 'DGF Prototype',
|
||||
url: window.location.href,
|
||||
},
|
||||
enableAnalytics: false,
|
||||
infuraAPIKey: '579d264c5f534aa1aefd6be323cb1a35',
|
||||
readonlyRPCMap: {
|
||||
'0x7a69': 'http://127.0.0.1:8545/',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<App />
|
||||
</MetaMaskProvider>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
// SPDX-License-Identifier: Unlicense
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
import "./ReputationHolder.sol";
|
||||
|
||||
contract Availability is ReputationHolder {}
|
|
@ -60,7 +60,7 @@ contract DAO is ERC721("Reputation", "REP"), ReputationHolder {
|
|||
address owner,
|
||||
uint256 tokenId
|
||||
) public view returns (uint256 value) {
|
||||
require(ownerOf(tokenId) == owner);
|
||||
require(ownerOf(tokenId) == owner, "NFT owner mismatch");
|
||||
value = valueOf(tokenId);
|
||||
}
|
||||
|
||||
|
@ -82,14 +82,18 @@ contract DAO is ERC721("Reputation", "REP"), ReputationHolder {
|
|||
uint256 toTokenId,
|
||||
uint256 amount
|
||||
) internal {
|
||||
require(amount >= 0);
|
||||
require(valueOf(fromTokenId) >= amount);
|
||||
require(amount >= 0, "Value transfer amount must be positive");
|
||||
require(
|
||||
valueOf(fromTokenId) >= amount,
|
||||
"Source token has insufficient value"
|
||||
);
|
||||
tokenValues[fromTokenId] -= amount;
|
||||
tokenValues[toTokenId] += amount;
|
||||
}
|
||||
|
||||
/// Accept fee to initiate a validation pool
|
||||
/// TODO: Rather than accept author as a parameter, accept a reference to a forum post
|
||||
/// TODO: Constrain duration to allowable range
|
||||
function initiateValidationPool(
|
||||
address author,
|
||||
uint duration
|
||||
|
@ -120,7 +124,7 @@ contract DAO is ERC721("Reputation", "REP"), ReputationHolder {
|
|||
bool inFavor,
|
||||
uint256 tokenId
|
||||
) internal {
|
||||
require(block.timestamp < pool.endTime);
|
||||
require(block.timestamp <= pool.endTime, "Pool end time has passed");
|
||||
Stake storage _stake = pool.stakes[pool.stakeCount++];
|
||||
_stake.sender = sender;
|
||||
_stake.inFavor = inFavor;
|
||||
|
@ -147,8 +151,11 @@ contract DAO is ERC721("Reputation", "REP"), ReputationHolder {
|
|||
/// Evaluate outcome of a validation pool
|
||||
function evaluateOutcome(uint poolIndex) public returns (bool votePasses) {
|
||||
ValidationPool storage pool = validationPools[poolIndex];
|
||||
require(block.timestamp >= pool.endTime);
|
||||
require(pool.resolved == false);
|
||||
require(
|
||||
block.timestamp > pool.endTime,
|
||||
"Pool end time has not yet arrived"
|
||||
);
|
||||
require(pool.resolved == false, "Pool is already resolved");
|
||||
uint256 amountFor;
|
||||
uint256 amountAgainst;
|
||||
Stake storage _stake;
|
||||
|
|
Loading…
Reference in New Issue