tl;dr: We shipped the thing! 🚢 v2.0 is awesome because it: doubles down on what people love from v1, natively supports wallets, alleviates v1’s pain points, and improves trust assumptions. Wallets and dApps can get started by following the Quick Start in our docs. A work-in-progress (Rinkeby) Dai Card is available here.

After a long two months of Rinkeby testing, audits, and bugfixing, we’ve deployed v2.0 of Connext! 🌟

Where Do I Get It?

The best place to jump in is the Quick Start guide in our docs.

Come talk to us in our discord if you have any questions.

Code is available at: https://github.com/ConnextProject/indra

Work in progress Rinkeby v2.0 Dai Card is live at: https://rinkeby.indra.connext.network

What about a mainnet v2.0 Dai Card? Soon! We’re working on making sure there’s no UI gotchas that might cause users to lose funds.

V2.0 runs on Counterfactual. When you integrate v2.0, you’ll also eventually support the State Channels framework — the unified standard for channels on Ethereum.

How Does It Work?

Check out our testnet post for an overview of the tech!

Why Does V2.0 Matter?

Two years ago, we started Connext with a simple question:

“How can we bring 1 billion users to Ethereum?”

This question led us through a lot of product iterations at the conflux of scalability, UX and Ethereum transfers. We hypothesized that end users want a seamless and consistent experience in their wallets and applications, regardless of whether they have Eth for gas, or how congested the blockchain is, or even what sidechain/plasmachain/shard they are on.

We knew we had hit upon something important when we shipped the v1 Dai Card earlier this year and saw reactions like this:

When building v2.0, our goals were simple. First: double down on what users already love about Connext. This meant simplifying Connext integrations further, reimplementing easy onboarding via links as a default, and — most importantly — continuing to work on making our already magical transfers even faster.

Second: re-architect Connext as a primarily wallet-to-wallet network, which dApps can then hook into for their specific usecases. We found that wallets loved the user experience v1 enabled, and so we’ve redesigned the Connext client to work much more seamlessly with existing wallet development paradigms for key management and storage.

Third: rethink our approach to users’ biggest pain points. In v1, the hardest part about Connext was, unsurprisingly, the process of depositing into and withdrawing from the channel onchain. In v2.0, we not only simplified deposit/withdraw, but we also made it much possible for wallets to inject a provider for a user’s channel into a dApp , removing the need for users to deposit into more than one channel to begin with. Another huge headache in v1 was the inflexibility of the protocol, meaning that it took weeks or months to react to user feedback. In v2.0, we can instead add support for new applications or features in days.

Fourth: make credible, meaningful progress towards becoming a more trust-minimized and decentralized system. While true decentralization is still a little ways away, we successfully moved to being fully noncustodial and laid the groundwork for implementing Lightning-style multihop without too many future protocol changes. We cover this in more detail in Trust Assumptions below.

v2.0 of Connext is the culmination of all of the awesome feedback we’ve received so far from the community, and is also the first step towards an Ethereum layer two that is ready for day to day use.

Thank you all for being part of our wonderful journey so far!

Trust Assumptions

When we launched the Dai Card on v1 of Connext, we listed the major trust assumptions of our network. This time, we’ll review our old assumptions in addition to covering the new ones introduced in this update.

[Fixed] While in-flight, some payments were custodial

In v1, user funds were always noncustodial but transfers themselves, while in-flight, were sometimes held by the hub. This was particularly true for more conditional transfers like Link payments or transfers to offline recipients.

In v2.0, all transfers are fully noncustodial, even when in-flight. The hub has no ability to steal your funds. This is possible because v2.0 natively supports generalized state updates in channels, giving them much more flexibility.

[Fixed] Hub held the “master” copy of state and clients did not back up state by default

In v1, if you went offline, the hub was the only entity that persisted your state. This was great for cross-device compatibility, but meant that you relied on the hub to restore your state accurately and to be truthful during disputes. We originally intended to solve this by backing up state on IPFS, but have since decided to go in a different direction.

In v2.0, state storage and backup is left up to the wallet. The user must have a local copy of state to run a channel, which acts as a persistent “working copy” of state, but wallets can and probably should create further remote backups. Clients do not recover state from the hub by default anymore, though they can optionally do so if the end user chooses. We also no longer require that channel disputes are resolved by the channel owner only — this makes it possible for wallet providers to act as Watchtowers for their users.

[In-progress] Updates happen via http and are censorable

In v1, the hub was a REST server and clients communicated updates via http POSTs. This was a good tactic to keep things simple but meant that the hub mandated a clunky request-based flow to update states and could censor those updates.

In v2.0, we’ve moved to NATS — a highly scalable, lightweight, open source, p2p messaging system. NATS lets us move the hub away from the http-request paradigm, making it possible to have multiple independent copies of state. Unfortunately, it still requires that we implement a messaging server (currently hosted by the hub) to work properly. This means that while they’re now p2p, messages in the centralized v2.0 hub are still censorable like in v1.

The decision to use NATS specifically is a step towards solving this problem, though. NATS supports decentralized (mesh) messaging by clustering many messaging servers together. This means is that we can ship clustered NATS instances as part of the Connext nodes in our eventual decentralized network, to decentralize our messaging layer in tandem.

[In-progress] Transfers happen through the hub and are censorable

In v1, every user deposited into channels with the hub and then routed transfers to each other over the hub (similar to how 0x relayers work). This was a bootstrapping technique to create a reliable, easily iterable system while we collected user data and tested a variety of different usecases. This also meant, however, that our hub could be censored, DDoS’d or shut down, putting our payment service offline (though no user funds would be lost!).

At launch, v2.0 uses the same paradigm and can still be censored. There’s still work that needs to be done before we can be a truly decentralized network. However, the addition of p2p messaging and generalized state is a huge step in the right direction. We can now rapidly iterate on more extensible transfer protocols without needing to do a full rewrite of the system or drastically update interfaces.

[New] Client proxies through hub’s interface to access Redlock

By decentralizing user state storage, we introduced complexity related to concurrently updating state. In centralized servers, concurrency is handled by locking/unlocking state on each operation. For our distributed paradigm, we integrated Redis’ distributed locks in the hub. Unfortunately, Redis isn’t natively supported in browsers and Webdis, the browser-based Redis interface, doesn’t support Redlock.

In the interest of shipping efficiently, we built a proxy interface hosted by the hub for the client to lock/unlock their state. In the short to mid term, we expect to reimplement or modify Webdis to use distributed locking as well.

Technical Details

Contracts have been independently audited:

Mainnet contracts:

Contract code: