Skip to content

Releases: aragon/connect

Aragon Connect 0.7.0

07 Sep 22:07
Compare
Choose a tag to compare

This version adds two main things: error-first callbacks and important improvements to the React API. Please read carefully these release notes before updating to 0.7.0, as it contains breaking changes.

Error-first callbacks 🐢🚀

Starting with Connect 0.7.0, every subscription callback receives an optional error as a first parameter. This is a breaking change. Errors are now properly passed to subscription methods, the same way async methods receive them by using try / catch.

Pull request

  • Move to Node-style callbacks in every subscription (#229)

Align app connector methods 📏

A number of changes have been made to align the subscription methods of the app connectors with their async counterparts, by moving their callback at the end, and accepting the same filter object.

Here is a list of the changes:

Finance

  • Interface: move the callback at the end.

Tokens

  • Fixes an issue on the Tokens connector where onHolders() was using the address of the app rather than the address of the token contract.
  • The onHolders method now accepts filters.

Voting

  • Align onCasts() with casts(): the method now accepts filters.
  • Connector interface: move the callback at the end.

Pull requests

  • App connectors: align subscription methods (#240)
  • Update docs: Finance, Tokens and Voting (#236)

React API updates 🏗️

createAppHook() changes

Connector configuration

When using the @aragon/connect API, app connectors can receive a source connector and its options, and up to this point, passing options wasn’t possible with createAppHook(). A second parameter has been added to createAppHook(), allowing to pass a specific connector with its options:

import connectVoting from '@aragon/connect-voting'
import { createAppHook } from '@aragon/connect-react'

const useVoting = createAppHook(connectVoting, [
  'thegraph',
  { subgraphUrl: 'https://…' },
])

Dependency array to control updates

Hooks created through createAppHook() now accept a dependency array, that can get used to refresh the callback passed to it. It behaves in a very similar way to the useEffect() or useMemo() hooks, except that when no dependency array is passed, the callback doesn’t update.

import connect from '@aragon/connect'
import connectVoting from '@aragon/connect-voting'
import { createAppHook, useApp } from '@aragon/connect-react'

const useVoting = createAppHook(connectVoting)

function App() {
  const [page, setPage] = useState(0)

  const [voting] = useApp('voting')
  const [votes] = useVoting(
    voting,
    (app) => app.votes({ first: 10, skip: 10 * page }),
    [page]
  )

  return (
    <div>
      <button onClick={() => setPage(page + 1)}>prev</button>
      <button onClick={() => setPage(page - 1)}>next</button>
    </div>
  )
}

Subscribe to app connector methods

Prior to 0.7.0, it was not possible to subscribe to app methods using createAppHook(). The fetched data was returned once, and only updated when the component was mounted again. This feature has been added, and we can now subscribe to any app method, the same way non-dynamic hooks (useApp(), usePermissions(), …) update automatically. Every part of the React API is now listening to changes and reacting accordingly.

To use this feature, the subscription methods (onX) should be called without passing a callback. createAppHook() will take care of handling the subscription.

import connect from '@aragon/connect'
import connectVoting from '@aragon/connect-voting'
import { createAppHook, useApp } from '@aragon/connect-react'

const useVoting = createAppHook(connectVoting)

function App() {
   const [voting, votingStatus] = useApp('voting')

   // To enable a subscription, use app.onVotes() rather than app.votes().
   const [votes, votesStatus] = useVoting(voting, app => app.onVotes())

   return (
      // …
   )
}

Of course, it also works with the dependencies array, taking care of replacing the subscription by a new one:

import connect from '@aragon/connect'
import connectVoting from '@aragon/connect-voting'
import { createAppHook, useApp } from '@aragon/connect-react'

const useVoting = createAppHook(connectVoting)

function App() {
   const [page, setPage] = useState(0)

   const [voting] = useApp('voting')
   const [votes] = useVoting(voting, app => (

      // Note the app.onVotes() rather than app.votes().
      app.onVotes({ first: 10, skip: 10 * page })

   // The subscription will refresh every time `page` changes.
   ), [page])

   return (
      // …
   )
}

Important: this only works with app connectors enabling this syntax. The core app connectors have been updated (@aragon/connect-voting, @aragon/connect-tokens and @aragon/connect-finance), but third party app connectors need to be updated in order to support it.

Populate status.error correctly

In many cases, errors were thrown rather than populating the status.error object in the React API. It is an issue that was also happening with the JS API (see #229). It has now been fixed.

import connect from '@aragon/connect'
import connectVoting from '@aragon/connect-voting'
import { createAppHook, useApp } from '@aragon/connect-react'

const useVoting = createAppHook(connectVoting)

function App() {

   const [voting, votingStatus] = useApp('voting')
   const [votes, votesStatus] = useVoting(voting, app => app.votes())

   if (votingStatus.error) {
      return (
         <h1>Error: {votingStatus.error.message}</h1>
      )
   }

   if (votesStatus.error) {
      return (
         <h1>Error: {votesStatus.error.message}</h1>
      )
   }

   return (
      // …
   )
}

Less frequent updates

Since we replaced the GraphQL subscriptions by queries with polling (see #203), the hooks provided by the React API were updating too often, and incorrectly (see #216). Since 0.7.0, the React Hooks are now taking care of only triggering updates when a changed happened, and to only use a loading state when necessary.

Pull request

  • React API improvements (#233)

Other changes

  • Bump radspec version (#253)
  • Finance connector: remove non-null operators (#244)
  • Ethers: use named imports (#208)
  • Add missing SubscriptionCallback types (#241)
  • Docs: Remove features we don't support yet (#213)
  • Tests: Use aragon subgraph on finance connector (#251)
  • Add pre release instructions (#267)
  • Run prettier on commits (through husky + precise-commits) (#207)
  • publish-version.sh: add the possibility to specify a version and tag (#248, #249)

Aragon Connect 0.6.0

17 Aug 13:05
c3b5ac7
Compare
Choose a tag to compare

This release is moving away from using WebSocket subscriptions, and uses HTTP polling instead. This is because The Graph doesn’t officially support GraphQL subscriptions, and they recently became unreliable. One advantage is that we are now using the caching mechanism of urql, the library used internally for GraphQL requests, which will make requests often feel instant. See #203 for more details.

Another important change is that name is now optional when network is provided as an object to the connect() function. See #202 for more details.

Changes

  • Replace GraphQL subscriptions (WS) by queries with polling (HTTP) (#203)
  • toNetwork(): make the name optional (#202)
  • Add a global .prettierrc (#201)
  • Documentation updates (#200, #204)
  • Examples cleanup (#205)

Aragon Connect 0.5.3

12 Aug 13:36
a2aee9e
Compare
Choose a tag to compare

This release fixes an issue where in some cases, using an app connector was emitting the error “App connector: the passed value is not an App”, even though a correct app instance was passed to it. See #197 for more details.

Changes

  • createAppConnector(): stop using instanceof (#197)
  • list-votes-cli: move from chainId to network (#198)
  • list-votes-cli: add a tsconfig file (#199)
  • DisputableVoting: Implement connector models (#181)
  • DisputableVoting: Extend vote model functionalities (#194)
  • Doc: Fix broken link (2be665e)
  • Add missing connectors to build script (#189)
  • Update app connectors models and types (#191)
  • Subgraph: Update subgraph deployments (#190)
  • Delete subgraph License file (#192)
  • Add a script to automate most of the publication tasks (#188)

Aragon Connect 0.5.2

04 Aug 23:27
bf0eec7
Compare
Choose a tag to compare

This release fixes an issue with the version ranges used internally by Connect packages, which could prevent some bundlers to deduplicate the modules properly (see #184).

Changes

  • Use fixed version ranges (#184)
  • Add release instructions (#174)
  • Remove per package README files (#187)

Aragon Connect 0.5.1

29 Jul 20:08
adbd8b4
Compare
Choose a tag to compare

This release fixes an issue with the @aragon/connect-finance, where the package.json did not contain the right paths to the CommonJS / ES Modules bundles and the TypeScript type definitions.

Changes

  • README: add the Finance app (#172)
  • Finance: fix package.json paths (#173)

Aragon Connect 0.5.0

29 Jul 18:25
18b5f98
Compare
Choose a tag to compare

This version introduces a series of changes to the API of Connect, aiming to make it easier to use while reducing the amount of boilerplate.

Contributors for this release: @0xGabi, @ajsantander, @bpierre, @onbjerg, @pengiundev 🎉

Breaking changes 🔨

  • New API to initiate an app connection (see next section).
  • New API to implement app connectors (see next section).
  • The @aragon/connect-thegraph-voting package is now @aragon/connect-voting.
  • The @aragon/connect-thegraph-tokens package is now @aragon/connect-tokens.
  • The chainId option of the connect() function is now network, and accepts a chain ID (e.g. 4), a network name (e.g. "rinkeby"), or a network object.
  • The readProvider option of the connect() function is now ethereum.

New app connectors API 🔌

This version is adding important changes to the way we interact with app connectors.

Before the new API

To illustrate these changes, let’s have a look at how a list of votes could get fetch with Connect 0.4.2:

import connect from '@aragon/connect'
import { Voting } from '@aragon/connect-thegraph-voting'

// Connect to an organization on mainnet via The Graph.
const org = await connect('myorg.aragonid.eth', 'thegraph')

// Get the voting app.
const voting = await org.app('voting')

// Instantiate the Voting class, and pass the URL for mainnet.
const votingConnected = new Voting(
  voting.address,
  'https://api.thegraph.com/subgraphs/name/aragon/aragon-voting-mainnet'
)

// Fetch the votes from the votingConnected object.
const votes = await votingConnected.votes()

The example above contains a few things that we wanted to improve:

  • The network (mainnet here) has to be set again on the app connector. The organization and the app live on the same network, so it shouldn’t be necessary.
  • The app connector is specific to a data source (The Graph here). The main library will eventually include several data sources, and app connectors should follow the same direction.
  • We are dealing with two different objects: voting and votingConnected. They might seem similar but are doing different things: one is an App instance, while the other one is coming from the app connector and allows to fetch data.

With the new API

This is how the same example looks with the new API:

import connect from '@aragon/connect'
import connectVoting from '@aragon/connect-voting'

// Connect to an organization on mainnet via The Graph.
const org = await connect('myorg.aragonid.eth', 'thegraph')

// Get and connect to the voting app.
const voting = await connectVoting(org.app('voting'))

// Fetch the votes from voting.
const votes = await voting.votes()

A few things about this last example:

  • The app connector function knows about the current network (mainnet), there is no need to specifiy the URL for The Graph (but it can be done optionally).
  • The app connector is now universal. You might have noticed that @aragon/connect-thegraph-voting is now @aragon/connect-voting. This is because a connector can now support any number of data sources it wants, and we plan to support the same data sources in @aragon/connect and the core app connectors.
  • We are now only using one object: voting. With this new API, the object returned by the app connector gets extended by App, rather than being separate. It means that the API of App is available on this object.
  • connectVoting() accepts either an App or a promise resolving to an App. This is why we can directly pass org.app('voting') to it.

This new API should make app connectors feel more similar to the connect() function, while keeping the boilerplate and code repetition to a minimum, without compromising on the expressiveness as everything can be configured as before − except it’s optional now.

Usage with React

This is how the example presented above looks like with the React library:

import { createAppHook, useApp } from '@aragon/connect-react'
import connectVoting from '@aragon/connect-voting'

// We start by creating a hook for the app connector.
const useVoting = createAppHook(connectVoting)

function Votes() {
  // We fetch the voting app.
  const [voting] = useApp('voting')

  // And we pass the voting app to the useVoting() hook.
  // The second parameter is a callback that returns the data we want.
  const [votes] = useVoting(voting, app => app.votes())

  return (
    <ul>
      {votes ? (
        votes.map(vote => <li key={vote.id}>{formatVote(vote)}</li>)
      ) : (
        <li>Loading votes…</li>
      )}
    </ul>
  )
}

As you can see, we are using the exact same function, connectVoting, to create a React Hook. This means that authors of app connectors don’t have to do anything specific for their connector to work with @aragon/connect-react.

Note: this doesn’t support subscriptions yet. The next version will enable subscriptions using the exact same syntax as above.

Authoring app connectors with the new API

This is how an app connector can get implemented in the simplest way:

import { createAppConnector } from '@aragon/connect-core'

export default createAppConnector(() => ({
  total: () => fetchTotal(),
}))

The createAppConnector() utility takes care of doing the necessary checks, and passing contextual information to the callback.

This is how the connector for the Voting app is implemented using createAppConnector():

import { createAppConnector } from '@aragon/connect-core'
import Voting from './entities/Voting'
import VotingConnectorTheGraph, {
  subgraphUrlFromChainId,
} from './thegraph/connector'

export default createAppConnector(
  ({ app, config, connector, network, verbose }) => {
    if (connector !== 'thegraph') {
      console.warn(
        `Connector unsupported: ${connector}. Using "thegraph" instead.`
      )
    }

    return new MyAppConnector(
      new VotingConnectorTheGraph(
        config.subgraphUrl ?? subgraphUrlFromChainId(network.chainId),
        verbose
      ),
      app.address
    )
  }
)

Pull request

  • connectApp() (#135)

New app connector: Finance 📊

A new app connector has been added, for the Finance app. It uses the new connector API, and you can use it this way:

const org = await connect(env.location, 'thegraph')
const finance = await connectFinance(org.app('finance'))
const transactions = await finance.transactions()

Pull requests

  • Finance connector + subgraph (#149)
  • Finance docs + review (#168)

ES modules exports 📦

Every Connect package is now exported in two formats: CommonJS and standard ES Modules, rather than CommonJS only. Your preferred bundler should detect the most appropriate format, or you should be able to configure it to choose either the main or module field from the package.json file. Nothing will change for Node.js apps, as the CommonJS export is still going to get imported by Node.

If you are using a tool like SnowPack, the integration with Connect will be much better from now on.

Pull request

  • Add ESM exports (#162)

New examples 📬

A few more examples have been added.

Karma template organization deployment

This script demonstrates how to deploy an organization using the Karma template. It doesn’t use Connect yet, but it will be updated when the possibility to deploy an organization from Connect will get added.

Minimal Setup

This example demonstrates the absolute minimum required to build a React app using Connect. Here we are using Parcel to bundle it, and nothing more.

List Votes (CLI + React)

These two examples demonstrate how the new API to connect apps can get used from Node.js or a React app.

Pull requests

  • Examples: Karma template organization (#152)
  • Examples: add minimal setup (#161)
  • connectApp() (#135)

Other changes 📝

  • connect() now accepts actAs as an option (#135)
  • connect() now accepts verbose as an option (#135)
  • The ipfs option of connect() now also accepts an URL template, containing {cid} and {path}.
  • Documentation tweaks (#134)
  • Handle stranger cases in TokenManager (#130)
  • Types: remove some non-null assertion operators (!) (#128)
  • Types: add SubscriptionHandler, Address (#136)
  • Rename ConnectorInterface to IOrganizationConnector (#137)
  • Connectors: make it possible to close the connection (#140)
  • Examples: connect-react-intro: move to SnowPack (#160, #163)
  • Add GRAPHKEY to the deploy scripts and documentation (#145)
  • Subgraph: deployment data of Tokens and Voting on xDai (#155)
  • Add app installation count to Repo entity (#150)
  • Fix: ethers overloads (#158)
  • Connectors: Use official aragon subgraphs url (#167)

Aragon Connect 0.4.2

08 Jul 22:55
4f2b91f
Compare
Choose a tag to compare

This release fixes a regression that was introduced in 0.4.1, where the contentUri property of Repo was not set.

Contributor for this release: @0xGabi.

Changes

  • Add appId to the Repo query + fix typo on argument (#126)

Aragon Connect 0.4.1

07 Jul 21:36
3cde874
Compare
Choose a tag to compare

This is a small release that includes a few changes and fixes.

Contributors for this release: @0xGabi, @bpierre.

Changes

  • Add TransactionRequest#children and Role#appId (#121)
  • Support xDai as a default provider (#119)
  • Fix transaction paths in the nodejs example (e7f22f5, 3b73a43)
  • New example: connect-react-intro (#120)
  • Documentation updates (#115, #116, #117, #118)

Aragon Connect 0.4.0

06 Jul 00:43
e6bc48c
Compare
Choose a tag to compare

This version includes a new package for React apps, app filters, and improved app metadata.

Contributors for this release: @0xGabi, @ajsantander, @bpierre, @fabriziovigevani, @sohkai 🕺

Connect 💙 React

Aragon Connect now offers a dedicated library for React.

Usage

Start by adding it to your React project:

yarn add @aragon/connect-react

And use it this way:

import { Connect, useApps, useOrganization } from '@aragon/connect-react'

function App() {
  const [org] = useOrganization()
  const [apps] = useApps()
  return (
    <>
      <h1>{org?.name || 'Loading'}</h1>
      <ul>
        {apps.map(app => <li>{app.name}</li>)}
      </ul>
    </>
  )
}

export default () => (
  <Connect
    location="myorg.aragonid.eth"
    connector="thegraph"
  >
    <App />
  </Connect>
)

Please have a look at the documentation for more details.

Pull request

  • Connect for React API (#52)

App filters 🗂️

The different app methods now include filters, making it easier and more performant to select a particular set of apps.

Usage

For example, this is how you would have instantiated a Voting app connector in the past:

// Connect to the organization.
const org = await connect('example.aragonid.eth', 'thegraph')

// Fetch all the apps from it.
const apps = await org.apps()

// Find the App instance we want.
const votingInfo = apps.find(app => app.appName === 'voting.aragonpm.eth')

// Instantiate the Voting connector using the address found.
const voting = new Voting(votingInfo.address, subgraphUrl)

And this is how it can be done now:

// Connect to the organization.
const org = await connect('example.aragonid.eth', 'thegraph')

// Instantiate the Voting connector directly by fetching the app address from the parameters.
const voting = new Voting(await org.app('voting').address, subgraphUrl)

Filter types

Filters can be passed as a first parameter to the following Organization methods: app(filters), apps(filters), onApp(filters), and onApps(filters).

They can be of different types:

  • An app name (e.g. "voting.aragonpm.eth") or its short format ("voting").
  • An app address: "0x…".
  • An array of app names: ["voting", "finance"].
  • An array of app addresses ["0x…", "0x…"].
  • An object can also be passed to disable the automatic detection:
    • { address: "0x…" }
    • { address: ["0x…", "0x…"] }
    • { appName: "voting" }.
    • { appName: ["voting", "finance"] }.

Pull request

  • App filters + align Organization methods (#111)

Improved apps metadata 🎁

The metadata attached to apps is now more reliable and consistent.

  • When an app metadata is not available on the connector (e.g. TheGraph), it is then fetched from the Aragon IPFS node by default.
  • System apps (Kernel, ACL, etc.) now contain metadata like the other apps.

Pull requests

  • Add overrides for apps without aragonPM repos (#114)
  • Add IPFS fallback logic to fetch metadata (#89)
  • Use an static method to create Entities + Split Data and Metadata (#110)

New utilities 🔧

A series of utilities have been added to the @aragon/connect-core and @aragon/connect packages.

  • findAppMethodFromIntent()
  • decodeCallScript()
  • encodeCallScript()
  • describeTransaction()
  • describeTransactionPath()
  • describeScript()
  • fetchMetadata()

Pull request

  • Add descriptions utils for evm scripts and transactions (#101)

Documentation updates 📚

An important number of improvements has been made to the documentation since the last release.

Check out our new guides, and let us know what you think!

Pull requests

  • Docs: add advance information about Connectors (#95)
  • Docs: Aragon Basics (#98)
  • Docs: dedupe subgraph and connector guides (#88)
  • Docs: review (#72)
  • Docs: Small fixes & correct links (#92)

Other changes

  • Refactor: Use an static method to create Entities + Split Data and Metadata (#110)
  • Populate App#name for system apps (#112)
  • Tokens subgraph: Update totalSupply if tokens minted or burned (#79)
  • Renamed App and Repo + Improve a callback type (#93)
  • Feat: Add IPFS fallback logic to fetch metadata (#89)
  • Fix broken tests (#96)

Upgrade from 0.3.0

  • Application has been renamed App.
  • Repository has been renamed Repo.

Aragon Connect 0.3.0

26 Jun 21:50
Compare
Choose a tag to compare

This version includes support for the xDai network, and API changes for the request-related objects.

Contributors for this release: @0xGabi, @ajsantander, @bpierre, @Evalir and @fabriziovigevani. 🙏

xDai support

Aragon Connect now supports the xDai network.

Set the chainId to 100 in order to use it:

const org = await connect('myorg.aragonid.eth', 'thegraph', {
  chainId: 100
})

Pull request

  • Add support for xdai network (#68)

Tokens connector renaming

The @aragon/connect-thegraph-token-manager package is now @aragon/connect-thegraph-tokens.

@aragon/connect-thegraph-token-manager won’t be updated after 0.3.0 and has been marked as deprecated. Please remember to update your package.json files!

Pull request

  • Renamed token-manager connector to tokens (#74)

TransactionPath and TransactionRequest API changes

TransactionPath

  • TransactionPath#forwardingFeePretransaction has been added.

TransactionRequest

  • The following properties have been removed from TransactionRequest: chainId, gas, gasLimit, gasPrice, value. They can be set as needed by app authors before passing it to an Ethereum library to sign.
  • description and descriptionAnnotated have been added and contain two formats for the radspec description of the transaction. description is a string, while descriptionAnnotated is a list of annotations following the format { type: string, value: any }.

Pull request

  • Refactor transactions (#73)

Other changes

  • Emit an error when a subgraph URL is invalid (#47)
  • Fix yarn clean (#71)
  • Add package.json files field (#67)
  • Removed GraphQL types (#70)
  • Token manager subgraph: fix duplicated balances (#75)
  • Upgrade Ethers to 5.0.0 (#73)