Giter Club home page Giter Club logo

connect's Introduction

Aragon Connect

a toolkit for developers to seamlessly integrate DAO functionality into apps.

codecov

Aragon Connect is still in active development and its API might change until it reaches 1.0.

Usage

// Connects to an organization.
const org = await connect('org.aragonid.eth', 'thegraph')

// Intents can be converted in a transaction.
const intent = await org.removeApp('0x…')

// Get the transactions for the intent with the current account
const transactions = await intent.transactions(wallet.address)

// Sign the generated transactions
for (const transaction of transactions) {
  await ethers.sendTransaction(transaction.toEthers())
}

Documentation

Please have a look at the documentation website. If you never used the library before, we highly recommend starting with the Getting Started guide.

Packages

Name Description Size Version
@aragon/connect The main package. Contains connect().
@aragon/connect-react React API for Connect.
@aragon/connect-core Core library (used by connectors).
@aragon/connect-ethereum Ethereum connector (in progress − included in @aragon/connect).
@aragon/connect-thegraph TheGraph connector (included in @aragon/connect).
@aragon/connect-finance Connector for the Finance app.
@aragon/connect-tokens Connector for the Tokens app.
@aragon/connect-voting Connector for the Voting app.

connect's People

Contributors

0xgabi avatar arabot-1 avatar bpierre avatar dependabot[bot] avatar evalir avatar fabriziovigevani avatar facuspagnuolo avatar githubdoramon avatar macor161 avatar mathewmeconry avatar onbjerg avatar pengiundev avatar sohkai avatar theethernaut avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

connect's Issues

React: createAppHook cleanup error on component mount

I've been seeing a state update error when mounting a component that uses createAppHook. It seems to occur only once when unmounting then remounting a component.

Below is an example I created by modifying the list-votes-react demo, the only change is the addition of a button to control the display of the <Votes/> component.

ezgif-7-9dada07d6ffd

Track the final bundle size

We should keep track of the final bundle size when the required modules are being imported in a web app.

We could have the following:

  • One bundle with only @aragon/connect.
  • One bundle with @aragon/connect + app connector, for every core app.
  • One bundle with @aragon/connect + all the core app connectors.

We could try to do this using https://bundlewatch.io/

Feat: Handle default subgraph URL for each network on the specific app connectors

In the current setup, we expect the user to know the subgraph specific URL of each network they are trying to connect.

For example:

const voting = new Voting(
  votingInfo.address,
  'https://api.thegraph.com/subgraphs/name/aragon/aragon-voting-mainnet'
)

It would be great to update current logic to default to a specific subgraph URL for each network using mainnet as default, as we are doing for the main connector. In this way, we will also encourage other devs working on their own app connectors to follow this convention.

The new way of connecting to the connector would be:

const voting = new Voting(
  votingInfo.address,
  {chainId: 4}  //optional, default to 1
)

Add filters to org.app() and org.apps()

The app() and apps() methods of Organization could provide a way to filter the desired apps, by having a filtering object passed to them.

Proposed API:

// Selecting by appName
org.apps({ appName: 'voting.aragonpm.eth' })

// Selecting multiple appName
org.apps({ appName: ['voting.aragonpm.eth', 'token-manager.aragonpm.eth'] })

// Selecting by address
org.apps({ address: '0xcafe…' })

// Selecting multiple addresses
org.apps({ address: ['0xcafe…', '0xbeef…'] })

We could have other filters but address and appName would probably enough for now.

Selecting the first app that matches could be done this way:

const [voting] = await org.apps({ appName: 'voting.aragonpm.eth' })

Or by using .app(), which should act as a convenient alias for the previous example:

const voting = await org.app({ appName: 'voting.aragonpm.eth' })

The only difference is that .app() would also accept an address to be passed directly:

// these two lines are equivalent:
const voting = await org.app('0xcafe…')
const [voting] = await org.apps({ address: '0xcafe…' })

It will eventually make it possible to do this, for an org with a single voting app:

const voting = new Voting(await org.app({ appName: 'voting.aragonpm.eth' }))

Note: this is not the case yet, but we sould try to reuse the names and patterns we use for filters as much as possible so it feels consistent.

API refactor: Forwarding Path

This issue keep track of all the tasks that need to happen to refactor the Forwarding Path described on #132.

  • New methods to interact with Transaction: sign, transactions
  • New method to describe a Forwarding Path. The logic to construct a description will change a lot. So this item needs further refinement that we will address on a separate issue:

API refactor: Describe a Forwarding Path

This issue goes further into the details of what it takes to create a Forwarding Path description. The logic that we currently support was migrated from aragon.js and it's not flexible enough to provide lot of value for custom UI experiences.

To transition into a more powerful and descriptive data type as the one described in #132 we need to address a few tasks:

Subgraph: Add organization names

I'm unsure whether this should be a separate subgraph or not, but it would be super helpful to have organization names in the GraphQL API for things like Apiary.

My general feeling is that it is somewhat high cost to maintain, since the only way to get the organization names (as far as I know) is to decode transactions sent directly to one of the organization templates/kits, which inherently is a per-contract action. This would mean that a list would need to be maintained of the kits on each network, along with kit-specific handlers for attaching the names to the correct organizations.

Add a boilerplate template repo

The boilerplate should help a new developer to bootstrap:

  1. A simple Aragon Connect custom front-end
  2. Have use-wallet configured
  3. Have GitHub pages already set up for easy deployments

Organization subgrah data source needs to be updated

Subgraphs in voting and tokens are using a slightly more sophisticated data source system which hasn't been applied in the main subgraph.

E.g. compare manifest/templates in connect-thegraph and connect-thegraph-tokens. While the former just contains files at this point, the latter contains a contracts/ and a sources/ folder. The latter is the latest form of data source usage.

We may not want to have it conform to the others in this way, but it should at least be considered.

Doc: Review and remove feature we do not support yet

The documentation has a few features we have in our roadmap but that do not land to production yet. This is confusing for the current users of the library. For example the options.as on the TransactionIntent object.

Docs: Update documentation with new Voting connector API changes

Feedback from the hack.

Things that need to change from the tutorial:

  1. You need to do import { Voting } from "@aragon/connect-thegraph-voting" instead of using a default import.
  2. The method to get the voting app address of await org.app("voting").address; doesn't seem to work anymore. Had to use:
const apps = await org.apps();
const { address } = apps.find(app => app.appName.startsWith("voting."));

Organization and app install metrics

We're currently in the process of migrating as much as possible of Apiary to The Graph and we'd like to use the subgraph already deployed for Aragon Connect. However, some metrics are missing, and I'd like to hear your thoughts on adding them:

  • Currently, it does not seem like there is an overall organization count. There only seems to be one for each kit.
  • There are no metrics on how many proxies ("installations") of an app there exists. This metric is something we have on Apiary and we'd like to retain it.

Forwarding Paths modes 🛤

The current Connect API logic only calculates the shortest Forwarding Path. But in many cases, we may want more flexibility to allow:

  • Calculate all existing Forwarding Paths
  • Calculate a Forwarding Path giving a hardcoded ForwardingPathDeclaration
  • Calculate a Forwarding Path for an intent basket

When we build the full version, it would be nice to tell it things like:

  • I'd like to start with these steps (one or more steps in the path)
  • I'd like to use X app/account as the final forwarders (one or more last steps)
  • I'd like to have these X steps in the middle
  • A combination of either

In practice all this is doing is allowing the user to narrow our search space for forwarding pathing.

Demo idea: Signing Modal

Like the signing panel we have on the client, this would allow app authors to provide to their users an easy way to pick a transaction path.

Add a new method to the ConnectorInterface to fetch Repos by name

Try to answer the question: What is the content of Repo? It is quite common. We should include new method repoByName that handle and parse a query in the lines of:

query {
  repos(where: { name: $name }) {
    id
    name
    lastVersion {
      codeAddress
      artifact
      semanticVersion
    }
  }
}

API to link between transaction path steps

I think this is non-trivial for Connect, because it requires app-level information (and even then it may be difficult due to the lack of explicit information in events or other details).

Ideally, if you had an organization requiring a multi-step transaction path to execute an action, for example:

  1. Approval (smaller group)
  2. Delay (time constraint to notify potential voters)
  3. Voting (large group)

It would be ideal if a user could establish a link between an action going through the different steps, for example:

  • Approval#4 created Delay#5
  • Delay#5 created Vote#2
  • Vote#2 can be traced all the way back to Approval#4 (and any other intermediate steps as necessary)

This would be useful for building UI that explains the path an action took, for example, to show all the steps taken (and to be taken) in one "proposal" detail view.

(If an action was at the middle Delay step, it would only be able to tell users that a potential vote may be created; see larger description)


