自前ノードを使って簡単なライトニングアプリを作ってみる【後編】

自前ノードを使って簡単なライトニングアプリを作ってみる【後編】

今回も簡単なライトニングアプリを、前回とはちょっと違ったやり方で作ってみたいと思います。

前回の記事です↓

準備

以下のものを使用します。
Node.js
Vue cli
Heroku cli
Git
Tor
LNDノード(umbrelも可)

torrcの編集(umbrelの方は飛ばしてください)

前回はノードを操作するインターフェースとしてgRPCを使用しましたが、今回はRESTのHidden Serviceをアプリに使用します。
ノードを運用しているラズパイなどにTorをインストールしたら(最低でもcontrolportのパスワード設定はやったほうがいいと思われます)、まずtorrcを編集します。

sudo nano /etc/tor/torrc

LNDのRESTはデフォルトではポート8080番なので、以下を追加し保存します。

HiddenServiceDir /var/lib/tor/lnd-rest 
HiddenServicePort 8080 127.0.0.1:8080 

保存できたらTorを再起動し、Hidden Serviceのhostnameを確認します。

sudo cat /var/lib/tor/lnd-rest/hostname

.onion」で終わるアドレスが出力されます。

lnd.confの編集

Hidden Serviceを介してノード操作できるようにlnd.confを編集していきます。
まずは以下のコマンドでhostnameを確認します。

sudo cat /var/lib/tor/lnd-rest/hostname
umbrelの場合
sudo cat ~/umbrel/tor/data/lnd-rest/hostname

確認出来たらlnd.confに設定します。

sudo nano ~/.lnd/lnd.conf
umbrelの場合
sudo nano ~/umbrel/lnd/lnd.conf

以下のようにtlsextradomainhostnameを設定します。(umbrelの場合はすでに設定されているものを消さないようにしてください。)

tlsextradomain=sffkvl......ssfgd.onion

新しくTLS証明書を作成する必要があるので、古いものを削除します。

rm ~/.lnd/tls.*
umbrelの場合は
rm ~/umbrel/lnd/tls.*

削除したらLNDを再起動し、新しくTLS証明書が作成されているか確認してください。
設定が終わったので、プロキシ経由でRESTに接続できるかテストします。

curl -x socks5h://127.0.0.1:9050 -k --header "Grpc-Metadata-macaroon: $(xxd -ps -u -c 1000 ~/.lnd/data/chain/bitcoin/mainnet/readonly.macaroon)" https://`sudo cat /var/lib/tor/lnd-rest/hostname`:8080/v1/getinfo
umbrelの場合
curl -x socks5h://127.0.0.1:9050 -k --header "Grpc-Metadata-macaroon: $(xxd -ps -u -c 1000 ~/umbrel/lnd/data/chain/bitcoin/mainnet/readonly.macaroon)" https://`sudo cat ~/umbrel/tor/data/lnd-rest/hostname`:8080/v1/getinfo

以下のようにノードの情報が返ってくれば大丈夫です。

{"version":"0.13.3-beta commit=v0.13.3-beta"........"is_known":true}}}

プロジェクトの作成

次にプロジェクトを作成します。

vue create lapp-sample2

Manually select featuresを選択
                ↓
Vuexと CSS Pre-processorsにチェック
                ↓
2.xを選択
                ↓
Sass/SCSS (with node-sass)を選択してあとは全部Enterを押します。作成が完了したら下記コマンドを実行し、http://localhost:8080にアクセスしてサーバーが起動しているか確認します。(Ctrl+Cで停止)

cd lapp-sample2
npm run serve

バックエンドの作成

必要なパッケージをインストールします。

npm install express socket.io ws got socks-proxy-agent dotenv

まずはserver/index.jsを編集します。初心者コードですが、今回はコードをすべてgistに上げました。

mkdir server && touch server/index.js

index.js

次にserver/routes/invoices.jsを作成します。

mkdir server/routes && touch server/routes/invoices.js

invoices.js

