JavaScript初心者がNEM Library使ってWebアプリを作りたい、から環境構築した(その3)

2回目でやっとローカルサーバー＋Debug(省略しましたが)環境まで整いました。
やっと本題のNEM Libraryをインストールして、動作させてみます。

# NEM Libraryのインストール
もはやおなじみのF1キーでクイックオープンですが、Yarn: Add and Save dev. Dependencyを実行します。
`nem-library`をインストールします。
devに入れる場合、ブラウザから実行時に`nem-sdk`も必要なようなので、`nem-sdk`も入れます。
`nem-library`は内部的に`nem-sdk`を使っているようです。(エラー時のスタックトレースでもわかる)

以下は私の想像であり何ら裏付けありません(調査もしていません)
> VC的な解釈をすると、ブラウザから実行時にはパス構成が変わって、ライブラリが参照できなくなるような感じかと。
> devに入れておけばビルド時に必要なものは取り込んだうえでビルドしてくれる？
> devないほうだと、「参照できることを信じる」っぽいので、I/F＋参照パスって感じだから、ローカルでの実行だとOKだけど、デプロイすると参照できなくなってNGと想像しました。

```json:package.json
    "devDependencies": {
        "babel-cli": "^6.26.0",
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.4",
        "babel-preset-env": "^1.6.1",
        "nem-library": "^1.0.1",
        "nem-sdk": "^1.6.4",
        "webpack": "^4.5.0",
        "webpack-cli": "^2.0.14",
        "webpack-dev-server": "^3.1.1"
    }
```

src/index.jsを書き換えます。
例えば、アドレスから残高(balance)を参照する場合です。
https://qiita.com/y-temp4/items/9be4b041565a4bb24dab
https://nemlibrary.com/documentation/account/#accounthttp-usage

```javascript:index.js
import {AccountHttp, NEMLibrary, NetworkTypes, Address} from "nem-library";

// Initialize NEMLibrary for TEST_NET Network
NEMLibrary.bootstrap(NetworkTypes.TEST_NET);

const address = new Address("TBFYMCJ6BZ6OSZJB5XGWN2JSGA5FYA7LBJBPAWGE");

const accountHttp = new AccountHttp();
accountHttp.getFromAddress(address).subscribe(accountInfoWithMetaData => {
    console.log(accountInfoWithMetaData.balance.balance);
});
```
これをビルド(`yarn run build`)し、nodeで実行します(`node lib/index.js`)。
ビルドはpackage.jsonのscriptsで定義している`build`ですので、実際はbabelが実行されます。
babelが実行されると、出力先のlibフォルダにindex.js(srcと同じ名前)が出力されます。

```terminal:実行結果
PS C:\project\myproject> yarn run build
yarn run v1.5.1
$ babel src -d lib
src\index.js -> lib\index.js
Done in 3.50s.
PS C:\project\myproject> node lib/index.js
88550000
PS C:\project\myproject>
```

動きました。
次にブラウザで動作させますが、エラー(Cannot find module "net" Can't resolve 'fs' Can't resolve 'tls'など)が出る場合には、`webpack.config.js`にnodeの記載がないとまずそうなので、以下を最下部に追記して実行します。
https://webpack.js.org/configuration/node/

```javascript:webpack.config.js
  node: {
    console: false,
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  }
```

# アカウントを作る
NEMのメッセージで「Hello World」するためには、少なくともアカウントが2つ必要です。
先ほどのindex.jsのサンプルコードのアドレスは私がテスト用に作ったものです。

