Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

feat: Add ENS Reverse Lookup to Create/Load Safe process #3262

Merged
merged 25 commits into from
Jan 21, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a5855ee
feat: Add ENS Reverse Lookup to Load Safe process
usame-algan Jan 10, 2022
a6847e5
build: Add ens domain to provider info
usame-algan Jan 11, 2022
d67909a
feat: Add ens reverse lookup function
usame-algan Jan 11, 2022
442fff1
fix: ENS Lookup only on account change
usame-algan Jan 11, 2022
47e4d0f
chore: Cleanup code + add types
iamacook Jan 12, 2022
d94080c
fix: Tweak logic + add return type
iamacook Jan 12, 2022
8e8dc68
chore: Remove empty string constant
iamacook Jan 12, 2022
2f1d876
fix: Compare against ChainId
iamacook Jan 13, 2022
70d30d5
feat: Add ENS Reverse Lookup to Load Safe process
usame-algan Jan 10, 2022
ec0faee
Merge branch 'safe-creation-reverse-ens-lookup' of github.com:gnosis/…
usame-algan Jan 13, 2022
4aae8f8
chore: Replace reverse ens lookup function from core sdk
usame-algan Jan 13, 2022
c282e51
feat: Add reverse ENS Lookup to create safe process
usame-algan Jan 14, 2022
800c363
chore: Add typing, extract getOwnerName
usame-algan Jan 17, 2022
3962480
refactor: use getOwnerName for load safe review step
usame-algan Jan 17, 2022
5ad3945
chore: jest spy on ens getResolver to fix failing tests
usame-algan Jan 17, 2022
938da79
fix: Don't use typed value as placeholder for owner name
usame-algan Jan 17, 2022
b14bf08
fix: try catch ens resolver
usame-algan Jan 17, 2022
1e9aeb4
build: Use ENS domain part for safe creation and loading
usame-algan Jan 18, 2022
6863634
chore: Rename getDomainPart util function
usame-algan Jan 18, 2022
33ee89c
Merge branch 'dev' into safe-creation-reverse-ens-lookup
usame-algan Jan 18, 2022
9db6155
fix: Move initial ENS fetch, fetch ENS when adding new owners
usame-algan Jan 20, 2022
591b911
refactor: use absolute import paths
usame-algan Jan 20, 2022
6beb294
refactor: Use absolute paths for imports
usame-algan Jan 20, 2022
967df77
fix: Get ENS if new owner is imported with qr code
usame-algan Jan 21, 2022
8cbb27e
Merge remote-tracking branch 'origin/dev' into safe-creation-reverse-…
usame-algan Jan 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/routes/LoadSafePage/LoadSafePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
FIELD_LOAD_IS_LOADING_SAFE_ADDRESS,
FIELD_LOAD_SAFE_ADDRESS,
FIELD_LOAD_SUGGESTED_SAFE_NAME,
FIELD_SAFE_OWNER_ENS_LIST,
FIELD_SAFE_OWNER_LIST,
LoadSafeFormValues,
} from './fields/loadFields'
Expand All @@ -54,6 +55,7 @@ function Load(): ReactElement {
[FIELD_LOAD_SAFE_ADDRESS]: safeAddress,
[FIELD_LOAD_IS_LOADING_SAFE_ADDRESS]: false,
[FIELD_SAFE_OWNER_LIST]: [],
[FIELD_SAFE_OWNER_ENS_LIST]: {},
}
setInitialFormValues(initialValues)
}, [safeAddress, safeRandomName])
Expand All @@ -64,13 +66,13 @@ function Load(): ReactElement {
const ownerEntries = ownerList
.map((owner) => {
const ownerFieldName = `owner-address-${owner.address}`
const ownerNameValue = values[ownerFieldName]
const ownerNameValue = values[ownerFieldName] || values[FIELD_SAFE_OWNER_ENS_LIST][owner.address]
katspaugh marked this conversation as resolved.
Show resolved Hide resolved
return {
...owner,
name: ownerNameValue,
}
})
.filter((owner) => !!owner.name)
.filter(Boolean)
katspaugh marked this conversation as resolved.
Show resolved Hide resolved

const safeEntry = makeAddressBookEntry({
address: checksumAddress(values[FIELD_LOAD_SAFE_ADDRESS] || ''),
Expand Down
2 changes: 2 additions & 0 deletions src/routes/LoadSafePage/fields/loadFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const FIELD_LOAD_SUGGESTED_SAFE_NAME = 'suggestedSafeName'
export const FIELD_LOAD_SAFE_ADDRESS = 'safeAddress'
export const FIELD_LOAD_IS_LOADING_SAFE_ADDRESS = 'isLoadingSafeAddress'
export const FIELD_SAFE_OWNER_LIST = 'safeOwnerList'
export const FIELD_SAFE_OWNER_ENS_LIST = 'safeOwnerENSList'
export const FIELD_SAFE_THRESHOLD = 'safeThreshold'

export type OwnerFieldListItem = {
Expand All @@ -16,5 +17,6 @@ export type LoadSafeFormValues = {
[FIELD_LOAD_SAFE_ADDRESS]?: string
[FIELD_LOAD_IS_LOADING_SAFE_ADDRESS]: boolean
[FIELD_SAFE_OWNER_LIST]: Array<OwnerFieldListItem>
[FIELD_SAFE_OWNER_ENS_LIST]: Record<string, string>
[FIELD_SAFE_THRESHOLD]?: number
}
11 changes: 11 additions & 0 deletions src/routes/LoadSafePage/fields/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
FIELD_LOAD_SUGGESTED_SAFE_NAME,
LoadSafeFormValues,
} from './loadFields'
import { getSDKWeb3Adapter } from '../../../logic/wallets/getWeb3'

export function getLoadSafeName(formValues: LoadSafeFormValues, addressBook: AddressBookMap): string {
let safeAddress = formValues[FIELD_LOAD_SAFE_ADDRESS] || ''
Expand All @@ -17,3 +18,13 @@ export function getLoadSafeName(formValues: LoadSafeFormValues, addressBook: Add
formValues[FIELD_LOAD_SUGGESTED_SAFE_NAME]
)
}

export async function getOwnerName(owner: string, signer: string): Promise<string> {
const sdkWeb3Adapter = getSDKWeb3Adapter(signer)
try {
const ensName = await sdkWeb3Adapter.ensReverseLookup(owner)
return ensName ?? ''
} catch (error) {
return ''
}
}
32 changes: 29 additions & 3 deletions src/routes/LoadSafePage/steps/LoadSafeAddressStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,26 @@ import {
FIELD_LOAD_CUSTOM_SAFE_NAME,
FIELD_LOAD_IS_LOADING_SAFE_ADDRESS,
FIELD_LOAD_SAFE_ADDRESS,
FIELD_SAFE_OWNER_ENS_LIST,
FIELD_SAFE_OWNER_LIST,
FIELD_SAFE_THRESHOLD,
LoadSafeFormValues,
} from '../fields/loadFields'
import NetworkLabel from 'src/components/NetworkLabel/NetworkLabel'
import { getLoadSafeName } from '../fields/utils'
import { getLoadSafeName, getOwnerName } from '../fields/utils'
import { currentChainId } from 'src/logic/config/store/selectors'
import { userAccountSelector } from '../../../logic/wallets/store/selectors'

export const loadSafeAddressStepLabel = 'Name and address'

function LoadSafeAddressStep(): ReactElement {
const [ownersWithName, setOwnersWithName] = useState<AddressBookEntry[]>([])
const [ownersWithENSName, setOwnersWithENSName] = useState<any>([])
const [threshold, setThreshold] = useState<number>()
const [isValidSafeAddress, setIsValidSafeAddress] = useState<boolean>(false)
const [isSafeInfoLoading, setIsSafeInfoLoading] = useState<boolean>(false)
const chainId = useSelector(currentChainId)
const connectedWalletAddress = useSelector(userAccountSelector)

const loadSafeForm = useForm()
const addressBook = useSelector(currentNetworkAddressBookAsMap)
Expand All @@ -64,10 +68,26 @@ function LoadSafeAddressStep(): ReactElement {
try {
const { owners, threshold } = await getSafeInfo(safeAddress)
setIsSafeInfoLoading(false)
const ownersWithName = owners.map(({ value: address }) =>
makeAddressBookEntry(addressBook[address] || { address, name: '', chainId }),
const ownersWithName = owners.map(({ value: address }) => {
return makeAddressBookEntry(addressBook[address] || { address, name: '', chainId })
})

const ownersWithENSName = await Promise.all(
owners.map(async ({ value: address }) => {
const ensName = await getOwnerName(address, connectedWalletAddress)
return makeAddressBookEntry({ address, name: ensName, chainId })
}),
)

const ownersWithENSNameRecord = ownersWithENSName.reduce<Record<string, string>>((acc, { address, name }) => {
return {
...acc,
[address]: name,
}
}, {})

setOwnersWithName(ownersWithName)
setOwnersWithENSName(ownersWithENSNameRecord)
setThreshold(threshold)
setIsValidSafeAddress(true)
} catch (error) {
Expand Down Expand Up @@ -97,6 +117,12 @@ function LoadSafeAddressStep(): ReactElement {
}
}, [ownersWithName, loadSafeForm])

useEffect(() => {
if (ownersWithENSName) {
loadSafeForm.change(FIELD_SAFE_OWNER_ENS_LIST, ownersWithENSName)
}
}, [ownersWithENSName, loadSafeForm])

const handleScan = (value: string, closeQrModal: () => void): void => {
loadSafeForm.change(FIELD_LOAD_SAFE_ADDRESS, value)
closeQrModal()
Expand Down
7 changes: 5 additions & 2 deletions src/routes/LoadSafePage/steps/LoadSafeOwnersStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import PrefixedEthHashInfo from 'src/components/PrefixedEthHashInfo'
import { disabled, extraSmallFontSize, lg, md, sm } from 'src/theme/variables'
import { minMaxLength } from 'src/components/forms/validator'
import { getExplorerInfo } from 'src/config'
import { FIELD_SAFE_OWNER_LIST } from '../fields/loadFields'
import { FIELD_SAFE_OWNER_ENS_LIST, FIELD_SAFE_OWNER_LIST } from '../fields/loadFields'
import NetworkLabel from 'src/components/NetworkLabel/NetworkLabel'

export const loadSafeOwnersStepLabel = 'Owners'

function LoadSafeOwnersStep(): ReactElement {
const loadSafeForm = useForm()
const ownersWithName = loadSafeForm.getState().values[FIELD_SAFE_OWNER_LIST]
const ownersWithENSName = loadSafeForm.getState().values[FIELD_SAFE_OWNER_ENS_LIST]

return (
<>
Expand All @@ -40,14 +41,16 @@ function LoadSafeOwnersStep(): ReactElement {
<Block margin="md" padding="md">
{ownersWithName.map(({ address, name }, index) => {
const ownerFieldName = `owner-address-${address}`
const ownerName = ownersWithENSName[address] || 'Owner Name'

return (
<OwnerContainer key={address} data-testid="owner-row">
<Col xs={4}>
<FieldContainer
component={TextField}
initialValue={name}
name={ownerFieldName}
placeholder="Owner Name"
placeholder={ownerName}
text="Owner Name"
type="text"
validate={minMaxLength(0, 50)}
Expand Down
4 changes: 3 additions & 1 deletion src/routes/LoadSafePage/steps/ReviewLoadStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Hairline from 'src/components/layout/Hairline'
import PrefixedEthHashInfo from 'src/components/PrefixedEthHashInfo'
import {
FIELD_LOAD_SAFE_ADDRESS,
FIELD_SAFE_OWNER_ENS_LIST,
FIELD_SAFE_OWNER_LIST,
FIELD_SAFE_THRESHOLD,
LoadSafeFormValues,
Expand All @@ -31,6 +32,7 @@ function ReviewLoadStep(): ReactElement {
const addressBook = useSelector(currentNetworkAddressBookAsMap)

const formValues = loadSafeForm.getState().values as LoadSafeFormValues
const ownersWithENSName = formValues[FIELD_SAFE_OWNER_ENS_LIST]
const safeName = getLoadSafeName(formValues, addressBook)
const safeAddress = formValues[FIELD_LOAD_SAFE_ADDRESS] || ''
const threshold = formValues[FIELD_SAFE_THRESHOLD]
Expand Down Expand Up @@ -118,7 +120,7 @@ function ReviewLoadStep(): ReactElement {
<Col align="center" xs={12}>
<PrefixedEthHashInfo
hash={owner.address}
name={owner.name}
name={owner.name || ownersWithENSName[owner.address]}
showAvatar
showCopyBtn
explorerUrl={getExplorerInfo(owner.address)}
Expand Down