Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/AddressBookIdentityProvider #31

Open
wants to merge 3 commits into
base: aragon-master
Choose a base branch
from

Conversation

topocount
Copy link

@topocount topocount commented Sep 20, 2019

This will allow identity badges to show the names stored for addresses in the address book.

One wrinkle:

  • With the LocalIdentityProvider component users are able to easily add a preferred "custom label" on top of the label resolved from the address book provider. However, the address book labels still show as "Custom Label" in the LocalIdentityProvider When they should show as something like "Address Book Entry"

@topocount topocount force-pushed the feat/AddressBookIdentityProvider branch from 5232dfe to 4aa6065 Compare September 21, 2019 00:08
Copy link

@chadoh chadoh left a comment

Choose a reason for hiding this comment

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

A couple notes; I need to look through the rest of the new AddressBookIdentityProvider still


const addressBookAppIds = [
'0x32ec8cc9f3136797e0ae30e7bf3740905b0417b81ff6d4a74f6100f9037425de'
// TODO Add in App Ids for rinkeby and mainnet appIds
Copy link

Choose a reason for hiding this comment

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

Hard-coding known Address Book-type appIds seems like a good, quick short-term solution. In the long-term, if we kept that architecture, I guess the process for a new team to develop a full-featured new Address Book-type app would be:

  1. Build their app
  2. Publish it
  3. Send a PR to aragon.js, adding their app's ID to this array

Has there been a decision around whether Aragon should have this sort of centralized review process, or whether it should be more of a permissionless system? If we want to make this permissionless someday, we will need a different architecture.

Copy link
Author

Choose a reason for hiding this comment

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

I think Aragon eventually wants to develop a way to detect third-party ID providers that don't need to be merged into their repo, so this would improve that process significantly

Copy link

Choose a reason for hiding this comment

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

Should we add a TODO for now, noting that this should eventually become a permissionless system?

Copy link
Author

Choose a reason for hiding this comment

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

This is the kind of thing that won't get developed until there's demand for it, either internally or externally due to this maintenance process becoming unsustainable. I'll update the note and if Brett wants it out, we'll remove it

packages/aragon-wrapper/src/index.js Outdated Show resolved Hide resolved
Copy link

@chadoh chadoh left a comment

Choose a reason for hiding this comment

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

Some questions and ocmments on AddressBookIdentityProvider.

* @param {string} address Address to resolve
* @param {Object} metadata Metadata to modify
* @return {Promise} Resolved success action or rejected error
*/
Copy link

Choose a reason for hiding this comment

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

Since calling modify is not supported for AddressBookIdentityProvider, let's update this comment. Maybe we can use it to explain how modify could end up being called, and why it's useful to have this error-throwing function as a safeguard.

@topocount topocount force-pushed the feat/AddressBookIdentityProvider branch from e9ee7d4 to 1f538bb Compare September 23, 2019 20:23
chadoh
chadoh previously requested changes Sep 24, 2019
Copy link

@chadoh chadoh left a comment

Choose a reason for hiding this comment

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

search and getAll look pretty nice! Here are some quick nitpicks to make them even nicer.

address.toLowerCase().indexOf(searchTerm.toLowerCase()) === 0) ||
name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1
)
.map(([address, { name }]) => ({ name, address }))
Copy link

Choose a reason for hiding this comment

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

If we use reduce, we can do the filter and map in one pass instead of two:

return Object.entries(await this.getAll()).reduce(
  (filtered, [address, { name }]) => {
    const found = (
      isAddressSearch &&
      searchTerm.length > 3 &&
      address.toLowerCase().indexOf(searchTerm.toLowerCase()) === 0
    ) || name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1
    return found ? [ ...filtered, { name, address } ] : filtered
  },
  []
)

Feel free to get rid of aspects of this proposed solution which are maybe too clever, and feel free to come up with better names for variables!

Copy link
Author

Choose a reason for hiding this comment

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

I think this is more of a style point, rather than of of efficiency. I'm actually a big fan of splitting these tasks up between filter and map because it's easier to read imo

return addressBookApps.reduce(async (allEntries, app) => {
const cacheKey = getCacheKey(app.proxyAddress, 'state')
const { entries = [] } = await this.cache.get(cacheKey)
const allEntriesResolved = await allEntries
Copy link

Choose a reason for hiding this comment

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

Given that we return an object ({ ...entriesObject, ...allEntriesResolved }), why do we need this? If we pass in a plain object to start, then we can avoid this, right?

Copy link
Author

Choose a reason for hiding this comment

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

We need this because the anonymous function is asynchronous and returns a Promise that needs to be resolved, even if we start with a plain object as the initial accumulator value

const allEntriesResolved = await allEntries
const entriesObject = entries.reduce((obj, entry) => {
return { ...obj, [entry.addr.toLowerCase()]: entry.data }
}, {})
Copy link

Choose a reason for hiding this comment

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

I really like implicit returns for things like this:

const entriesObject = entries.reduce(
  (obj, entry) => ({ ...obj, [entry.addr.toLowerCase()]: entry.data }),
  {}
)

Separate question: do we want toLowerCase here?

Copy link
Author

Choose a reason for hiding this comment

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

I actually try to avoid implicit returns if the function is going to take up more than one line. I think they can lead to some unnecessary confusion.

return { ...obj, [entry.addr.toLowerCase()]: entry.data }
}, {})
// ensure the entries retrieved from the first-installed address book aren't overwritten
return { ...entriesObject, ...allEntriesResolved }
Copy link

Choose a reason for hiding this comment

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

It's a little strange that getAll starts with an array and works to turn it into an object, just so search can do some work to turn it back into an array. Do we expect getAll to be used somewhere other than within search? That is, is it part of the external API of AddressBookIdentityProvider? If not, if it's only used in search, then we could keep it as an array here and do less work in search.

t.plan(3)
const provider = t.context.addressBookIdentityProvider
let result = await provider.search('0x3a')
t.deepEqual(result, [ { name: 'testEntity', address: '0x3a' } ])
Copy link

Choose a reason for hiding this comment

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

I think it might be nice to also show a search of 0x3, which should return all of the entries.

Copy link
Author

Choose a reason for hiding this comment

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

This isn't possible because an address search won't return unless a full byte is entered in the search

@topocount topocount force-pushed the feat/AddressBookIdentityProvider branch from b5703e3 to 58e368a Compare September 24, 2019 14:42
@topocount topocount dismissed chadoh’s stale review December 12, 2019 17:32

Addressed applicable changes, and justified other decisions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants