-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #328 from rulfo71/feature/10-custom-rpcs
Feature/10 custom rpcs
- Loading branch information
Showing
17 changed files
with
486 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { Button } from 'components/primitives/Button'; | ||
import { ErrorLabel } from 'components/primitives/Forms/ErrorLabel'; | ||
import styled from 'styled-components'; | ||
|
||
export const IconWrapper = styled.div<{ size?: number }>` | ||
${({ theme }) => theme.flexColumnNoWrap}; | ||
align-items: center; | ||
justify-content: center; | ||
& > img, | ||
span { | ||
height: ${({ size }) => (size ? size + 'px' : '24px')}; | ||
width: ${({ size }) => (size ? size + 'px' : '24px')}; | ||
} | ||
${({ theme }) => theme.mediaWidth.upToMedium` | ||
align-items: flex-end; | ||
`}; | ||
`; | ||
|
||
export const ChainName = styled.div` | ||
display: flex; | ||
align-items: center; | ||
color: ${({ theme }) => theme.colors.text}; | ||
margin-left: 0.5rem; | ||
`; | ||
|
||
export const ChainContainer = styled.div` | ||
width: 100%; | ||
display: flex; | ||
justify-content: left; | ||
align-items: center; | ||
border: none; | ||
&:focus { | ||
border: none; | ||
} | ||
`; | ||
|
||
export const ErrorText = styled(ErrorLabel)` | ||
margin-top: 0.5rem; | ||
`; | ||
|
||
export const CustomRPCModal = styled.div` | ||
text-align: -webkit-center; | ||
padding: 1rem; | ||
`; | ||
|
||
export const ChainOptionContainer = styled.div` | ||
background-color: ${({ theme }) => theme.colors.bg1}; | ||
padding: 1rem; | ||
border-radius: ${({ theme }) => theme.radii.curved}; | ||
margin: 1rem 0; | ||
`; | ||
|
||
export const SaveButton = styled(Button)` | ||
width: 100%; | ||
font-weight: 600; | ||
padding: 0.5rem 0; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { useNetwork } from 'wagmi'; | ||
import { CustomRPCOption } from './components'; | ||
import { CustomRPCModal } from './CustomRPC.styled'; | ||
|
||
export const CustomRPC: React.FC = () => { | ||
const { chains } = useNetwork(); | ||
|
||
return ( | ||
<CustomRPCModal> | ||
{chains.map(chain => ( | ||
<CustomRPCOption key={chain.id} chain={chain} /> | ||
))} | ||
</CustomRPCModal> | ||
); | ||
}; |
48 changes: 48 additions & 0 deletions
48
apps/davi/src/components/CustomRPC/components/CustomRPCHeader.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { useTranslation } from 'react-i18next'; | ||
import { | ||
Toggle, | ||
ToggleContainer, | ||
ToggleLabel, | ||
} from 'components/primitives/Forms/Toggle'; | ||
import { ChainContainer, ChainName, IconWrapper } from '../CustomRPC.styled'; | ||
import { Flex } from 'components/primitives/Layout'; | ||
import { Chain } from 'wagmi'; | ||
|
||
interface ChainOptionProps { | ||
chain: Chain; | ||
icon: string; | ||
isDefaultValue: boolean; | ||
setIsDefaultValue: (isDefaultValue: boolean) => void; | ||
} | ||
|
||
export const CustomRPCHeader: React.FC<ChainOptionProps> = ({ | ||
chain, | ||
icon, | ||
isDefaultValue, | ||
setIsDefaultValue, | ||
}) => { | ||
const { t } = useTranslation(); | ||
|
||
const handleChange = () => { | ||
localStorage.setItem(`customRPC[${chain.id}]`, ''); | ||
setIsDefaultValue(!isDefaultValue); | ||
}; | ||
|
||
return ( | ||
<Flex direction="row"> | ||
<ChainContainer> | ||
<IconWrapper>{icon && <img src={icon} alt={'Icon'} />}</IconWrapper> | ||
<ChainName> {chain.name}</ChainName> | ||
</ChainContainer> | ||
<ToggleContainer width="100%"> | ||
<ToggleLabel>{t('customRPC.useDefaultValue')}</ToggleLabel> | ||
<Toggle | ||
value={isDefaultValue} | ||
onChange={handleChange} | ||
small | ||
name="toggle-is-default-value" | ||
/> | ||
</ToggleContainer> | ||
</Flex> | ||
); | ||
}; |
128 changes: 128 additions & 0 deletions
128
apps/davi/src/components/CustomRPC/components/CustomRPCOption.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import { JsonRpcProvider } from '@ethersproject/providers'; | ||
import { | ||
Control, | ||
ControlLabel, | ||
ControlRow, | ||
} from 'components/primitives/Forms/Control'; | ||
import { Input } from 'components/primitives/Forms/Input'; | ||
import { Loading } from 'components/primitives/Loading'; | ||
import { useEffect, useState } from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { getChainIcon } from 'utils'; | ||
import { Chain } from 'wagmi'; | ||
import { | ||
ChainOptionContainer, | ||
ErrorText, | ||
SaveButton, | ||
} from '../CustomRPC.styled'; | ||
import { CustomRPCHeader } from '.'; | ||
|
||
interface CustomRPCOptionProps { | ||
chain: Chain; | ||
} | ||
|
||
interface LocalStorageRPC { | ||
key: string; | ||
value: string; | ||
} | ||
|
||
export const CustomRPCOption: React.FC<CustomRPCOptionProps> = ({ chain }) => { | ||
const [error, setError] = useState(''); | ||
const { t } = useTranslation(); | ||
const localStorageRPCKey = `customRPC[${chain.id}]`; | ||
|
||
const [localStorageRPC, setLocalStorageRPC] = useState<LocalStorageRPC>({ | ||
key: localStorageRPCKey, | ||
value: localStorage.getItem(localStorageRPCKey) ?? '', | ||
}); | ||
|
||
const [isDefaultValue, setIsDefaultValue] = useState(!localStorageRPC.value); | ||
const [rpcValue, setRPCValue] = useState(localStorageRPC.value); | ||
const [isLoading, setIsLoading] = useState(false); | ||
|
||
useEffect(() => { | ||
if (isDefaultValue) { | ||
setRPCValue(''); | ||
} | ||
}, [isDefaultValue]); | ||
|
||
useEffect(() => { | ||
localStorage.setItem(localStorageRPC.key, localStorageRPC.value); | ||
}, [localStorageRPC]); | ||
|
||
const validateRPCValue = async rpcValue => { | ||
const genericError = t('customRPC.genericError'); | ||
try { | ||
setIsLoading(true); | ||
const ethersTestProvider = new JsonRpcProvider(rpcValue); | ||
const network = await ethersTestProvider.getNetwork(); | ||
if (!ethersTestProvider || !network) { | ||
throw new Error(); | ||
} | ||
setIsLoading(false); | ||
if (network.chainId !== chain.id) { | ||
setIsLoading(false); | ||
setError(t('customRPC.wrongChain', { chainName: chain.name })); | ||
return false; | ||
} | ||
} catch (e) { | ||
setIsLoading(false); | ||
setError(genericError); | ||
setLocalStorageRPC({ ...localStorageRPC, value: '' }); | ||
return false; | ||
} | ||
|
||
return true; | ||
}; | ||
|
||
const handleRPCSave = async chain => { | ||
setError(''); | ||
if (!(await validateRPCValue(rpcValue.trim()))) { | ||
return; | ||
} | ||
setError(''); | ||
setLocalStorageRPC({ ...localStorageRPC, value: rpcValue.trim() }); | ||
}; | ||
|
||
return ( | ||
<ChainOptionContainer> | ||
<CustomRPCHeader | ||
chain={chain} | ||
icon={getChainIcon(chain.id)} | ||
isDefaultValue={isDefaultValue} | ||
setIsDefaultValue={setIsDefaultValue} | ||
/> | ||
{!isDefaultValue && ( | ||
<Control> | ||
<> | ||
<ControlLabel>{t('customRPC.customRPCUrl')}</ControlLabel> | ||
<ControlRow> | ||
<Input | ||
value={rpcValue} | ||
data-testid="rpc input" | ||
onChange={e => setRPCValue(e.target.value)} | ||
aria-label={'rpc input'} | ||
placeholder={t('customRPC.enterURL')} | ||
/> | ||
</ControlRow> | ||
<ErrorText>{error}</ErrorText> | ||
</> | ||
{isLoading ? ( | ||
<Loading loading></Loading> | ||
) : ( | ||
<SaveButton | ||
variant="tertiary" | ||
disabled={ | ||
rpcValue.trim() === '' || | ||
rpcValue === localStorage.getItem(localStorageRPCKey) | ||
} | ||
onClick={() => handleRPCSave(chain)} | ||
> | ||
{t('customRPC.saveChanges')} | ||
</SaveButton> | ||
)} | ||
</Control> | ||
)} | ||
</ChainOptionContainer> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { CustomRPCHeader } from './CustomRPCHeader'; | ||
export { CustomRPCOption } from './CustomRPCOption'; |
53 changes: 53 additions & 0 deletions
53
apps/davi/src/components/DecentralizeMode/DecentralizeMode.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { useTranslation } from 'react-i18next'; | ||
import { useState } from 'react'; | ||
import { ReactComponent as Info } from 'assets/images/info.svg'; | ||
import { Tooltip } from 'components/Tooltip'; | ||
import { Toggle, ToggleContainer } from 'components/primitives/Forms/Toggle'; | ||
import { StyledIcon } from 'components/primitives/StyledIcon'; | ||
import { | ||
WalletModalItem, | ||
WalletModalItemTitle, | ||
WalletModalItemValue, | ||
} from 'components/Web3Modals/WalletModal/WalletModal.styled'; | ||
import { BiShapePolygon } from 'react-icons/bi'; | ||
|
||
export const DecentralizeMode: React.FC = () => { | ||
const { t } = useTranslation(); | ||
|
||
const localStorageDecentralizeMode = | ||
localStorage.getItem('decentralizeMode') === 'true'; | ||
const [isDecentralizeMode, setIsDecentralizeMode] = useState( | ||
localStorageDecentralizeMode | ||
); | ||
|
||
const handleDecentralizeModeChanged = () => { | ||
console.log('handleDecentralizeModeChanged'); | ||
|
||
localStorage.setItem('decentralizeMode', String(!isDecentralizeMode)); | ||
setIsDecentralizeMode(!isDecentralizeMode); | ||
}; | ||
return ( | ||
<WalletModalItem> | ||
<WalletModalItemTitle> | ||
<BiShapePolygon size={24} /> | ||
{t('decentralizeMode.decentralizeMode')} | ||
<Tooltip | ||
text={t('decentralizeMode.decentralizeModeTooltip')} | ||
placement="bottom" | ||
> | ||
<StyledIcon src={Info} /> | ||
</Tooltip> | ||
</WalletModalItemTitle> | ||
<WalletModalItemValue> | ||
<ToggleContainer marginRight="0.3rem"> | ||
<Toggle | ||
value={isDecentralizeMode} | ||
onChange={handleDecentralizeModeChanged} | ||
small | ||
name="toggle-is-default-value" | ||
/> | ||
</ToggleContainer> | ||
</WalletModalItemValue> | ||
</WalletModalItem> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
9c05d42
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
davi – ./
davi-git-develop-dxgov.vercel.app
davi-dxgov.vercel.app
project-davi.dev
davi-monorepo-davi.vercel.app