From 66b9f3150e4a63b78f17f3e1197fa04a348a82f5 Mon Sep 17 00:00:00 2001 From: leeduckgo Date: Thu, 3 Aug 2023 11:24:06 +0800 Subject: [PATCH] update with lightweight_dao_manager --- src/components/NavBar.tsx | 1 + src/pages/lightweight_dao_manager.tsx | 565 ++++++++++++++++++++++++++ 2 files changed, 566 insertions(+) create mode 100644 src/pages/lightweight_dao_manager.tsx diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx index 1c752ea..2ea960f 100644 --- a/src/components/NavBar.tsx +++ b/src/components/NavBar.tsx @@ -17,6 +17,7 @@ export function NavBar() { + {/* */} diff --git a/src/pages/lightweight_dao_manager.tsx b/src/pages/lightweight_dao_manager.tsx new file mode 100644 index 0000000..a42bf1e --- /dev/null +++ b/src/pages/lightweight_dao_manager.tsx @@ -0,0 +1,565 @@ +import { + DAPP_ADDRESS, + APTOS_FAUCET_URL, + APTOS_NODE_URL, + MODULE_URL +} from "../config/constants"; +import { useWallet } from "@manahippo/aptos-wallet-adapter"; +import { MoveResource } from "@martiandao/aptos-web3-bip44.js/dist/generated"; +import { useState, useEffect } from "react"; +import { + AptosAccount, + WalletClient, + HexString, + AptosClient, +} from "@martiandao/aptos-web3-bip44.js"; + +import { CodeBlock } from "../components/CodeBlock"; + +import newAxios from "../utils/axios_utils"; + +import React, { KeyboardEventHandler } from 'react'; +import CreatableSelect from 'react-select/creatable'; + +import VerifyEthAddrBtn from "../components/VerifyEthAddrBtn"; +import VerifyAptosAddrBtn from "../components/VerifyAptAddrBtn"; + +// import { TypeTagVector } from "@martiandao/aptos-web3-bip44.js/dist/aptos_types"; +// import {TypeTagParser} from "@martiandao/aptos-web3-bip44.js/dist/transaction_builder/builder_utils"; + +// TODO: downcase the tags input + +export default function Home() { + const { account, signAndSubmitTransaction, connected } = useWallet(); + const client = new WalletClient(APTOS_NODE_URL, APTOS_FAUCET_URL); + // const [resource, setResource] = React.useState(); + // const [resource_v2, setResourceV2] = React.useState(); + const [addrInfo, setAddrInfo] = React.useState>([]); + const [hasAddrAggregator, setHasAddrAggregator] = React.useState(false); + const [addAddrInput, setAddAddrInput] = useState<{ + did_type: number; + description: string; + resource_path: string; + addr_type: number; + addr: string; + pubkey: string; + addr_description: string; + chains: Array; + expire_second: number; + }>({ + did_type: 0, + description: "", + resource_path: "", + addr_type: 1, + addr: "", + pubkey: "", + addr_description: "", + chains: [], + expire_second: 0, + }); + const [updateAddrInput, setUpdateAddrInput] = useState<{ + addr: string; + addr_description: string; + chains: Array; + }>({ + addr: "", + addr_description: "", + chains: [], + }); + + const components = { + DropdownIndicator: null, + }; + + interface Option { + readonly label: string; + readonly value: string; + } + + const createOption = (label: string) => ({ + label, + value: label, + }); + const [inputValue, setInputValue] = React.useState(''); + const [chainsValue, setChainsValue] = React.useState([]); + + const [inputValue2, setInputValue2] = React.useState(''); + const [chainsValue2, setChainsValue2] = React.useState([]); + + const handleKeyDown: KeyboardEventHandler = (event) => { + if (!inputValue) return; + switch (event.key) { + case 'Enter': + case 'Tab': + setChainsValue((prev) => [...prev, createOption(inputValue)]); + setAddAddrInput({ ...addAddrInput, chains: [...addAddrInput.chains, inputValue] }) + setInputValue(''); + event.preventDefault(); + } + }; + + const handleKeyDown2: KeyboardEventHandler = (event) => { + if (!inputValue2) return; + switch (event.key) { + case 'Enter': + case 'Tab': + setChainsValue2((prev) => [...prev, createOption(inputValue2)]); + setUpdateAddrInput({ ...updateAddrInput, chains: [...updateAddrInput.chains, inputValue2] }) + setInputValue2(''); + event.preventDefault(); + } + }; + + async function init_did() { + await signAndSubmitTransaction( + do_init_did(), + { gas_unit_price: 100 } + ); + check_addr_aggregator(); + } + + async function add_addr() { + const test = await signAndSubmitTransaction( + do_add_addr(), + { gas_unit_price: 100 } + ); + console.log(test); + get_addr_info(); // refresh after address added + } + + async function update_addr() { + const addrIndex = addrInfo.map((item) => {return item.addr}).indexOf(updateAddrInput.addr); + if(addrIndex !== -1) { // if address to be updated is one of the existing addresses, see if it's verified + const verified = addrInfo[addrIndex].signature !== "0x"; + if(verified) { + console.log("will update verified address"); + const txn = await signAndSubmitTransaction( + do_update_addr_verified(), + { gas_unit_price: 100 } + ); + console.log(txn); + } else { + console.log("will update non verified address"); + const txn = await signAndSubmitTransaction( + do_update_addr_not_verified(), + { gas_unit_price: 100 } + ); + console.log(txn); + } + get_addr_info(); // refresh addr info after update + } else { + alert("Address not found!") + } + } + + async function delete_addr(address: string) { + const txn = await signAndSubmitTransaction( + do_delete_addr(address), + { gas_unit_price: 100 } + ); + console.log(txn); + get_addr_info(); // refresh addr info after update + } + + async function get_addr_info() { + if(account && account.address) { + try { + const addr_aggregator: any = await client.aptosClient.getAccountResource(account.address.toString(), DAPP_ADDRESS + "::addr_aggregator::AddrAggregator"); + // console.log(addr_aggregator); + if(addr_aggregator) { + const addresses: Array = addr_aggregator.data.addrs; + const addr_infos_map_handle: string = addr_aggregator.data.addr_infos_map.handle; + // console.log(addresses); + // console.log(addr_infos_map_handle); + const out: Array = []; + for(let i = 0; i < addresses.length; i++) { + const table_item = await client.aptosClient.getTableItem(addr_infos_map_handle, { + key_type: "0x1::string::String", + value_type: DAPP_ADDRESS + "::addr_info::AddrInfo", + key: addresses[i], + }); + out.push(table_item); + } + console.log(out); + setAddrInfo(out); + } + } catch(err) { + console.log(err); + } + } + } + + useEffect(()=>{get_addr_info()}, [account]); + + function do_init_did() { + const { description, resource_path, addr_type, addr, pubkey, addr_description, chains } = addAddrInput; + return { + type: "entry_function_payload", + function: DAPP_ADDRESS + "::init::init", + type_arguments: [], + arguments: [ + addr_type, + description + ], + }; + } + + function do_add_addr() { + const { description, resource_path, addr_type, addr, pubkey, addr_description, expire_second } = addAddrInput; + return { + type: "entry_function_payload", + function: DAPP_ADDRESS + "::addr_aggregator::add_addr", + type_arguments: [], + arguments: [ + addr_type, + addr, + "", // pubkey + [], // chains + addr_description, + "", // spec fields + expire_second, + ], + }; + } + + function do_update_addr_verified() { + const { addr, chains, addr_description } = updateAddrInput; + return { + type: "entry_function_payload", + function: DAPP_ADDRESS + "::addr_aggregator::update_addr_info_with_chains_and_description_and_expired_at", + type_arguments: [], + arguments: [ + addr, + chains, + addr_description, + 0 + ], + }; + } + + function do_update_addr_not_verified() { + const { addr, chains, addr_description } = updateAddrInput; + return { + type: "entry_function_payload", + function: DAPP_ADDRESS + "::addr_aggregator::update_addr_info_for_non_verification", + type_arguments: [], + arguments: [ + addr, + chains, + addr_description, + ], + }; + } + + function do_delete_addr(address: string) { + // const { addr } = addAddrInput; + return { + type: "entry_function_payload", + function: DAPP_ADDRESS + "::addr_aggregator::delete_addr", + type_arguments: [], + arguments: [ + address, + ], + }; + } + + const render_addr_info = () => { + let out_array = []; + for (let i = 0; i < addrInfo.length; i++) { + out_array.push( + + {addrInfo[i].addr.substring(0, 10) + "..."} + {addrInfo[i].addr_type === "0" ? "ETH" : "APT"} + {addrInfo[i].chains} + {addrInfo[i].description.length > 20 ? addrInfo[i].description.substring(0, 20) : addrInfo[i].description} + {new Date(addrInfo[i].created_at * 1000).toLocaleString()} + {addrInfo[i].expired_at === "0" ? "Never" :new Date(addrInfo[i].expired_at * 1000).toLocaleString()} + {addrInfo[i].updated_at === "0" ? "Never" : new Date(addrInfo[i].updated_at * 1000).toLocaleString()} + {addrInfo[i].signature !== "0x" ? "Yes" : "No"} + {addrInfo[i].addr_type === "0" ? + : + + } + + + + + ); + } + return out_array; + }; + + async function check_addr_aggregator() { + if(account && account.address) { + try { + const addr_aggregator: any = await client.aptosClient.getAccountResource(account.address.toString(), DAPP_ADDRESS + "::addr_aggregator::AddrAggregator"); + console.log("addr_aggregator: " + addr_aggregator.data); + setHasAddrAggregator(true); + } catch(err: any) { + console.log("check_addr_aggregator: " + err); + setHasAddrAggregator(false); + } + } + } + + useEffect(() => {check_addr_aggregator()}, [account]) + useEffect(() => {console.log("has_addr: " + hasAddrAggregator)}, [hasAddrAggregator]) + + // useEffect(() => {console.log("has account:" + account)}, [account]) + + + return ( +
+
+

+ Module Path: + + {DAPP_ADDRESS}::addr_aggregator + +

+
+ {!hasAddrAggregator && ( + <> + + setAddAddrInput({ ...addAddrInput, description: e.target.value }) + } + /> +

+

+ The type of DID Owner:         + +

+         💡 INIT Your DID on Aptos before the other Operations! +

+ + +

+ + )} + + {hasAddrAggregator && + + } + {/* Need the description here. */} + {(hasAddrAggregator && addrInfo) && ( +
+

DID Resources

+ + + + + {/* TODO: Need to Copiable */} + + + + + + + + + + + + + {render_addr_info()} +
AddressAddress TypeChain(s)DescriptionCreated AtExpire AtUpdated AtVerifiedVerifySignatureDelete
+ +

+ +

+ + + setAddAddrInput({ ...addAddrInput, addr: e.target.value }) + } + /> + {/*

+ + setAddAddrInput({ ...addAddrInput, pubkey: e.target.value }) + } + /> */} +

+ + setAddAddrInput({ ...addAddrInput, addr_description: e.target.value }) + } + /> +

