The Status Mobile App Technology Stack

The Status Mobile App Technology Stack

Status is an open source, decentralised messaging platform, non-custodial crypto wallet, and web 3.0 browser, designed to act as a network node which interacts with decentralised applications (DApps) that run on the Ethereum network.

Status is an open source community of people committed to building better decentralised tools for web3, and making sure that everyone across the world can access these tools directly from their pockets.

The Status Network is an ecosystem of decentralised applications – building private, secure communication tools. We stand for upholding human rights, and empowering sovereign communities, therein becoming a gateway to undeniable free trade, peer-to-peer payments, and encrypted p2p communication for anyone with a smartphone and internet access.

In this article, we'll take a look at the underlying technology we use to build out the Status Mobile App, and also explore the reasons those technologies were chosen. From the backend to the frontend, we make use of many existing tech libraries, as well as rolling many of our own.

As a polyglot company, on our Github you will find that we have libraries ranging from C, Go, JavaScript, Nim, Clojure, all the way through to TypeScript, and with just about everything in between! Let's see how and why we utilise some of those:

Status-Go

Status-Go is the underlying backbone of the Status App. It relies heavily upon our own custom fork of go-ethereum, and is the technology which actually enables the Status client to interact with the Ethereum VM / Blockchain.

A simplified, but good, way to think about Status-go is that; it very much forms the backend of Status. It can also be built into several forms:

  • A cross-platform static library providing Status bindings for go-ethereum, ready to be used in other Go projects, or in status-react through cgo.
  • A command line interface, which can be used to run a full, LES (Light Eth Client) or ULC (Ultra Light Client) node, with support for Whisper mailserver functionality;
  • A command line tool to test availability of a given Whisper mailserver (used to check current uptime of the Status cluster).

NOTE: Normally the status-react library uses a precompiled version of status-go, but you can build a custom version of it to include in status-react if you so choose (see how-to in Build Status Yourself).

Status-React

Status-react is where most of what might traditionally be called the “frontend” logic sits (everything to do with UI components and interactions, chats, views etc.) and status-go is where all the heavier blockchain and backend logic sits. Status-go can be compiled as a stand alone library, and gets included as a static dependency in status-react at build time.

Status-react is actually written in Clojure & ClojureScript, which is a Lisp-like language that can be compiled down to React Native, so that we only have to maintain one codebase for many platforms.

Clojure / CLJS is one of the most performant frontend tools around; enabling the greatest productivity, with the fewest lines of code. However, a lot of that is lost in the compilation down to React Native, so what are our real motivations?

With Clojure you get a complete separation of functions and data. This means in the future we can do amazing things in Status extensions; allowing developers a lot of access to different parts of the data, that now lives client side in decentralised networks, without compromising on the security of our users. It also allows us rapid expansion of features, enabling a truly agile product.

Messaging - Whisper

One of the other most important underlying features of Status is our transport layer for the Status chat protocol.  Whisper is an identity-based messaging system and a hybrid P2P/DHT communication protocol, which delivers messages probabilistically. For more details on the protocol, visit https://status.im/research/

Multicast broadcasting:

When sending a message to a specific person, a user actually broadcasts that message to the entire network. Because it is encrypted with the intended recipient’s public key, only the designated recipient can view the message.

Time-to-live:

A message will bounce from node to node in the network even after it reaches its intended recipient until it’s time to live has expired - this provides plausible deniability that the message was intended for a specific recipient.

Envelopes:

As the name suggests, contain all the parts of a message. They can be compared to physical letters - all the nodes, regardless if they are the recipient or not, need to be able to handle the envelope, but only the recipient node knows how to “unseal” the actual message text. They are a packet format that encapsulates message text, along with metadata like time-to-live, and the message itself. Envelopes themselves are not encrypted, as they are part of the protocol and need to be readable by the nodes.

What does Whisper mean?

Whisper's features combine into a fully dark system – i.e. one that is uncompromising when it comes to information leakage from metadata. In its most secure mode of operation, Whisper can (at a considerable cost of bandwidth and latency) deliver 100% dark operation.

Distributed systems must make a trade off between the efficiency of deterministic routing, and darkness (i.e. routing privacy). This is why user config matters – the people who use the technology ought to be the ones deciding between routing privacy and efficiency, and ought to be able to do so in a granular and editable way.

At its most dark, Whisper nodes are entirely reactive - they receive and record pieces of data, and forward them trying to maximise the utility of information transmission to the peers.

However, Whisper is also designed to be able to route probabilistically using two methods, both giving away minimal routing information, and both being exceptionally resilient to statistical attacks from large-scale metadata collection.

Moving away from Whisper

Whisper is no longer under active development, after having Status as its core contributors for a long time. When Status was conceived, Whisper was the way forward, but it does have several drawbacks. Among others:

  • It is very wasteful bandwidth-wise and it doesn't appear to be scalable,
  • Proof of work is a poor spam protection mechanism for heterogeneous devices,
  • The privacy guarantees provided are not rigorous,
  • There are no incentives to run a node.

Finding a more suitable transport privacy is an ongoing research effort of ours, together with Vac, and other teams working within the space. Here at Status, we are currently working on an immediate upgrade to whisper called Waku.  More details can be found here.

Keeping Everything Secure

