Skip to content
This repository was archived by the owner on Apr 4, 2022. It is now read-only.

add basic ENS name resolution for address lookup #771

Merged
merged 5 commits into from
Oct 18, 2021

Conversation

acolytec3
Copy link
Contributor

Summary

Adds basic ENS name resolution to the address lookup route in the Protocol Explorer.

To Test

  1. <> Open the home page.
  • <<What to expect?>> Verify it contains "Search by Order ID / ETH Address / ENS Address" in the search box
  1. <> Type in a any valid ENS domain and hit submit
  • <<What to expect?>> The order history for the address that owns the ENS domain should be displayed
  • Note: If the provided ENS domain cannot be resolved, just routes to /address/null to display the default error message for an address that cannot be found

Background

  • ENS resolver function:

    • I'm using the web3.eth.ens.getAddress to do the ENS name resolution since that's what is readily available in your web3 provider though that method appears to have been marked deprecated in web3.
    • There any number of alternative ENS resolution packages that could be put here but it might involve switching web3 library to ethers or something (which I also see in your package.json)
  • Address validation regex updates

    • I decided to just update the address validation to check for anything that appeared to be a potentially valid top-level DNS domain (e.g. .com, .org, .xyz). It looks like ENS only currently allows two other TLDs at (.xyz, kred) but according to this article any DNS TLD could conceptually be used so no reason to not let anyone enter any arbitrary valid DNS address to support potential future extensions of ENS.

Copy link
Contributor

@anxolin anxolin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! We love to see contributors. Great initiative

@@ -265,4 +265,4 @@ export const isAnOrderId = (text: string): boolean => text.match(/^0x[a-fA-F0-9]
*
* @param text Possible address string to check
*/
export const isAnAddressAccount = (text: string): boolean => text.match(/^0x[a-fA-F0-9]{40}$/)?.input !== undefined
export const isAnAddressAccount = (text: string): boolean => text.match(/^0x[a-fA-F0-9]{40}$|[a-zA-Z0-9]+\.[a-zA-Z]+$/)?.input !== undefined
Copy link
Contributor

@anxolin anxolin Oct 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we have a separate pattern just for the ENS?

web3.eth.ens
.getAddress(query)
.then((res) => res && res.length > 0 && history.push(`/${pathPrefix}/${res}`))
.catch(() => history.push(`/address/null`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the ENS case, when it cannot be resolved, it should just take you to the default. This is kind of unrelated of this PR (so out of it's scope), however, I mention it because address/null is not a good redirection imo

A good one could be:
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my latest commit, I route to /address/${query} so let me know if it should be something yet different. If it's a valid ENS domain, it will just show no records (since there will be valid ETH address behind it) or else the generic "Page not found" where an invalid address is provided as the query parameter.

Copy link
Contributor

@alfetopito alfetopito left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, thank you for the time to submit this PR, really appreciate it.

I've left a couple of comments in the code.

Regarding the behaviour, I can't get the ENS resolution to work locally.
Any (valid or invalid) ens fails resolution. Did it work out for you fine?
I wonder if I have any local setting making it fail...
screenshot_2021-10-15_10-07-24

@@ -265,4 +265,4 @@ export const isAnOrderId = (text: string): boolean => text.match(/^0x[a-fA-F0-9]
*
* @param text Possible address string to check
*/
export const isAnAddressAccount = (text: string): boolean => text.match(/^0x[a-fA-F0-9]{40}$/)?.input !== undefined
export const isAnAddressAccount = (text: string): boolean => text.match(/^0x[a-fA-F0-9]{40}$|[a-zA-Z0-9]+\.[a-zA-Z]+$/)?.input !== undefined
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ESlist fix

Suggested change
export const isAnAddressAccount = (text: string): boolean => text.match(/^0x[a-fA-F0-9]{40}$|[a-zA-Z0-9]+\.[a-zA-Z]+$/)?.input !== undefined
export const isAnAddressAccount = (text: string): boolean =>
text.match(/^0x[a-fA-F0-9]{40}$|[a-zA-Z0-9]+\.[a-zA-Z]+$/)?.input !== undefined

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think would be best to have a separated query only for ENS addresses.

The way you suggest will force all addresses to be queried against the network, but we do not need that since we already know it's an address simply by the regex.

In the future sure, we could have different checks for smart contracts wallets, tokens, contracts, etc, but that's a task for another time :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, my bad. I added a check in the callback hook that runs the regex again for just the second half (i.e. [a-zA-Z0-9]+\.[a-zA-Z]+$/) to see if it looks like a domain name since an ETH address will never have a period in it so this bypasses the network check when it's just a normal 0x... address.

@acolytec3
Copy link
Contributor Author

Also, I was able to get ens resolution working. I just looked on etherscan for a recent transaction with the settlement contract that comes from a ens domain and used that to test

@alfetopito
Copy link
Contributor

Also, I was able to get ens resolution working. I just looked on etherscan for a recent transaction with the settlement contract that comes from a ens domain and used that to test

I'm sorry, you are right.
I thought I was using a valid ENS address but turns out I wasn't :)

Copy link
Contributor

@alfetopito alfetopito left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it's working 👍

Some more suggestions below

@@ -22,8 +23,22 @@ export function useSearchSubmit(): (query: string) => void {
// Orders, transactions, tokens, batches
const path = pathAccordingTo(query)
const pathPrefix = prefixNetwork ? `${prefixNetwork}/${path}` : `${path}`

query && query.length > 0 && history.push(`/${pathPrefix}/${query}`)
if (pathPrefix === 'address' && query.match(/[a-zA-Z0-9]+\.[a-zA-Z]+$/)?.input !== undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you refactor the ENS regex and reuse here and in the isAnAddressAccount helper?

I'm thinking something like:

isEns(query:string) => boolean

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I was testing locally and you'd want to compare 'address' against path, not pathPrefix

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requested changes are made and added a test for the new helper.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you see anything else. Otherwise, it seems to be working well locally and hopefully I've dealt with any test coverage issues.

Comment on lines 32 to 37
history.push(`/address/${res}`)
} else {
history.push(`/address/${query}`)
}
})
.catch(() => history.push(`/address/${query}`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the ${pathPrefix} to keep the network in the query.

Unless you want to always ever redirect to mainnet address?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, just an error on my part in understanding how it works. I added the pathPrefix back.

Copy link
Contributor

@alfetopito alfetopito left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@alfetopito alfetopito merged commit 35c4176 into gnosis:develop Oct 18, 2021
@avsavsavs
Copy link

Hey @acolytec3 great contribution!!!

please join our Discord (chat.cowswap.exchange) so that MasterCoW can DM you ;)

@acolytec3
Copy link
Contributor Author

acolytec3 commented Oct 28, 2021 via email

@avsavsavs
Copy link

awesome, found you!!

This was referenced Nov 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants