A look under the hood of a decentralised VPN Application.

Donatas Kučinskas
Mysterium Network
Published in
5 min readNov 27, 2018

--

MysteriumVPN is the client application of Mysterium Network, a project focused on providing security and privacy to web 3 applications.

In this article, we will discuss the architecture of MysteriumVPN and how it integrates with Mysterium Node to ensure an encrypted end to end flow of data through Mysterium Network.

Cross-platform architecture

Usually, you need separate builds for each platform. Now that cross-platform technology has improved, this is no longer the case.

For desktop:

Electron is a framework which allows us to build cross-platform applications using common web technologies such as HTML, CSS and Javascript. We are using Electron which allows us to develop one application for two platforms for desktop — Windows and Mac OS. Linux coming soon. Download our alpha.

Under the hood of an Electron application, sits a Chromium browser; A website, rendered by an embedded browser.

For mobile:

We are kicking off our mobile development for MysteriumVPN, with Android versions set to release shortly.

For this, we are using React Native for cross-platform applications.

Most of MysteriumVPN is written in Javascript, which is run in a separate process. Javascript generates the virtual structure of the user interface. This Javascript process communicates to native mobile processes which are responsible for rendering the actual user interface as you see it.

The architecture of MysteriumVPN Desktop Client Application

How MysteriumVPN works on desktop:

Since we are using Electron, we have two processes, MAIN and RENDERER.

MAIN is the first process which is started when the application starts. It is a NodeJS process which is responsible for managing the following functions:

  • Application state and internal operations
  • Tray
  • Kicking off the RENDERER process

The second process is RENDERER and it is responsible for displaying the graphical user interface for the application.

Communication between processes:

Both the MAIN and RENDERER processes need to communicate with each other to stay in sync. For this reason, we are using a standard approach of Inter-Process Communication (IPC).

Javascript is not type-safe, which isn’t very reliable. We use Flow static type checker which adds type-safety for Javascript. This especially applies to syncing data between processes — it becomes less reliable when using out-of-the-box IPC. To improve that, with custom implementation on top to have type-safety.

MessageTransport describes a single typed message which is sent between processes. It creates alignment between both processes by introducing sender and receiver objects, ensuring that both sides expect the same arguments of this message.

Here is an implementation:

class MessageTransport<T> {
_channel: string
_messageBus: MessageBus
constructor (channel: string, messageBus: MessageBus) {
this._channel = channel
this._messageBus = messageBus
}
buildSender (): MessageSender<T> {
return new MessageSender(this._channel, this._messageBus)
}
buildReceiver (): MessageReceiver<T> {
return new MessageReceiver(this._channel, this._messageBus)
}
}
class MessageSender<T> {
_channel: string
_messageBus: MessageBus
constructor (channel: string, messageBus: MessageBus) {
this._channel = channel
this._messageBus = messageBus
}
send (data: T) {
this._messageBus.send(this._channel, data)
}
}
class MessageReceiver<T> {
_channel: string
_messageBus: MessageBus
constructor (channel: string, messageBus: MessageBus) {
this._channel = channel
this._messageBus = messageBus
}
on (callback: T => void) {
this._messageBus.on(this._channel, callback)
}
removeCallback (callback: T => void) {
this._messageBus.removeCallback(this._channel, callback)
}
}

Here is an example of communication between both these MAIN and RENDERER processes:

Example: communicating country proposal updates between processes:

MAIN process is managing country proposals internally and it sends all updates:

this._countryList.onUpdate(countries => {
this._communication.countryUpdate.send(countries)
})

RENDERER process listens for country updates,

this.rendererCommunication.countryUpdate.on(this.onCountriesUpdate)
...
onCountriesUpdate (countries) {
this.countriesAreLoading = false
this
.countryList = countries
}

Having such an abstraction layer ensures that communication is type-safe, reliable and features around it are simple to test.

How do we integrate Mysterium Node with MysteriumVPN Application?

Once we’ve rendered the application layer, we still need to connect MysteriumVPN to Mysterium Node. Mysterium Nodeis a software that connects you to Mysterium Network where you are able to exchange value for bandwidth.

MysteriumVPN is a client application of Mysterium Network. The successful running of our dVPN on the network will attract other use cases from existing or future businesses that require end-to-end encryption of data, thereby expanding Mysterium Network’s ecosystem.

We require specific information to ensure the successful running of our dVPN service.

Operation System Service
Since we are running Mysterium Node under the MysteriumVPN application we need to supervise the Mysterium Node to ensure that it works.

Our Data Protection Policy
We make a clear distinction between personal data and usage data. We do not collect information on who you are. We collect data on session and connection inputs and outputs. This is important data for us as it gives us visibility on how our technology fares against the realities of cyber oppression. Check out our privacy policy for more information.

Logging
Since we are integrating Mysterium Node into the MysteriumVPN application, the application itself gets quite complex. That’s why we have to be prepared to log errors from everywhere, — our application, Mysterium Node, and from Electron.

That means that there are three sources of inputs. When we are inspecting something, we need to understand that these errors can happen in three different places. We need to synchronise those and collect all relevant data from these sources.

Data management in the era of web 3 is complex and we hope to do so in an ethical and fair manner. Check out how our no logs policy protects your personal data.

Build on Mysterium Network

We have an npm package that allows for you to connect to Mysterium Node easily. This is the same package that the MysteriumVPN uses to connect to Mysterium Network. This can be used for any application — it’s literally plug and play.

Interested in contributing to Mysterium Network? We are an open source project focused on bringing privacy, security and freedom to web 3. Check out our Github.

--

--