Developer Documentation

From Status Wiki
This is the approved revision of this page, as well as being the most recent.
Jump to: navigation, search

Getting Started

In this page, you will learn what the two main languages used in Status are, how to learn them, how to build Status, & finally how to find tasks to work on.

Status is largely written in two languages: ClojureScript & Golang and builds on React Native for UI. I'll talk about the rational behind these design decisions and link to offsite resources on learning each of these technologies.

React Native

Status has always aspired to have a single, unified codebase for multi-platform development. This is not so easy to achieve, as many of the non-web-based solutions out there allow you to have a semi-single codebase, but you find yourself creating a lot of separate logic for handling user interfaces on each platform - Status is 80% frontend code and this presents a problem. We tried Xamarin & Java (EthereumJ was the first implementation we got running on Android & iOS - via RoboVM), and we quickly discovered this problem.

Mobile apps built on web-based technologies, such as those done in Cordova, are great for short-term projects or mvp, but you will quickly run into performance issues on resource-limited devices and may need to rewrite you app. In our tests displaying webView DApps in a chat history with iframes and all the other bells and whistles we wanted turned out to be a futile effort.

That limited our options to choosing between NativeScript & React Native. We chose React Native because it is more mature and is being used in production for popular apps like Facebook, Instagram, AirBnB, Baidu & Discord. This gave us the impression that this framework was here to stay with many Fortune 500 companies invested in its continuance.

At this point all we had to do is merge Material & iOS design into our unique look'and'feel so that we could minimise the amount of Android & iOS specific code. Our amazing designer Andrei Mironov elegantly solved the rest of that puzzle.

React Native Learning Resources

If you would like to start learning React Native, check out these resources: Use React Native React Native ReadTheDocs you might want to continue reading and learn more about re-natal, re-frame & reagent.

Re-natal

Re-natal is an invaluable tool to that automates the setup of your re-frame React Native for Android & iOS, it includes figwheel for easy development.

Re-frame

Re-frame is simple but expressive library for writing Single Page Applications in ClojureScript, using Reagent. It is a functional framework for reactive 'MVC-style' applications. To learn more:

Reagent

Reagent provides a minimalistic interface between ClojureScript and React. It allows you to define efficient React components using nothing but plain ClojureScript functions and data, that describe your UI using a Hiccup-like syntax. The goal of Reagent is to make it possible to define arbitrarily complex UIs using just a couple of basic concepts, and to be fast enough by default that you rarely have to care about performance.

ClojureScript

“Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.” — Eric Raymond. To read more quotes on Lisp read Lisp, made with secret alien technology.

Building Status

This document is the entry point for developers of Status. This guide is for anyone who is interested in building, developing, debugging or submitting a bug report, pull request or contributing to Status with code.

This guide is written with OS X in mind.

Build and Run Requirements

Windows-specific Setup Notes

Setting up a development instance in Windows requires some tweaks. Consider the following before attempting the following sections:

  • Make sure you run everything in a elevated command prompt (Right-click a link to Cmd.exe or Cygwin and click 'Run as Administrator')
  • Do not use the ./re-natal symlink. Write your own re-natal.sh script that uses full relative paths, give it execution permissions with chmod +x, and use it instead. Script:
#!/usr/bin/env node
require('coffee-script/register');
require('./node_modules/re-natal/index.js'); 
  • In the root package.json edit "./postinstall.sh" to "postinstall.sh"
  • Any npm install commands (except for npm install -g global commands) should be done as follows, to avoid windows symlink problems: npm install --no-bin-links
  • Do not use Cygwin for npm install commands, use cmd.exe.
  • React-native is not bug-free. If you run into an error like error: bundling: UnableToResolveError: Unable to resolve module..., the guaranteed solution is to manually edit the require()statements to the full relative path. E.g. (crypt = require('crypto')) becomes (crypt = require('../../../../node_modules/crypto/package.json')).

Android-specific Setup Notes

For Android you need to setup the NDK package in order to be able to build the application. The NDK is needed so that status-go logs can be read via adb logcat command.

  • Download NDK from https://developer.android.com/ndk/downloads/index.html or using the SDK Manager in Android Studio Tools > Android > SDK Manager
  • If you downloaded the NDK from the website unzip it
  • Set the environment variable $ANDROID_NDK_HOME to the NDK directory e.g. Android/Sdk/ndk-bundleif you downloaded it using the SDK Manager
  • If you get  A problem occurred starting process 'command 'null/ndk-build'' while running react-native run-android check the file status-react/android/local.properties and if it exists add the line ndk.dir=Android/Sdk/ndk-bundle(replace Android/Sdk/ndk-bundleby the path of your NDK directory)

