2017年5月10日水曜日

XRP用のウォレットを自作する ー 残高照会

今回は残高を確認する機能を実装していきます。

1.オンライン用のRippleAPIインスタンスを作る


残高を確認するにはリップルのサーバーに接続する必要があるので、オンライン用のRippleAPIインスタンスを作ります。

const apiOnline = new ripple.RippleAPI({ server: 'wss://s1.ripple.com' });

サーバーに接続するには connect() メソッドを使います。オンラインでRippleAPIを使う場合、接続が失敗したときの処理や接続を切断する処理も必要になります。幸いなことにRippleの公式サイトにテンプレートがあるので、それを使わせてもらうことにします。

const apiOnline = new ripple.RippleAPI({ server: 'wss://s1.ripple.com' });
apiOnline.on('error', (errorCode, errorMessage) => {
  console.log(errorCode + ': ' + errorMessage);
});
apiOnline.on('connected', () => {
  console.log('connected');
});
apiOnline.on('disconnected', (code) => {
  // code - [close code](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) sent by the server
  // will be 1000 if this was normal closure
  console.log('disconnected, code:', code);
});
apiOnline.connect().then(() => {

  // ここにコードを書いていきます

}).then(() => {
  return apiOnline.disconnect();
}).catch(console.error);


2.getBalances() メソッドによる残高データの取得


残高データを取得するには getBalances() メソッドを使います。このgetBalances()メソッドに残高を調べたいアドレスを文字列として渡すと、オブジェクトを要素として持つ配列を返します。

呼び出し
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
return apiOnline.getBalances(address).then(balances =>
  {/* ... */});


返り値
[
  {
    "value": "922.913243",
    "currency": "XRP"
  },
  {
    "value": "0",
    "currency": "ASP",
    "counterparty": "r3vi7mWxru9rJCxETCyA1CHvzL96eZWx5z"
  },

  .
  .
  .
  .

  {
    "value": "0",
    "currency": "015841551A748AD2C1F76FF6ECB0CCCD00000000",
    "counterparty": "rs9M85karFkCRjvc6KMWn8Coigm9cbcgcx"
  },
  {
    "value": "0",
    "currency": "USD",
    "counterparty": "rEhDDUUNxpXgEHVJtC2cjXAgyx5VCFxdMF"
  }
]


3.残高データを取得する関数を実装する


それでは最初に、「残高を確認する」ボタン、アドレス入力欄、確認実行ボタン、そして結果を表示する場所を<body>~</body>に追加します。

CSSは 4.今回のまとめ のコードを参照してください。

<form>
  <input type="button" class="button" value="残高を確認する">
  <div id="address_text">Address: <input type="text" class="text" id="address"><input type="button" value="確認する" onClick="checkBalances()"></div>
</form>
<div id="show_balances"></div>


ブラウザで見るとこのように表示されます。



では、残高データを取得する関数を書いていきましょう。

流れとしては、アドレス入力欄の値を取得し、その値を getBalances()メソッドに渡します。そして返り値の配列からオブジェクトを一つずつ取り出して、表形式にまとめていきます。