+ {/* { + setChainsValue(newValue); + setAddAddrInput({ ...addAddrInput, chains: newValue.map(x => x.value) }) + }} + onInputChange={(newValue) => setInputValue(newValue)} + onKeyDown={handleKeyDown} + placeholder="Chains" + value={chainsValue} + className="mt-8 input-primary w-full select-input" + styles={{ + control: (_, state) => { + return { + // display + display: 'flex', + alignItems: 'center', + // height & width + width: '100%', + height: '3rem', + // outline + outline: state.isFocused ? '2px solid #570df8' : '0px', + outlineOffset: '3px', + // border & padding + borderRadius: '8px', + paddingLeft: '0.4rem', + // size + fontSize: '1rem', + } + }, + }} + /> */} + + setAddAddrInput({ ...addAddrInput, expire_second: parseInt(e.target.value) }) + } + /> +

+ +

+ + + + setUpdateAddrInput({ ...updateAddrInput, addr: e.target.value }) + } + /> +

+ + setUpdateAddrInput({ ...updateAddrInput, addr_description: e.target.value }) + } + /> + {/* { + setChainsValue2(newValue); + setUpdateAddrInput({ ...updateAddrInput, chains: newValue.map(x => x.value) }) + }} + onInputChange={(newValue) => setInputValue2(newValue)} + onKeyDown={handleKeyDown2} + placeholder="Chains" + value={chainsValue2} + className="mt-8 input-primary w-full select-input" + styles={{ + control: (_, state) => { + return { + // display + display: 'flex', + alignItems: 'center', + // height & width + width: '100%', + height: '3rem', + // outline + outline: state.isFocused ? '2px solid #570df8' : '0px', + outlineOffset: '3px', + // border & padding + borderRadius: '8px', + paddingLeft: '0.4rem', + // size + fontSize: '1rem', + } + }, + }} + /> */} + +
+ )} + + + + {/* */} +
+ ); +} \ No newline at end of file