-
Notifications
You must be signed in to change notification settings - Fork 53
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
connectApp() #135
connectApp() #135
Conversation
Changes: - Pass a ConnectionContext instance to Organization. - ConnectorInterface is now IOrganizationConnector. - IOrganizationConnector: add a name property. - Prepare the ipfs resolver and injects it into ConnectionContext. - provider => ethersProvider, readProvider => ethereumProvider. - Move the initialization into connect() rather than Organization. - Organization: accept a single ConnectionContext object. - Organization: remove the _connect() method. - Move everything to the SubscriptionHandler type. - Coding style.
Codecov Report
@@ Coverage Diff @@
## master #135 +/- ##
==========================================
- Coverage 23.92% 17.07% -6.86%
==========================================
Files 59 59
Lines 1049 1183 +134
Branches 168 205 +37
==========================================
- Hits 251 202 -49
- Misses 798 981 +183
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
It also now contains the name and network properties.
commit 6456de9 Author: Pierre Bertet <hello@pierre.world> Date: Tue Jul 14 16:08:04 2020 +0100 ConnectorInterface is now IOrganizationConnector It also now contains the name and network properties.
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.
Awesome PR @bpierre 💪 Every package is improving a lot with the latest changes.
There is an important point I notice on the EhtersProvider
initialization. We should figure out if we can override the ensAddress
otherwise create a WebSocket
provider like we are doing for xDai.
I think this solution is already improving the developer experience even it's still a two-step process.
I like your second suggestion about using a method at the core organization level. What you think about naming it: connectApp
? Regardless I will go ahead with this solution first.
examples/list-votes-cli/src/index.ts
Outdated
printOrganization(org) | ||
|
||
const votingInfo = await org.app('voting') | ||
const voting = await votingInfo.connect(votingConnector()) |
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.
Boom ⚡️
@@ -65,8 +64,8 @@ export default class Organization { | |||
return this.#connection.orgAddress | |||
} | |||
|
|||
get provider(): ethers.providers.Provider { | |||
return this.#connection.ethersProvider | |||
get _connection(): ConnectionContext { |
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.
🙌
queries.ALL_VOTES('query'), | ||
{ appAddress, first, skip }, | ||
parseVotes | ||
result => parseVotes(result, this) |
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.
I like this syntax a lot more!
if (chainId === 1) { | ||
return 'https://api.thegraph.com/subgraphs/name/aragon/aragon-voting-mainnet' | ||
} | ||
if (chainId === 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.
We should deploy the apps into xDai 😅. Made this issue: #141
So that connect-core can do as much as possible to simplify the implementation of an app connector. createAppConnector() creates a function ready to be exported by the app connector package, like connectVoting(). It passes to its callback an object providing contextual information about the connection, the current app, the ipfs provider, verbosity, etc. It waits for the app if a promise is provided, and emits an error if the type is incorrect. It handles the possibility to pass a connector name, or a connector name and its configuration, as a secondary parameter. It extends the passed object with the original App. Lastly, it forwards the types of the configuration and the extended app, if declared.
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.
Looking really good, let's merge and try to release sonnish, I want people to start using this new way of working with Connectors! 🙌
|
||
To create a new instance of the connector, you need the specific Tokens app address and a Subgraph URL: | ||
|
||
```javascript | ||
import { TokenManager } from '@aragon/connect-thegraph-tokens' | ||
```js |
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.
The new way is much better! I like that you only interact with the Connect library.
@@ -0,0 +1,59 @@ | |||
import TokenAmount from 'token-amount' |
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.
This isolated examples of how to use the connectors are great. Good idea! 💪
@@ -1,25 +1,25 @@ | |||
import { VotingConnectorTheGraph, Vote, Cast } from '../../src' | |||
|
|||
const VOTING_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/aragon/aragon-voting-rinkeby' | |||
const VOTING_SUBGRAPH_URL = |
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.
I wonder if we should refactor the tests to use the new API or just connect at a lower level like we are currently doing?
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.
Yes I think we could definitely improve the way we test things now that objects are instantiated by the library itself. Maybe the JSON provider could be useful here too. Do you see things we could do now, or should we talk about it separately?
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.
Yes, let's first release version 0.5 and refactor the Intent API and afterwards we can concentrate fully on tests.
if (chainId === 1) { | ||
return 'https://api.thegraph.com/subgraphs/name/aragon/aragon-voting-mainnet' | ||
} | ||
if (chainId === 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.
I'll publish the Tokens and Voting app subgraphs on xDai so we release with support for that network at the app connector level as well.
…onnection-context
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.
That was long, but it looks awesome! Just left some comments (most of them doubts):
const org = connect('myorg.aragonid.eth', 'thegraph') | ||
const voting = connectVoting(org.app('voting')) |
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.
It's so short now! 🏎️
@@ -1,11 +1,14 @@ | |||
{ | |||
"extends": "../../tsconfig.json", | |||
"extends": "@snowpack/app-scripts-react/tsconfig.base.json", |
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.
Snowpack 👁️ ❄️
const provider = new ethers.providers.JsonRpcProvider(env.rpc, env.network) | ||
const wallet = new ethers.Wallet(env.key) | ||
const signer = wallet.connect(provider) |
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.
Should we print the public key of the wallet?
examples/nodejs/src/helpers.ts
Outdated
name, | ||
}) | ||
|
||
return data.repos[0] |
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.
Hmmm, if this returns null (due to a network error or something of the sort), this may just explode. This is probably the reason that makes connectors break if we update our subgraphs as well. Should we prefix it with ?
, or should we just let the user handle it?
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.
(this was part of another PR sorry :s)
It seems like it yes. We should definitely improve the reliability of the parts where data is fetched, it’s something I want to do soon alongside providing better errors. I also think we should consider GraphQLWrapper
to be an object used internally or by app connectors, but not by end users or demos.
} | ||
|
||
if (!value) { | ||
throw new Error(`Network: incorrect value provided.`) |
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.
Hmm, shouldn't we say something like You must provide a "value" argument to the network config
?
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.
Yes we should have something like this at an upper level, but in toNetwork()
there is no concept of configuration yet. I plan to add custom errors for the next version, which will make it much easier to do things like this! 👍
if (value.chainId === undefined) { | ||
throw new Error(`Network: no chainId provided.`) | ||
} | ||
|
||
if (value.name === undefined) { |
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.
This was probably for clarity :P But shouldn't we do !value.chainId
/ !value.name
?
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.
This is to accept a chainId
being 0
or a name
being ""
, just in case someone does that 😄
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.
Awesome work!! Super happy to see this one merged 🙌
Fixes #109
Builds on #136, #137
App connection
This PR adds a new way to connect apps:
connectVoting()
accepts either anApp
or a promise resolving to anApp
, allowing this syntax:Usage from React
This is how the same task can get accomplished using the React library:
Note: this doesn’t support subscriptions yet. I plan to introduce a separate change in the app connectors that will allow to subscribe using the exact same syntax as above.
App connector authoring
This is how an app connector can get implemented in the most basic way:
And this is how the Voting app connector is implemented:
Status
@aragon/connect-thegraph-voting
to@aragon/connect-voting
.@aragon/connect-thegraph-tokens
to@aragon/connect-tokens
.App
.@aragon/connect-react
compatibility.Other changes
connect
as a default export of@aragon/connect
.toNetwork()
function that transformsNetworkish
intoNetwork
.Organization
now receives a singleConnectionContext
object.ConnectionContext
.provider
=>ethersProvider
,readProvider
=>ethereumProvider
.connect()
rather than doing it inOrganization
.Organization
: remove the_connect()
method.list-votes-cli
andlist-votes-react
.