Status builds upon the X3DH and Double Ratchet specifications from Open Whisper Systems, with some adaptations to operate in our decentralised environment.

Forward Secrecy & E2E Encryption

Perfect Forward Secrecy is a feature of specific key-agreement protocols which provide assurances that your session keys will not be compromised even if the private keys of the participants are compromised. Specifically, past messages cannot be decrypted by a third-party who manages to get a hold of a private key.

End-to-end encryption (E2EE) takes place between two clients. The main cryptographic protocol is a Status implementation of the Double Ratchet protocol, which is in turn derived from the Off-the-Record protocol, using a different ratchet.

The message payload is subsequently encrypted by the transport protocol - Whisper, using symmetric key encryption.

Furthermore, Status uses the concept of prekeys (through the use of X3DH) to allow the protocol to operate in an asynchronous environment. It is not necessary for two parties to be online at the same time to initiate an encrypted conversation.

Wallet Key Management

Status never uses third party services for managing and storing public and private keys. Once generated, the first BIP44 key is saved in a keystore json file locally on your device. This file is encrypted with the password you choose for your Status account, and is only accessible by the Status app.

As a non-custodial wallet, Status gives you full control over your funds without the use of a central server. As mentioned above, private keys are stored in an encrypted manner on your device. Your money is under your control, and cannot be accessed by anyone without the private key.

Therefore, if you lose your mnemonic phrase, you will never be able to restore access to your funds. So backup your private keys somewhere safe, offline!

Web3 Browser Security

The Status browser is designed to keep the end user informed and their funds safe. Browser Privacy mode is enabled by default. This means that DApps will be required to ask permission before connecting to your wallet. (Which may cause some DApps to break, if they are not compatible with this security measure.)

Finally, the Status browser implements EIP712 which aims to improve the usability of off-chain message signing for use on-chain.

We are seeing growing adoption of off-chain message signing as it saves gas and reduces the number of transactions on the blockchain. Currently; signed messages are an opaque hex string, displayed to the user with little context about the items that make up the message.

User Management & Auth

Account generation

Generating a user account in Status involves 2 steps:

  • Generation of a random seed, and the respective account;
  • Generation of a X3DH bundle. This prekey bundle will become part of the user’s contact code.

Account recovery

If a user later recovers their account, the Double Ratchet state information will not be available, so they will no longer be able to decrypt any messages received from existing contacts.

If an incoming message (on the same Whisper topic) fails to decrypt, a message is replied with the current bundle, so that the other end is notified of the new device. Subsequent communications will use this new bundle.

Session Management

A peer is identified by two pieces of data:

  • A device installation-id (which is generated upon creating a new account in the Status application)
  • Their identity whisper key

Initialisation

A new session is initialised once a successful X3DH exchange has taken place. Subsequent messages will use the established session until re-keying is necessary.

Concurrent sessions

If two sessions are created concurrently between two peers the one with the symmetric key first in byte order should be used, marking the other has expired.

Re-keying

On receiving a bundle from a given peer with a higher version, the old bundle should be marked as expired and a new session should be established on the next message sent.

Multi-device support

Multi-device support is quite challenging as we don’t have a central place where information on which and how many devices (identified by their respective installation-id) belongs to a whisper-identity.

Furthermore we always need to take account recovery in consideration, where the whole device is wiped clean and all the information about any previous sessions is lost.

Taking these considerations into account, the way multi-device information is propagated through the network is through bundles/contact codes, which will contain information about paired devices as well as information about the sending device.

This means that every time a new device is paired, the bundle needs to be updated and propagated with the new information, and the burden is put on the user to make sure the pairing is successful.

Pairing

When a user adds a new device, a new installation-id will be generated. The device should be paired as soon as possible if other devices are present. Once paired the contacts will be notified of the new device and it will be included in further communications.

Any time a bundle from your Identity Key Pair, but different installation-id, is received the device will be shown to the user and will have to be manually approved, to a maximum of 3. Once that is done any message sent by one device will also be sent to any other enabled device.

Once a new device is enabled, a new contact-code/bundle will be generated which will include pairing information.

Removal of paired devices is a manual step that needs to be applied on each device, consisting simply of disabling the device; at which point pairing information will not be propagated anymore.

Sending messages to a paired group

When sending a message, the peer will do so to any installation-id that they have seen, using pairwise encryption, including their own devices.

The number of devices is capped to 3, ordered by last activity.

Partitioned devices

In some cases (i.e. account recovery when no other pairing device is available, device not paired), it is possible that a device will receive a message that is not targeted to its own installation-id.

In this case an empty message containing bundle information is sent back, which will notify the receiving end as to including this device in any further communication.

Status API

View our API Docs for more information, and to learn how to integrate your DApp into Status. You can read more about how to add your DApp to Status here.

Give me Binaries!

You can get our Beta builds for both Android and iOS on our website, through our nightly builds or by building it yourself.

Core Contributors

Core Team Members

Contact us

Feel free to email us at [email protected].im or better yet, join our chat.

Want to learn more about the tech used? Looking for a specific answer? Ask your question in our open forum discuss.status.im.

Not finding what you need? Get support in the #support channel in Discord.

Otherwise, if you would like to reach out to me personally, you can do so here!

- @rbin