From f5bab9ff37420cd903b04209c851b7ff417f7de4 Mon Sep 17 00:00:00 2001 From: Kahn Date: Tue, 26 Mar 2024 12:12:41 +0800 Subject: [PATCH] feat: optimize op eas register. --- .../src/abi/EASRegistrationContract.js | 144 ++++++++++++++++++ .../src/components/Register/Register.js | 9 +- .../RegistrationForm/RegistrationForm.js | 102 ++++++++++--- 3 files changed, 232 insertions(+), 23 deletions(-) create mode 100644 daostar-website/src/abi/EASRegistrationContract.js diff --git a/daostar-website/src/abi/EASRegistrationContract.js b/daostar-website/src/abi/EASRegistrationContract.js new file mode 100644 index 00000000..bffe4368 --- /dev/null +++ b/daostar-website/src/abi/EASRegistrationContract.js @@ -0,0 +1,144 @@ +const EASRegistrationContract = [{ + "inputs": [{"internalType": "address", "name": "_admin", "type": "address"}], + "stateMutability": "nonpayable", + "type": "constructor" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, {"indexed": true, "internalType": "bytes32", "name": "newAdminRole", "type": "bytes32"}], + "name": "RoleAdminChanged", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, {"indexed": true, "internalType": "address", "name": "sender", "type": "address"}], + "name": "RoleGranted", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, {"indexed": true, "internalType": "address", "name": "sender", "type": "address"}], + "name": "RoleRevoked", + "type": "event" +}, { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "MEMBER_ROLE", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "components": [{ + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, {"internalType": "bytes32", "name": "schema", "type": "bytes32"}, { + "internalType": "uint64", + "name": "time", + "type": "uint64" + }, {"internalType": "uint64", "name": "expirationTime", "type": "uint64"}, { + "internalType": "uint64", + "name": "revocationTime", + "type": "uint64" + }, {"internalType": "bytes32", "name": "refUID", "type": "bytes32"}, { + "internalType": "address", + "name": "recipient", + "type": "address" + }, {"internalType": "address", "name": "attester", "type": "address"}, { + "internalType": "bool", + "name": "revocable", + "type": "bool" + }, {"internalType": "bytes", "name": "data", "type": "bytes"}], + "internalType": "struct Attestation", + "name": "attestation", + "type": "tuple" + }], + "name": "createFromEAS", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}], + "name": "getRoleAdmin", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "to", "type": "address"}], + "name": "grantMember", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "internalType": "address", + "name": "account", + "type": "address" + }], "name": "grantRole", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "internalType": "address", + "name": "account", + "type": "address" + }], + "name": "hasRole", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "internalType": "address", + "name": "account", + "type": "address" + }], "name": "renounceRole", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [], + "name": "resolver", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "to", "type": "address"}], + "name": "revokeMember", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "internalType": "address", + "name": "account", + "type": "address" + }], "name": "revokeRole", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "_resolver", "type": "address"}], + "name": "setResolver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "bytes4", "name": "interfaceId", "type": "bytes4"}], + "name": "supportsInterface", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function" +}]; + +export default EASRegistrationContract; diff --git a/daostar-website/src/components/Register/Register.js b/daostar-website/src/components/Register/Register.js index 391f137b..0b7d1c6c 100644 --- a/daostar-website/src/components/Register/Register.js +++ b/daostar-website/src/components/Register/Register.js @@ -22,7 +22,7 @@ const Register = (props) => { const [registrationScreen, setRegistrationScreen] = useState('REGISTER'); // REGISTER | REG_RECEIVED const onToggleRegScreen = (screen) => setRegistrationScreen(screen); - + const [registrationData, setRegistrationData] = useState(null); return ( @@ -30,7 +30,7 @@ const Register = (props) => {
{registrationScreen === 'REGISTER' && ( - @@ -38,11 +38,12 @@ const Register = (props) => { {registrationScreen === 'REG_RECEIVED' && ( )} +
- + ) } -export default Register; \ No newline at end of file +export default Register; diff --git a/daostar-website/src/components/Register/RegistrationForm/RegistrationForm.js b/daostar-website/src/components/Register/RegistrationForm/RegistrationForm.js index db5d081d..895572a9 100644 --- a/daostar-website/src/components/Register/RegistrationForm/RegistrationForm.js +++ b/daostar-website/src/components/Register/RegistrationForm/RegistrationForm.js @@ -9,11 +9,16 @@ import { HTMLSelect, InputGroup, Switch, + Dialog, DialogBody, DialogFooter,AnchorButton } from "@blueprintjs/core"; +import { Tooltip2 } from "@blueprintjs/popover2" import FRAMEWORK_URIs from "./FRAMEWORK_URIs"; import { EAS, SchemaEncoder } from "@ethereum-attestation-service/eas-sdk"; import { useSigner } from "../../../utils/wagmi-utils"; -import { useAccount, useNetwork } from "wagmi"; +import { useAccount, useNetwork, useContractRead } from "wagmi"; +import { ethers } from 'ethers'; + +import RegistrationContract from "../../../abi/EASRegistrationContract"; const networkIds = { mainnet: 1, @@ -28,6 +33,8 @@ const RegistrationForm = ({ toggleRegScreen, setRegistrationData }) => { const {address,isConnected} = useAccount(); const signer = useSigner(); const {chain} = useNetwork(); + const [showEASRegisterDialog, setShowEASRegisterDialog] = useState(false); + const [attestationURL, setAttestationURL] = useState(''); const [daoContractNetwork, setDaoContractNetwork] = useState("mainnet"); const onChangeDaoContractNetwork = (e) => { @@ -273,15 +280,17 @@ const RegistrationForm = ({ toggleRegScreen, setRegistrationData }) => { errors.push(`Please connect wallet`); } if(!(chain.id === 10 || chain.id === 11155420)) { - errors.push(`Just support for Optimism`); + errors.push(`Switch to Optimism mainnet`); } // todo optimism eas schema let easscanURL = '' let schemaUid = ''; + let registrationContract = ''; if(chain.id === 11155420) { easscanURL = "https://optimism-sepolia.easscan.org/schema/view"; schemaUid = '0xf90c716cef83b64e4b9cbf5babeb4ee65662e2081535afd76cad37dde744c2dd'; + registrationContract = '0xF124Aca94e664Bfd5373feA9E2410FD799a8a08B' } if (errors.length > 0) { @@ -291,8 +300,24 @@ const RegistrationForm = ({ toggleRegScreen, setRegistrationData }) => { setErrors(null); } + // test + // setAttestationURL(`${easscanURL}/${schemaUid}`); + // setShowEASRegisterDialog(true); + // return; + setRegisterLoading(true); + // check authority + const contract = new ethers.Contract(registrationContract, RegistrationContract, signer); + const memberRole = await contract.MEMBER_ROLE(); + const isMember = await contract.hasRole(memberRole,address); + + if(!isMember) { + setErrors(['you have no authorization']); + setRegisterLoading(false); + return; + } + const schemaEncoder = new SchemaEncoder("string daoName,string daoURI"); const data = [ { name: 'daoName', value: daoName, type: 'string' }, @@ -303,23 +328,32 @@ const RegistrationForm = ({ toggleRegScreen, setRegistrationData }) => { const eas = new EAS('0x4200000000000000000000000000000000000021'); eas.connect(signer); - const attestation = await eas.attest({ - schema: schemaUid, - data: { - recipient: address, - expirationTime: 0, - revocable: true, - refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', - data: encodedData, - value: 0, - }, - }); - console.log("attest:",attestation); - setRegisterLoading(false); - - window.location.href = `${easscanURL}/${schemaUid}`; + try { + const attestation = await eas.attest({ + schema: schemaUid, + data: { + recipient: address, + expirationTime: 0, + revocable: true, + refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', + data: encodedData, + value: 0, + }, + }); + setAttestationURL(`${easscanURL}/${schemaUid}`); + setShowEASRegisterDialog(true); + } catch (e) { + console.log("attest error:",e); + setErrors([`Register Error. ${e}`]); + } finally { + setRegisterLoading(false); + } }; + const onHandleCloseEASRegisterDialog = () => { + setShowEASRegisterDialog(false); + } + const EthNetworksSelect = ( { )} - {registerByEAS && ( + {registerByEAS && !showEASRegisterDialog && (
@@ -555,7 +589,15 @@ const RegistrationForm = ({ toggleRegScreen, setRegistrationData }) => { />
-
+
+
)} + {registerByEAS && showEASRegisterDialog && ( +
+
+

+ + Congratulations, DAO registered. + +

+
+
+ + View onchain + +
+
+ )} );