30億のデバイスで走りうるnem-kotlin

煽りみたいなタイトルでスミマセン。

## nem-kotlin というライブラリをリリースしました

NEM の API を使うためのラッパーライブラリです。その名の通り、Kotlin 製です。

[nem-kotlin のGitHub リポジトリ](https://github.com/ryuta46/nem-kotlin)

NIS に対しての REST API のリクエスト/レスポンスをラップしたり、送金トランザクションの署名を行ったり出来ます。

## 使い方

細かい部分は [Github 上の README](https://github.com/ryuta46/nem-kotlin/blob/master/README.ja.md) 見ていただくと良いかと思います。
ここではざっくりと説明します。

### 準備

本体

```
implementation 'com.ryuta46:nem-kotlin:0.3.0'
```
依存ライブラリ

```
implementation 'com.madgag.spongycastle:prov:1.51.0.0'
implementation 'com.madgag.spongycastle:core:1.51.0.0'
implementation 'net.i2p.crypto:eddsa:0.2.0'
implementation 'com.google.code.gson:gson:2.8.2'

// for reactive client or WebSocket client users
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxkotlin:2.1.0'

// for WebSocket client users
implementation 'org.java-websocket:Java-WebSocket:1.3.6'
```

### サンプル1. アドレスの残高取得

同期処理で取得

```kotlin
val client = NemApiClient("http://62.75.251.134:7890")
val accountInfo = client.accountGet("アドレス").account
val balance = accountInfo.balance // XEM 残高
```

Reactive に取得

```kotlin
val rxClient = RxNemApiClient("http://62.75.251.134:7890")
rxClient.accountGet("アドレス")
    .subscribeOn(Schedulers.newThread())
    .subscribe { response: AccountMetaDataPair ->
          val accountInfo = response.account
          val balance = accountInfo.balance // XEM 残高
    }
```

### サンプル2. 送金

先に署名するアカウントのインスタンスを作成してからトランザクションを作成します。

```kotlin
val account = AccountGenerator.fromSeed(ConvertUtils.toByteArray("秘密鍵"), Version.Main)
val transaction = TransactionHelper.createXemTransferTransaction(account, "送金先のアドレス", amount)
val result = client.transactionAnnounce(transaction)
```

### サンプル3. WebSocket でリアルタイム処理

WebSocket を使うと、指定した情報が更新される度に通知を受け取る事ができます。
下記は、所有しているモザイク量の変化をリアルタイムに検知するサンプルです。

```kotlin
val wsClient = RxNemWebSocketClient("http://62.75.251.134:7778")
val subscription = wsClient.accountMosaicOwned(address)
                .subscribeOn(Schedulers.newThread())
                .subscribe { mosaic: Mosaic ->
                    // mosaic が所有しているモザイクの情報
                }
```

**通知が必要なくなったら必ず dispose を呼び出してください。**

```
subscription.dispose()
```

## 特長

### 特長1. 用途に応じた 3種類のクライアント

* NemApiClient  
同期クライアント
* RxNemApiClient  
Reactive なクライアント  
* RxNemWebSocketClient  
WebSocket を使う場合のクライアント

NemApiClient と RxNemApiClient は同じインターフェイスを持っています。

NemApiClient の方が簡単に使えますが、呼び出し元スレッドをブロックします。

RxNemApiClient は Observable なオブジェクトを返すので、Reactive なプログラムに慣れている方はこちらのほうがオススメです。

RxNemWebSocketClient は WebSocket を使ったリアルタイム処理を行うためのクライアントです。こちらも Observable を返します。

### 特長2. 環境依存部分を外部から設定できる

ロガーと HTTP 処理部分を自前実装したもので拡張することが出来ます。

```kotlin
val client = NemApiClient("http://62.75.251.134:7890", yourHttpClient, yourLogger)
```

OkHttp を HTTP クライアントとして使いたい、ロガーで Android の Log.* を使いたい、といった場合に有効です。

### おまけ ライブラリに実装がない API を使いたい場合

Version 0.3.0現在、NEM の API 全てを実装しているわけでないです。すみません。

未実装のAPI は下記の様に自前でデータ型とパスを渡せば他のAPI と同様に処理できます。これで回避してください。

```kotlin

data class HarvestInfoArray(val data: List<HarvestInfo>)
val harvests: HarvestInfoArray = client.get("/account/harvests/", mapOf("address" to account.address)
```

## nem-kotlin の使いどころ

Kotlin という言語が大きく認知されるようになったのは、[今年の Google I/O で Kotlin が Android の公式開発言語に選定された](http://jp.techcrunch.com/2017/05/18/20170517google-makes-kotlin-a-first-class-language-for-writing-android-apps/)ことに起因しているように思います。

このニュースもあって、Kotlin は Android 用の開発言語という認識になってしまっているかもしれませんが、実際は AltJava、つまり Java の代替として開発されているものなので、**Java が動いている環境であれば基本的に動きます。**

nem-kotlin は Android 依存コードを利用しないようにしていますので、もちろん Android 上でも動くし、サーバサイドでも動きます。

まだ自作が多いですが、利用例

* [NEM総合アプリ](https://play.google.com/store/apps/details?id=wacode.yamada.yuki.nempaymentapp)
    山田ユキ氏( [@YukiYamadaJP](https://twitter.com/YukiYamadaJP) ) が作成した Android アプリです。nem-kotlin を使って頂いています。

* [送金サンプルアプリ](https://github.com/ryuta46/nem-kotlin/tree/master/samples/simple-android)
    nem-kotlin リポジトリ内にある XEM、モザイク送信のサンプルアプリです。

* [NEMの入出金を通知するSkypeのBotを作ったので試験公開](https://ryuta46.com/805)
    Skype の Bot。
    Kotlin の Web フレームワーク [Ktor](https://github.com/ktorio/ktor) と組み合わせてサーバサイドで動かしています。

* [NEMで特定のモザイク所有者のみが開けるドアを作ってみた](https://ryuta46.com/858)
    実質 Android ですが、Raspberry Pi 3 上で動かしています。IoT 分野でも使えるかもしれない、という実験です。


## おわりに

Advent Calendar 最終日なのでそれっぽいことを。

NEM Advent Calendar、様々なサービス、言語の話しがありましたね。
実際、NEM で何かを作っている方々は、開発言語も様々かと思います。

私は Kotlin 好きなので、この記事でも Kotlin のこと書いていますが、正直使う言語なんてなんでも良いです。

これだけ多くの環境に適用されているのは、開発者が REST API や WebSocket といった汎用的な技術を使って NEM ブロックチェーンに容易にアクセスすることが可能になっているからで、
それが NEM の大きな魅力になっていると思います。

NEM のアプリ開発は今日からでも始めることができます。みなさんも、是非。