function checkBalances() {
  
  .
  .    // テンプレート
  .
 
  const address = document.getElementById('address').value;
  return apiOnline.getBalances(address).then((balances) => {
    let resultString = "";
    for(i=0; i<balances.length; i++) {
      const value = balances[i].value;
      const currency = balances[i].currency
      const counterparty = balances[i].counterparty;
      resultString += "<table>" +
        "<tr><th>currency</th><td>" + currency + "</td></tr>" +
        "<tr><th>value</th><td>" + value + "</td></tr>;
      if(counterparty) { 
        resultString += "<tr><th>counterparty</th><td>" + counterparty + "</td></tr>"
      };
      resultString += "</table>";

    };

    document.getElementById('show_balances').innerHTML = resultString;
  
  .
  .  // テンプレート
  .

}


試しに東京JPYのアドレスを入力してみると以下のように結果が表示されました。



4.今回のまとめ


では今回作った残高照会のコードを、前回の新規ウォレット作成のコードに追加してみましょう。CSSも追加しています。

[wallet.html]
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>XRP Wallet</title>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.js"></script>
    <script src="ripple-0.17.4.js"></script>

    <script>

        const apiOffline = new ripple.RippleAPI();

    // 新規ウォレット作成
        function createNewWallet() {
            const addressAndSecret = apiOffline.generateAddress();
            const address = addressAndSecret.address;
            const secret = addressAndSecret.secret;

            document.getElementById("new_wallet").innerHTML =
            "<ul><li>下に表示されているアドレスとシークレットキーを紙に書くなどして保存してください</li>" +
            "<li>特にシークレットキーの保管には十分注意してください。</li>" +
            "<li>画像にしたりやテキストファイルにコピーして保存する場合はUSBメモリーなどの外部メモリーで保存するなどして、インターネットから切り離された状態で保管してください。</li>" +
            "<li>シークレットキーを失くすと資金を引き出すことができなくなります。</li>" +
            "<li>シークレットキーを他人に知られると勝手に資金を引き出される危険があります。</li></ul>" +
            "<table><tr><th>Address</th><td>" +
            address +
            "</td></tr><tr><th>Secret</th><td>" +
            secret +
            "</td></tr></table>";
        };

        // 残高照会
        function checkBalances() {
            const apiOnline = new ripple.RippleAPI({ server: 'wss://s1.ripple.com' });
            apiOnline.on('error', (errorCode, errorMessage) => {
                console.log(errorCode + ': ' + errorMessage);
            });
            apiOnline.on('connected', () => {
                console.log('connected');
            });
            apiOnline.on('disconnected', (code) => {
                console.log('disconnected, code:', code);
            });
            apiOnline.connect().then(() => {
                const address = document.getElementById('address').value;                
                return apiOnline.getBalances(address).then((balances) => {
                    let resultString = "";
                    for(i=0; i<balances.length; i++) {
                        const value = balances[i].value;
                        const currency = balances[i].currency;
                        const counterparty = balances[i].counterparty;
                        resultString += "<table>" +
                            "<tr><th>currency</th><td>" + currency + "</td></tr>" +
                            "<tr><th>value</th><td>" + value + "</td></tr>";
                            if(counterparty) {
                                resultString += "<tr><th>counterparty</th><td>" + counterparty + "</td></tr>";
                            };
                            resultString += "</table>";
                    };
                    document.getElementById('show_balances').innerHTML = resultString;
                }).then(() => {
                    return apiOnline.disconnect();
                }).catch(console.error);
            });
        };

        
        
    </script>

    <style type="text/css">
    #container {
        max-width: 600px;
        margin: 0 auto;
        }
    .button {
        font-size: 1.4em;
        font-weight: bold;
        padding: 10px 30px;
        width: 100%;
        margin: 40px 0px 0px 0px;
        background-color: #248;
        color: #fff;
        border-style: none;
        border-radius: 5px;
        }
    #addressText {
        margin: 20px;
        }
    .text {
        width: 300px;
        margin-right: 10px;
        } 
    table {
        margin: 10px auto;
        width: 500px;
        }
    td, th { 
        border: 1px solid black;
        padding: 5px;
       }
    table {
       border-collapse: collapse;
       }
    </style>
</head>

<body>
    <div id="container">
        <form>
            <input class="button" type="button" value="新規にウォレットを作成" onClick="createNewWallet()">    
        </form>
        <div id="new_wallet"></div>

        <form>
            <input type="button" class="button" value="残高を確認する">
            <div id="addressText">アドレス: <input type="text" class="text" id="address"><input type="button" value="確認する" onClick="checkBalances()"></div>
        </form>
        <div id="show_balances"></div>
    </div>
</body>
</html>

これで残高照会機能の実装は終わりです。次回はいよいよ送金機能を実装していきます。

0 件のコメント:

コメントを投稿