1. こちら( https://nem.io/downloads/ )からnano Walletをダウンロードします。
2. アカウント作成をします
3. シンプルウォレットを選択します
4. Testnetを選択します
5. ウォレット名を入力します
6. パスワードを設定します
7. 秘密鍵を作成し、注意事項に同意します
8. ウォレットファイルのバックアップを取得します
9. 秘密鍵のバックアップを作成し、作成を完了します
10. トップページに戻るのでログインします
	- ログインできればウォレット(+1つ目のアカウント)は作成完了です。
	(ダッシュボード画面右上)![image.png](https://qiita-image-store.s3.amazonaws.com/0/249932/5c3634b5-f690-6087-feb5-c8347d357846.png)
- ノードが緑になっていることを確認します
	- 赤の場合にはノードをクリックし、ノードリストから接続先ノードを変更します

# 2つ目のアカウントを作成する
1. ダッシュボード画面右上のアカウントをクリックするとアカウント情報画面に遷移します
2. ウォレットに新規アカウント(アドレス)を追加をクリックします
	- ![image.png](https://qiita-image-store.s3.amazonaws.com/0/249932/03cad4bc-5328-f7ee-f88e-a0754dec9c06.png)
3. パスワードを入力し、新しいアカウントの名前を入力します。
4. 別のアカウントに切り替えるが表示されますので、新しいアカウントに切り替えます
	- ![image.png](https://qiita-image-store.s3.amazonaws.com/0/249932/a7eaacf7-3b7c-d44f-ff22-f681d5f3720a.png)
5. ダッシュボード画面右上のアカウントがPrimaryから変わっています。
	- ![image.png](https://qiita-image-store.s3.amazonaws.com/0/249932/297de698-f79e-d594-5054-320d929e03f4.png)
6. それぞれのアカウントのアドレスを適当にコピーしておきます
	- 以降の作業でコピペで入力するためです

# アカウントを使えるようにする
アカウントを作成しただけでは、NEM Libraryから使えないようです。
index.jsのAddressに作成したばかりのアカウントのアドレスを入れて実行すると、以下のように表示されます。

```terminal:実行結果
PS C:\project\myproject> node lib/index.js
C:\project\myproject\node_modules\rxjs\util\subscribeToResult.js:43
            root_1.root.setTimeout(function () { throw err; });
                                                 ^

Error: Not a valid public key
(以下省略)
```

アカウント情報画面の公開鍵欄に`You need to make a transaction to get a public key`と書かれており、公開鍵が作成されていないことがわかります。
アカウントでトランザクションを作成したときにはじめて公開鍵が作成されるようです。

トランザクションを作成するにはXEMが必要ですが、作成したばかりのアカウントは0XEMです。
Mainnetであれば、取引所等でXEMを購入し、アカウント情報画面のアドレスに送付すれば解決です。
Testnetの場合は、こちら( https://tomotomo9696.xyz/nem/faucet/ )で配布されています。
注意事項を守り、ありがたく使わせていただきます。

1. 配布を受けたアカウント(primary)のダッシュボード画面上部にある「送信」をクリックします。
2. 以下のように送信設定します
	- 宛先のアドレス ： もう一方のアカウント(例：secondary)のアドレス
	- 量 ： 適当(10XEM以上は送っておくといいと思います)
	- メッセージ ： 空欄
	- メッセージタイプ ： 平文
	- モザイクを送信 ： チェックなし
3. パスワードを入力し、送信します
4. もう一方のアカウント(secondary)に切り替え、トランザクションが承認済みになっていることを確認します
	- 未承認の場合には1分程度待つと承認済みになります
5. 配布を受けたアカウント(primary)にトランザクションを送信します
	- 量は0でよいです
6. 配布を受けたアカウント(primary)に切り替え、トランザクションが承認済みになっていることを確認します
7. さらにアカウント情報画面にて、公開鍵が作成されていることを確認します
	- 公開鍵は作成したトランザクションが承認された時点で作成されているようです。

これで2つのアカウントに公開鍵が作成され、XEMもある状態になりました。
やっと環境構築が終わりました。

# NEM Libraryでコメント付きのトランスファートランザクションを作成する
公式( https://nemlibrary.com/guide/transaction/ ) から以下を参考にします。
	- How to sign a Transaction
	- How to create a Transfer Transaction with a Message
メッセージ付きトランスファートランザクションを作成して、サインすればよさそう。
サインには秘密鍵(privatekey)が必要になります。

xxxxxxxxxxxxのところに実際に秘密鍵を書いておきます。

```javascript:index.js
import {
    NEMLibrary, NetworkTypes, Address, Account, TransferTransaction, TimeWindow,
    TransactionHttp, XEM, PlainMessage
} from "nem-library";

// Initialize NEMLibrary for TEST_NET Network
NEMLibrary.bootstrap(NetworkTypes.TEST_NET);

const youAddress = new Address("TDRFRYEFSPCRZ4E2LT2UIVXRMST6MIEUPLNIEVHK");

// Replace with a cosignatory private key
const privatekey = "xxxxxxxxxxxx";
const account = Account.createWithPrivateKey(privatekey);

const transferTransaction = TransferTransaction.create(
    TimeWindow.createWithDeadline(),
    youAddress,
    new XEM(0),
    PlainMessage.create("Hello nem world!")
);

const transactionHttp = new TransactionHttp();
const signedTransaction = account.signTransaction(transferTransaction);
transactionHttp.announceTransaction(signedTransaction).subscribe( x => 
        console.log(x)
    );
```

まずローカルで動作させます。
ビルド`yarn run build`して、nodeで実行します`node lib/index.js`

```console:実行結果
PS C:\project\myproject> yarn run build
yarn run v1.5.1
$ babel src -d lib
src\index.js -> lib\index.js
Done in 4.36s.
PS C:\project\myproject> node lib/index.js
NemAnnounceResult {
  type: 1,
  code: 1,
  message: 'SUCCESS',
  transactionHash:
   { data: '10e37ffb6c88618e4db50cefdb3fdbcdf035c89bbc2e6fa8bc47f5434f215ed8' },
  innerTransactionHash: {} }
```

SUCCESSとあるため、成功したようです。
これを受信側のアドレスのnano Walletのダッシュボードで見ると、以下のように未承認欄に、送られてきていることがわかります。(ちゃんとメッセージも入っています)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249932/1d97653e-806a-2803-dd68-433aea2159b5.png)
少し待つと承認済みになります。

次にブラウザで動作させます。
`yarn run start`でwebpack-dev-serverを動作させます。
localhostを開き、F12でコンソールを開くと、ちゃんとありました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249932/e4a235fc-7527-1ced-06a5-033d0e784e7b.png)

# NEM Libraryでトランザクションからコメントを取得する
nano Walletでは当然メッセージが見れましたが、これをNEM Library使って取得します。

公式( https://nemlibrary.com/guide/account/ ) から以下を参考にします。
	- How to receive incoming transactions for an account
また、https://nemlibrary.com/documentation/transaction/#transfertransaction を参照し、メッセージの取得方法を確認します。

大まかに以下な感じでした。
1. `subscribe`で取得できるtransactionは配列です。先頭(0番目)が新しいようでしたので、これを参照します。
2. 取得したtransactionからメッセージを取り出す。暗号化していないのでplain()で取得します。

```javascript:index.js
import {
    AccountHttp, NEMLibrary, NetworkTypes, Address
} from "nem-library";

// Initialize NEMLibrary for TEST_NET Network
NEMLibrary.bootstrap(NetworkTypes.TEST_NET);

const youAddress = new Address("TDRFRYEFSPCRZ4E2LT2UIVXRMST6MIEUPLNIEVHK");

const accountHttp = new AccountHttp();
accountHttp.incomingTransactions(youAddress).subscribe(transaction => {
        console.log(transaction[0].message.plain());
    });
```

まずローカルで動作させます。
ビルド`yarn run build`して、nodeで実行します`node lib/index.js`

```console:実行結果
PS C:\project\myproject> node lib/index.js
Hello nem world!
```
問題ないですね。

次にブラウザで動作させます。
`yarn run start`でwebpack-dev-serverを動作させます。
localhostを開き、F12でコンソールを開くと、ちゃんとありました。わかりにくいですが。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249932/736bdcd8-38c3-7d96-1153-4664c4f40b17.png)

---
というわけで、**Hello Worldまで超長かった！！！**
**こんなに長くかかるHello Worldないわー！**

NEMはLibraryあるから簡単っぽい話をどこかで見ましたが、Web界隈の住人じゃないと超絶難易度でした。

環境ができたので、マルチシグ、アポスティーユ、モザイクを試してみたいと思います。
そのまえに、RxJSとReactやらないと、いいかげんconsole.logだけじゃカッコ悪い。
なので、今の環境でRxJSとReact導入してのお試しが先になると思います。

[JavaScript初心者がNEM Library使ってWebアプリを作りたい、から環境構築した(その1)](https://qiita.com/kihaku_dol/items/fa53256de1aafcd110af)
[JavaScript初心者がNEM Library使ってWebアプリを作りたい、から環境構築した(その2)](https://qiita.com/kihaku_dol/items/8e1b4787a36cd23a87d2)
[JavaScript初心者がNEM Library使ってWebアプリを作りたい、から環境構築した(その3)](https://qiita.com/kihaku_dol/items/049c94731482b6f346c7)

---
**変更履歴**
2018/05/10 リンク先を追加