Dependencies & Setup

$ git clone [email protected]:status-im/status-react.git -b master && cd status-react
# or
$ git clone [email protected]:status-im/status-react.git -b develop && cd status-react

$ lein deps && npm install && ./re-natal deps && ./re-natal use-figwheel && lein re-frisk use-re-natal && ./re-natal enable-source-maps
$ mvn -f modules/react-native-status/ios/RCTStatus dependency:unpack
$ cd ios && pod install && cd ..

Building Status for Release

# fill in store file properties in android/gradle.properties
$ lein prod-build
$ react-native run-android --variant=release
# for iOS, build in Xcode

Building Status for Development

$ lein prod-build

$ ./re-natal use-android-device <device> # (genymotion, real or avd)
# or
$ ./re-natal use-ios-device <device> # (simulator or real)

$ ./re-natal use-figwheel

# new tab, run figwheel REPL
$ BUILD_IDS="ios,android" lein repl

# new tab, run react native packager
$ react-native start

# FOR ANDROID
# new tab, enable communication to react-native, figwheel and re-frisk debugging
$ adb reverse tcp:8081 tcp:8081
$ adb reverse tcp:3449 tcp:3449
$ adb reverse tcp:4567 tcp:4567
$ react-native run-android

# FOR IOS
$ react-native run-ios

Access Geth on Device

adb forward tcp:8545 tcp:8545
build/bin/geth attach http://localhost:8545

Contributing

Please make sure your contributions adhere to our coding guidelines:

  • Code must be idiomatic Clojure, please refer to the style guidelines (i.e. use lein eastwood & lein kibit).
  • Code must be documented.
  • Pull requests need to be based on and opened against the develop branch.
  • Commit messages should be prefixed with the root namespace(s) under status-im that they modify.
    • e.g. "contacts, ios: add contact stylistic changes"

Issues

Only Github is used to track issues. (Please include the commit and branch when reporting an issue.)

Overv.io is used to overview issues in multiple repositories.

Code formatting

Please run lein eastwood and lein kibit before contributing.

Branch naming

Branch format must be under CATEGORY/PLAIN-TEXT-#ISSUE_NUMBER acceptable branches are;

feature/discover or bug/broken-form-#113

The following categories are:

  • feature/ for implementation of features
  • bug/ for fixing bugs
  • tests/ for unit/UI tests
  • experiment/ for non-features
  • wip/ for longer lived branches
  • junk/ for irrelevant/soon-to-be-deleted branches

Pull Requests

Pull Requests should by default use the develop branch as a base. The master branch is kept stable and develop is periodically merged there. Tags are used for releases. Each Pull Request must be rebased against develop and squashed into a single commit.

Commit messages

Commit message should help understand why (and what) has been fixed. Add a summary as first line if the message is too long. When fixing bugs the first line should be prefixed with [FIX #123].

As a good practice message starts with capitalized verb in the imperative mood.

Walkthrough

Fork the repository on Github's web UI.

Clone your fork. Add the upstream as a remote.

$ git clone [email protected]:<you>/status-react.git
$ git remote add upstream [email protected]:status-im/status-react.git

Now you have two remotes: origin pointing to your fork and upstream pointing to the shared repo.

$ git fetch --all

Then isolate the bug/feature work you will do into a topic branch

$ git checkout -b bug/missing-contact-#116 upstream/develop

Keep your branch fresh against upstream

$ git fetch upstream
$ git rebase upstream/develop

If multiple people are working on the same feature branch don't forget to also

$ git rebase upstream bug/missing-contact-#116

When you are ready to make your pull request

$ git push origin

After PR has been reviewed do a final cleanup and squash your commit

$ git rebase -i upstream/develop
$ git push -f origin

Repository Overview

The Status application is divided into 6 core repositories;

  • status-react - our main react native application writtein in Clojurescript, Java & Objective C
  • go-ethereum - our branch of go-ethereum which contains our custom modifications in go-ethereum/status-develop
  • status-go - represents our binding to the go-ethereum lib and exposes methods to status-react to Java / Objective C

Adding your DApp to Status

While in Alpha anyone with a DApp on TestNetwork may request to be added to "Contacts" please see these guidelines for more information adding your DApp to Status .