アプリの構成は前回とほとんど同じです。createInvoiceでインボイスを作成、subscribeToInvoicesでインボイスの更新を購読し、支払いがあったタイミングでインボイスをクライアントに送信するようにします。だだし、今回はこれらの関数を自分で用意する必要があるのでserver/controllers/lnd-rest.jsに関数を定義します。

mkdir server/controllers && touch server/controllers/lnd-rest.js

lnd-rest.js

最後に.envファイルを作成し編集します。

touch .env.local

.env.local

.envファイルには3つの値を設定します。
HS_HOSTにはlnd.confの編集で確認したHidden Serviceの.onionアドレスを設定してください。LND_MACAROONLND_CERTは以下のコマンドで取得できる値をそれぞれ設定します。

base64 ~/umbrel/lnd/data/chain/bitcoin/mainnet/invoice.macaroon | tr -d '\n'
base64 ~/umbrel/lnd/tls.cert | tr -d '\n'

こんな感じになると思います。

HS_HOST=yul4czkfj47.......2szwxqad.onion
LND_MACAROON=AgFDbG9kA........I9gxavn4cUat
LND_CERT=AgEFbG6kAagDFhCaYP........0FARS7tLS0Fg==

フロントエンドの作成

バックエンドの作成が終わったので、フロントエンドを作成していきます。
まずは必要なパッケージをインストールします。

npm install axios socket.io-client vue-qrcode@0.3.6 qrcode

今回も前回と同じように、インボイスの支払いがあったタイミングで画面をちょっと変えるようなアプリにしたいと思います。
まずはsrc/App.vueを編集します。

App.vue

src/viewsHome.vueSettled.vuesrc/componentsModal.vueNav.vueを作成し、編集します。

mkdir src/views && touch src/views/{Home.vue,Settled.vue} && rm src/components/HelloWorld.vue && touch src/components/{Modal.vue,Nav.vue}

Home.vue
Settld.vue
Modal.vue
Nav.vue

次にvuexを設定します。src/store/index.jsを編集します。

index.js

いくつかディレクトリとファイルを作成します

mkdir src/assets/stylesheet && touch src/assets/stylesheet/style.scss && mkdir src/assets/image && mv src/assets/logo.png src/assets/image

次にスタイルを設定します。src/assets/stylesheet/style.scssを編集します。javascriptと一緒にcssも最近勉強し始めたのですが、難しすぎる...。

style.scss

いくつかアイコンを使ったのでpublic/index.html<head>内に以下を追加しFont Awesomeを読み込みます。

<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>

動作確認

準備が整ったので動作確認をしてみます。動作確認を行う場合はプロキシを自分で実行する必要があります。いくつか方法がありますが、Dockerが一番お手軽かなと思います。パソコンにDockerをインストールした後、以下のコマンドでプロキシを実行できます。

docker run --name tor -p 9050:9050 -d dperson/torproxy

ログを確認し、Bootstrapped 100% (done): Doneと出力されるまで待ちます。

docker logs tor

プロキシが起動したらアプリをビルドします。ビルドが終わるとプロジェクトのルートディレクトリにdistが生成されます。

npm run build

最後にサーバーを起動します。

node server/index.js

以下のように出力されれば正常に起動しています。

Server started at port 3000
Connected to LND

サーバーが起動したらhttp://localhost:3000を開きます。うまくいけばこんな感じに動くと思います。

今回はJoule Extensionを利用して支払いをしてみました。Jouleはローカル、またはリモートで稼働しているLNDノードを使って、ブラウザ上で支払いができる拡張機能です。Umbrelでも使うことができます。

プロキシは以下のコマンドで停止できます。

docker stop tor

デプロイ

せっかくなので今回もHerokuにデプロイしたいと思います。
最初にProcfileを作成します。

touch Procfile && echo "web: node ./server/index.js" > Procfile

以下のコマンドでアプリを作成します。

heroku create

Node.jsのbuildpackを追加します。

heroku buildpacks:add heroku/nodejs

今回はアプリでSOCKS5プロキシを使用するので、Herokuアプリでプロキシを実行できるこちらのbuildpackを使用します。必要に応じてTOR_CONTROL_PASSなど環境変数を設定してください。

heroku buildpacks:add https://github.com/iamashks/heroku-buildpack-tor-proxy.git

