-
Notifications
You must be signed in to change notification settings - Fork 88
Conversation
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.
Some initial feedback to unblock you ;-)
src/ens/services/ens/index.ts
Outdated
@@ -0,0 +1,11 @@ | |||
import ENS = require('ez-ens'); |
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.
Putting this file in src/ens/services/ens.ts
should be fine. It's simple enough to not need a directory.
src/ens/resolvers/index.ts
Outdated
@@ -0,0 +1,57 @@ | |||
import { GraphQLScalarType, Kind } from 'graphql'; |
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.
Commit 5ba9227 introduced a change that allows the resolver map to be a function, taking in the previous resolvers and returning new ones that will be merged. Using this approach, ens
wouldn't need to hard-reference the resolvers from core, it would just assume they are there (given the ordering sequence, as core is applied before), and would wrap around them accordingly. The way I see it, ens resolvers resolve the address promise, and call the original resolver that comes in the prev
argument.
src/ens/resolvers/index.ts
Outdated
} | ||
|
||
// tslint:disable-next-line | ||
const Address = new GraphQLScalarType({ |
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.
We should separate the Address
scalar type from the rest into different files, e.g. scalars.ts
and resolvers.ts
(look at how it's done in core).
src/ens/resolvers/index.ts
Outdated
serialize: String, | ||
parseValue: input => (Web3.utils.isAddress(input) || isEnsDomain(input) ? input : undefined), | ||
parseLiteral: ast => { | ||
if (ast.kind !== Kind.STRING || (!Web3.utils.isAddress(ast.value) && !isEnsDomain(ast.value))) { |
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.
We actually want to return a Promise<String>
in all cases, whether it is an ENS domain or not. If it's an ETH address, we'd return Promise.resolve(ast.value)
, whereas if it's an ENS domain, we'd return the promise from the ENS lib.
Then the wrapper resolvers (see above) would resolve the promise before delegating onto the original resolver.
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.
@raulk I'm not sure of how to implement it this way, as context/services are not accessible as they are when declaring a resolver.
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.
You're right. I'm thinking the scalar parsers can return a 1-arg thunk, e.g.
type AddressThunk = (context: EthqlContext) => Promise<string>;
Then the resolver could do something like:
const addr = await params.address(context);
@@ -60,6 +60,7 @@ | |||
"dataloader": "^1.4.0", | |||
"deepmerge": "^2.1.1", | |||
"express": "^4.16.3", | |||
"ez-ens": "^1.0.4", |
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.
Curious as to why this choice of library?
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.
compact + it works. Seemed like a good option.
@raulk I was a little busy these last couple of days. I should have plenty of time to work on this tomorrow. |
@StevenJNPearce just checking in to see if you've got any follow-up questions? |
I was just busy, sorry about the wait. Will let you know if I have any questions. |
@StevenJNPearce any chance we can get an ETC here? We have other things inflight which depend on the ENS integration now. |
e84e331
to
369da6d
Compare
@raulk I took another look at this today and have resolved most of the issues that came up in the review expect one. The one I've not dealt with is #111 (comment) . Whilst I could understand the exmaples in the tests with the commit referenced in your comment, I couldn't get my head round how to implement it - I found the combination of the reduce, merge and functions with (prev, next) arguments a bit confusing. |
@StevenJNPearce yeah, that's a tricky part. I'm happy to accept suggestions regarding a clearer API. The idea here is that some plugins are "decorator" plugins. This is the case of ens. It should not explicitly refer to other resolvers, but it should take any existing ones and "wrap" them in custom logic. Let me have a look and propose a change on your PR. |
src/ens/resolvers/index.ts
Outdated
import resolvers from './resolvers'; | ||
import scalars from './scalars'; | ||
|
||
export default [resolvers, scalars].reduce((prev, curr) => _.merge({}, curr, prev), {}); |
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.
Take for example the account
resolver which now needs to be wrapped in the ENS resolution logic.
Instead of returning a resolvers map here, we would return a function like the following:
export default (prev) => {
const wrappedResolvers = {
Query: {
account: (obj, args, context: EthqlContext) => {
args.address = await args.address(context);
return prev.Query.account(obj, args, context);
}
},
// same for the other affected resolvers
// Block: { transactionsInvolving, transactionsRoles },
};
return _.mergeDeep(prev, wrappedResolvers);
}
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.
@raulk looks like i forgot to comment back here after fixing this last week. You can check it now.
ens plugin ens plugin
1f568fe
to
88ac02e
Compare
@raulk Commenting here as you may have missed my comment on having fixed the last change requested above. |
@raulk I don't see a way to make a pull request against the wiki repository. Maybe you can take the contents of README.md from my last commit and add them to the wiki. |
@StevenJNPearce looking, thanks! |
@StevenJNPearce Good job here. Unfortunately, this PR did introduce a serious regression: non-ENS addresses stopped working. And there were no test cases covering queries with normal addresses with the ENS plugin, so it went unnoticed. Luckily I noticed this, and fixed it for you in 4f6cd81. Strangely, the ConsenSys/ethql CircleCI account hasn't picked up this PR. Looking into that, as I'd like to see a green CircleCI before I merge. |
Fixes #106