The only way I know how to do this now is by inspecting the transaction that created a particular action (e.g. Vote#2). You can eventually follow the logs to know that a particular Dispute#5 created the vote, but this is both slow and requires a lot of additional context. It would be much, much better if we could find a way to do this through a subgraph or another approach.

API refactor: App connectors transaction requirements

This issue is to discuss and outline the scope of changes we may need to do to allow the app connector to add more details when sending transactions.

  • E.g. Finance and Agreement need token pre-approvals, and it would be easier if those connectors held logic to calculate these

Brett's comment on the subject:

It's becoming clearer now, especially with Agreements and Disputable Voting, that app actions will have more context about the periphery transactions related to an action.

For example, in order to start a disputable vote (called directly or at the beginning of a transaction path), users will have to include one (or two) approval pre-transactions. And for the Agreement, a challenger could have up to four pre-transactions related to token approvals before they actually submit the transaction that starts the challenge.

Given this, I've started leaning more and more on allowing app connectors to include more logic on actions they expose, rather than directly mirroring organization#appIntent().

An alternative to this is providing a standard for app connectors to "hook" into an appIntent() call (e.g. "if I'm included in the forwarding chain, add a transaction"), but this would also force us to configure the app connectors in the main connect() export.

Intent: Support apps intent overloads

We are not handling overloads correctly on ethers. For examples:

await org.appIntent(Voting.address, 'newVote', ["0x00000001", "test"])

Error from ethers.js with multiple matching functions.

The source of problems is here.

It was reported that using the function signature instead of the methodJsonDescription.name fixed it.

Radspec: allow users to define extensions at run-time

Radspec descriptions are usually very organization-specific (contextual to each individual organization).

This would require aragon/radspec#88, but we should expose a way for Connect users to declare any additional radspec descriptions they'd like to incorporate into their organization's actions.

Another aspect I was thinking about was making the action descriptor transformation run-time configurable; an example might be an organization that is backed by a database (or IPFS blob) mapping descriptions to transaction hash or action id (e.g. voting app addr + vote id).

React: Votes returning null inbetween poll updates

This might be related to the changes in #203

In between polling updates, votes return null before being repopulated.

Here is an example from the react demo:

image

This causes jumps between loading and display at every interval.

Is this expected behaviour?

API Refactor: Transactions

This issue keeps track of the changes that need to happen to the Transaction entity described on #132.

  • Update the data types on every place
  • Refactor how we handle the creation of the Transaction entities during the Forwarding Path calculation

Automate npm releases

I think it could be nice to consider the master branch stable, and automate the build + version bump + npm publication using GitHub Actions.

We could:

  • Have a specific line in the PR and merge commit (e.g. change: major|minor|patch) to determinate the new version.
  • Have one of the status checks verifying that the change: information exists (and prevent merging without it).
  • For every merge on master, a workflow would:
    • Build everything.
    • Bump the version.
    • Push the newly created tag.
    • Publish on npm.

The changelog will still be edited manually.

Some things we might want to explore:

Using merge-release

Some potential issues:

  • It only checks at the commit level, so we can’t run a PR status check to verify that the information has been set.
  • It is not as explicit as having a change: major|minor|patch, which might cause issues.
  • I couldn’t make it work with aragonUI and our npm account. For some reason, it never accepts to authenticate, even without OTP.

Using GitHub Packages + npm-package-sync

This would allow to publish on GitHub Packages, and just sync it with npm. It would make things easier if GitHub Packages provide a transparent bridge to npm at some point.

/cc @sohkai @promaty

API changes: Intents, Forwarding Paths and Transactions

This issue will keep track of the planned changes regarding the intents, forwarding paths and transactions.

These changes are aiming to improve / solve the following:

  1. Separate the forwarding paths from the transactions to sign [1].
  2. Provide a standard transaction request object that can be passed to Ethereum libraries.
  3. Make it easier to sign a single transaction.
  4. Make it possible to ignore the forwarding paths.
  5. Make it possible to express complex forwarding paths.

[1] This is why the term “Forwarding Path” is now preferred to “Transaction Path”.

Current Status

  • Store the signing address in the context.

Going forward we'll use a milestone to keep track of the progress: https://github.com/aragon/connect/milestone/1

Storing the signing address in the connection context

The idea here is to attach a default address to the connection context. This address will get used by the methods generating forwarding paths and transaction requests. It will be possible to override it at any point.

It could be passed to connect():

const myorg = await connect('myorg.aragonid.eth', 'thegraph', {
  actAs: '0x…',
})

It should also be possible to update it without resetting the connection. A new method on Organization could help doing that:

org.actAs('0x…')

Reshaping the intent-to-transaction flow

ForwardingPath

  • Replaces AppIntent and TransactionPath.
  • Represents the forwarding path corresponding to an action that will be executed.
  • Returned by some methods of Organization and App (e.g. App#exec()).
  • Users should not instantiate it directly (using new).
class ForwardingPath {
  // A list of transaction requests ready to get signed.
  transactions: Transaction[]

  // Lets consumers pass a callback to sign any number of transactions.
  // This is similar to calling transactions() and using a loop, but shorter.
  // It returns the value returned by the library, usually a transaction receipt.
  sign<Receipt>(
    callback: (tx: Transaction) => Promise<Receipt>
  ): Promise<Receipt[]>

  // Return a description of the forwarding path, to be rendered.
  describe(): Promise<ForwardingPathDescription>

  // Return a description of the forwarding path, as text.
  // Shorthand for .describe().toString()
  toString(): string
}

New App methods: exec() and execPaths()

The two initial methods returning ForwardingPath instances are App#exec() (to get the shortest path) and App#execPaths() (to get all the possible paths).

type ExecOptions = {
  // The account to sign the transactions with. It is optional
  // when `actAs` has been set with the connection. If not,
  // the address has to be passed.
  actAs: Address

  // Optionally declare a forwarding path. When not specified,
  // the shortest path is used instead.
  path: ForwardingPathDeclaration
}

// No `path` option here since we want them all.
type ExecPathsOptions = {
  actAs: Address
}

interface App {
  exec(signature, params, options?: ExecOptions)
  execPaths(signature, params, options?: ExecPathsOptions)
}

Address

This is a type we could use for documentation purposes.

type Address = string

AppOrAddress

This type accepts an App instance or its address, and should get used whenever possible rather than an address only.

type AppOrAddress = App | Address

ForwardingPathDeclaration

This type allows to express a forwarding path in a simplified, but limited way: it is not possible to nest the forwarding actions.

type ForwardingPathDeclaration = AppOrAddress[]

Transaction

Transaction replaces TransactionRequest, and is now a type rather than a class. It describes a subset of the eth_sendTransaction parameters in the Ethereum JSON-RPC API.

type Transaction = {
  data: string
  from: Address
  to: Address
}

ForwardingPathDescription

This object contains all the information needed to render the description of a forwarding path. It gets returned by ForwardingPath#describe().

type ForwardingPathDescriptionTreeEntry =
  | AppOrAddress
  | [AppOrAddress, ForwardingPathDescriptionEntry[]]

type ForwardingPathDescriptionTree = ForwardingPathDescriptionEntry[]

class ForwardingPathDescription {
  // Return a tree that can get used to render the path.
  tree(): ForwardingPathDescriptionTree

  // Renders the forwarding path description as text
  toString(): string

  // TBD: a utility that makes it easy to render the tree,
  // e.g. as a nested list in HTML or React.
  reduce(callback: Function): any
}

Forwarding Path Builder

Forwarding Path Declaration Syntax

Paths can be complex and defining them using JS structures might not provide a level of clarity that is sufficient. Having a dedicated syntax could improve that.

Using tagged templates could make it possible to integrate our existing object types into it, App and Intent in particular.

Initial draft:

const p = path`
  > ${voting}
    > ?
      > ${voting.createVote('something')}
      > "encoded_sub_action_1"
      > "encoded_sub_action_2"
  > ${tokens}
    > "encoded_action_1"
      > "encoded_sub_action_1"
`

const txRequests = p.transactions({ as: '0x…' })

In this example, ? would express a part that need to be filled by the library, if possible.

Note: this draft is only used to express the idea, its syntax will probably be different.

Path Builder Utility

Using the language previously mentioned above, we could also provide a forwarding path builder. This tool would let users edit a forwarding path after its initial creation.

We could imagine an initial implementation accepting the same JS structure than the one returned by path\``.

Initial draft:

const pathBuilder = path`
  > ${voting}
    > ?
      > ${voting.createVote('something')}
      > "encoded_sub_action_1"
      > "encoded_sub_action_2"
  > ${tokens}
    > "encoded_action_1"
      > "encoded_sub_action_1"
`

// Call insert() in this way to insert an action after "encoded_sub_action_2"
pathBuilder.insert('0 > 0', voting.createVote('something'))

// PathBuilder could inherit from Intent since it would provide the same methods:
pathBuilder.sign()
pathBuilder.transactions()
pathBuilder.path()
pathBuilder.paths()

Note: this draft is only used to express the idea, its syntax will probably be different.

Demo idea: Aragon Button Builder

An “Aragon Button” builder that would allow to pick a certain action on an organization, and to export it as a single button ready to embed anywhere.

For example, a button could be configured to cast “Yes” on a specific vote of a given Voting app.

Subgraphs: handle app upgrades

Currently we only use the appId in each app subgraph to determine a contract template.

However, an app instance may actually go through multiple versions (e.g. as they did when we upgraded 0.6 to 0.7 organizations), and this is ultimately in the control of the app developer and organization.

Ideally app subgraphs would be able to detect if an app changed its implementation address and switch to a different contract template which defines different event handlers. Technically we should be able to know when to do this if we also listen to all Kernel SetApp events, but it's unclear how we would switch the template (outside of encoding a version in the entity and sprinkling if/elses everywhere).

cc @facuspagnuolo

API refactor: Intent logic

This issue keeps track of the changes that need to happen related to the Intent entity described on #132.

  • New methods to interact with Transaction: sign, transactions
  • Update the current path method to use the new data structures and types
  • New method to calculate all the possible Forwarding Paths: paths

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.