UNPKG

@foreverrbum/ethsign

Version:

This package will allow you to electronically sign documents within your application

215 lines (201 loc) 9.87 kB
import React, {useState, useEffect} from 'react'; import PhonebookIcon from '../../assets/phonebook.svg'; import XIcon from '../../assets/x.svg'; import EditIcon from '../../assets/edit.svg'; import {storeNotif} from '../../helpers/dashboard'; import Identicon from 'react-identicons'; import { ethers } from 'ethers'; import { useIntl, FormattedMessage } from 'react-intl'; import { getAlias } from '../../helpers/signer'; import { format } from 'highcharts'; const SignerForm = (props) => { const {ensEnabled, signers, provider, handleSigners, id, initialValue, ethAccount, added, inReview, updateStoredData} = props; const [currentSigner, handleCurrentSigner] = useState(initialValue); const [loading, handleLoading] = useState(false) const [final, handleFinal] = useState(initialValue? true:false); const [error, handleError] = useState(false); const [remove, handleRemove] = useState(false); const [entered, handleEntered] = useState(0); // 0 = address, 1 = ens alias const { formatMessage } = useIntl(); const addSigner = async () => { handleLoading(true); let curSigner = document.getElementById('signer-'+id).value?.toLowerCase(); if(!curSigner || curSigner.length === 0) { handleLoading(false); return; } curSigner = curSigner.trim(); let temp = signers; const index = _.findIndex(temp, function(o) { return (o.address == curSigner || o.alias == curSigner); }); if (index>-1){ // if address has already been added to signers storeNotif(formatMessage({id: 'ERROR'}), formatMessage({id: 'THE_SIGNER_HAS_ALREADY_BEEN_ADDED'}), "danger") handleLoading(false) return; } else if(ensEnabled) { provider.resolveName(curSigner).then(async (address) => { // resolve is the address if curSigner is an address/alias if(!address) { // user entered an invalid alias/address if(curSigner.startsWith("0x") ) { storeNotif(formatMessage({id: 'ERROR'}), formatMessage({id: 'THE_ADDRESS_YOU_ENTER_IS_INVALID'}),"danger") } else { storeNotif(formatMessage({id: 'ERROR'}), formatMessage({id: 'THE_SIGNER_NAME_COULD_NOT_BE_FOUND'}),"danger") } handleError(true) handleLoading(false) return; }else{ // user entered a valid alias or an address address = address.toLowerCase(); let alias, avatar = null; if(ethers.utils.isAddress(address)) { // address is valid if(!curSigner.startsWith('0x')) { alias = curSigner; handleEntered(1); // user entered an address } else { alias = await provider.lookupAddress(address) handleEntered(0); // user entered an alias } if (alias){ const resolver = await provider.getResolver(alias); avatar = await resolver.getText("avatar"); } const temp_signer = { address: address, alias: alias, avatar: avatar } temp.push(temp_signer); handleSigners(temp); updateStoredData(temp) handleCurrentSigner(temp_signer) handleFinal(true); handleLoading(false) } else { storeNotif(formatMessage({id: 'ERROR'}), formatMessage({id: 'THE_ADDRESS_YOU_ENTER_IS_INVALID'}),"danger"); handleError(true); handleLoading(false) return; } } }).catch((err)=> { console.log(err) storeNotif(formatMessage({id: 'ERROR'}), formatMessage({id: 'THE_ADDRESS_YOU_ENTER_IS_INVALID'}),"danger"); handleError(true); handleLoading(false) return; }) } else { if(curSigner.startsWith("0x")){ if(ethers.utils.isAddress(curSigner)) { const temp_signer = { address: curSigner, alias: null, avatar: null } temp.push(temp_signer); handleCurrentSigner(temp_signer); handleSigners(temp); updateStoredData(temp) handleFinal(true); } else { storeNotif(formatMessage({id: 'ERROR'}), formatMessage({id: 'THE_ADDRESS_YOU_ENTER_IS_INVALID'}),"danger"); handleLoading(false) handleError(true); return; } }else{ storeNotif(formatMessage({id: 'ERROR'}), formatMessage({id: 'THE_SIGNER_ADDRESS_SHOULD_START_WITH_0X'}),"danger") handleLoading(false) handleError(true) return; } handleLoading(false) } } const removeSigner = () => { if(currentSigner != null){ let temp = signers; temp = _.pull(temp, currentSigner); handleSigners(temp) updateStoredData(temp) } handleRemove(true); } useEffect (()=>{ // if editing if(final == false && currentSigner != null){ document.getElementById('signer-'+id).value = entered == 0 ? currentSigner.address : currentSigner.alias; // remove currentSigner from the signers let temp = signers; temp = _.pull(temp, currentSigner); } handleError(false) },[final]); return ( <> { !remove && <div className="min-h-20 shadow-md px-5 my-4 py-4 flex w-45p relative flex-wrap xs:flex-nowrap md:flex-wrap lg:flex-nowrap"> {!added && !inReview && <img src={XIcon} className="absolute -top-2 -right-2 z-20 cursor-pointer" onClick={()=>{removeSigner()}}/> } <div className="flex flex-grow"> <div className={`flex flex-col mr-3 ${!final && 'self-end'}`}> {final? <> <div className={`identicon flex flex-col justify-center my-auto w-11 h-11 border border-orange-500 rounded-full`}> {ensEnabled && currentSigner?.avatar != null? <img className="w-11 h-11 rounded-full object-cover" src={currentSigner.avatar} /> : <div className="p-2"> <Identicon string={currentSigner?.address?.toLowerCase()} size="25" palette={['#D7EEFF', '#eef2ff', '#991A1A', '#FFDECC', '#E98234', '#D98234','#EE9F63', '#464648']} /> </div> } </div> {!added && <img src={EditIcon} onClick={()=>{handleFinal(false);}} className="xs:hidden mx-auto my-auto mt-2 cursor-pointer"/>} </> : <img src={PhonebookIcon} className='mb-1'></img> } </div> <div className="flex-grow mr-3 xl:mr-8 my-auto"> <div className="font-medium pb-1"> {final ? <> {getAlias(ethAccount, currentSigner, ensEnabled, formatMessage)} </> : <FormattedMessage id="ENS_ALIAS_OR_ADDRESS" /> } </div> {final? <div className="text-gray-200 font-medium select-all"> {currentSigner?.address?.toLowerCase()} </div> : <input className={`focus:outline-none focus:ring focus:border-blue-300 w-full rounded-sm border-b mr-0 border-gray-200 ${error && 'ring border-b border-blue-300'}`} type="text" name="signer" id={`signer-${id}`} placeholder={formatMessage({id: 'ENS_ALIAS_OR_ADDRESS'})} autoComplete="new-password" /> } </div> {!added && final && !inReview && <img src={EditIcon} onClick={()=>{handleFinal(false)}} className="hidden xs:block my-auto px-5 cursor-pointer"/>} </div> {!final && <div className="mt-2 lg:mt-0 w-full xs:w-auto md:w-full lg:w-auto self-end"> <div className="text-center cursor-pointer h-auto rounded-md px-5 py-2 bg-orange-500 hover:bg-orange-600 text-white" onClick={()=>{addSigner()}}> {loading == true? <FormattedMessage id='ADDING' /> : <FormattedMessage id='ADD' /> } </div> </div> } </div> } </> ); } export default SignerForm;