次にアプリで使用する環境変数を設定します。.envファイルに設定した値をそれぞれ設定します。

heroku config:set HS_HOST="yul4czkfj47.......2szwxqad.onion" LND_MACAROON="AgFDbG9kA........I9gxavn4cUat" LND_CERT="AgEFbG6kAagDFhCaYP........0FARS7tLS0Fg=="

設定できたらデプロイします。

git add . && git commit -m "first commit" && git push heroku master

しばらくしたあとに以下の出力があればデプロイできています。

https://xxx-xxx-xxx.herokuapp.com/ deployed to Heroku

アプリのURLにアクセスして問題なく動けば成功です。

IFTTTとIoTデバイスを使って遊ぶ

最近Pollofeedというライトニング払いでなぜか電球を光らせることができる(昔はニワトリに餌をあげれたらしいです)Lappを知りました。人気のLappらしいので、ちょっと真似してみたいと思います。

今回は、買ってから一回も使ってないプラズマボールを使って、ライトニング払いでこいつを光らせたいと思います。問題はどうやってこいつの電源を制御するかですが、色々調べていくと、スマートプラグなる接続した家電をIoT化する機器を発見しました。
この記事によると、IFTTTというアプリを使えば、異なるサービス間でも簡単に連携ができるようになるっぽいので、IFTTTを使ってトリガーが起こる条件をインボイスが決済された時に設定し、アクションをスマートプラグをオンにすることで、即席Pollofeedもどきを実現したいと思います。

まず、どのようにしてインボイスの決済をトリガーに設定するかですが、今回はWebhooksというものを使って実現したいと思います。
Webhooksは特定のイベントを検知した時に、別のアプリケーションにHTTPリクエストを飛ばして通知を送ることができるので、今回はインボイスへの支払いがあったタイミングでLappからIFTTTで発行したURLにリクエストを飛ばし、それをトリガーとしてアクションを実行させます。

アプリを開いたらアプレット作成画面に移動し、追加する”を選択し、検索欄に”webhooks”と入力します。webhooksの設定画面が出てくるので、”Receive a web request”を選択し、Event Nameを設定します。今回は”invoice_settled”としました。入力したら”続ける”を押してください。
トリガーの設定は以上です。

次にアクションを設定していきます。今回はこちらのSwitchBot製のスマートプラグを使用します。Then That”の”追加する”を選択し”Switchbot”と検索します。今回はプラグの制御を行うので”Turn Plug on”を選択します。次の画面では制御できるデバイスの一覧が表示されるので、目的のデバイスを選択して”続ける”を押してください。

アプレットの作成が終わったので、WebhooksのURLを確認します。ホーム画面へ移動し、作ったアプレットを選択します。Webhooksのアイコンをタッチし、”Documentation”にいくと発行されたURLが表示されます。

URLが確認できたので、インボイスが支払われたタイミングでリクエストを飛ばすようにします。lnd-rest.jsの以下の部分にコードを追加しました。これで一応動くはずです。


  ws.on("message", async (message) => {
    const msg = JSON.parse(message);
    if (msg.error || !msg.result.settled) return;
    io.emit("invoice_settled", { request: msg.result.payment_request });
    // 追加
    await got(
      `https://maker.ifttt.com/trigger/invoice_settled/with/key/自分のkey`
    );
  });

あとはLappに動画を埋め込めば終了です。ライブ配信サービス(今回はYouTube Live)をセットアップして埋め込みコードをLappに追加しました。ちょっと動かしてみます。


光りましたwww

というわけで今回もこんな感じでライトニングアプリを作ってみました。
ノードを建ててると、こうやって好きなだけ遊べるからいいですね笑
IFTTTを活用すれば、簡単にライトニングで出来ることの幅も広がりそうです。

お疲れ様でした!

Remaining : 0 characters / 0 images
100

Sign up / Continue after login

Related stories

Writer

Share

Popular stories

自前ノードを使って簡単なライトニングアプリを作ってみる【前編】

240

チャネルバックアップファイルを自動でコピーしてみる

78

チャネルバックアップファイルを自動でクラウドに保存してみる

59