ohacのブログ

React hooks collection vol.2 (Mpurse連携)

December 26, 2020

Mpurseの情報を取得して表示と署名と送信

Mpurseの情報を表示するコンポーネントです。 Mpurseがブラウザにインストールされている必要があります。

<Mpurse />

このように書くと以下のように表示されます。

Mpurse検出中...

URLのhashの部分を変えると署名対象のテキストや送信先、額が指定できますので、 そのままツールとしても使えます。

ソースコード

import React, { useEffect, useState } from "react"

function useMpurse() {
  const [mpurse, setMpurse] = useState(null);
  const [addr, setAddr] = useState(null);
  useEffect(() => {
    if (mpurse === null) {
      const mp = window.mpurse;
      if (window.location.hash === '') {
        window.location.hash =
          'foobar,' +
          'mona1qg7msfzsd9y3kdgkuduznqc6wmcfu6ju54k0g7z,' +
          '0.05';
      }
      if (mp) {
        setMpurse(mp);
        mp.getAddress().then((addr) => {
          setAddr(addr);
        });
      } else {
        // debug code
        //setMpurse(0);
        //const testaddr = 'MCj6QFbD7Gwy64qbzKonFbF5NTcsakwiXe';
        //setAddr(testaddr);
      }
    }
  }, [mpurse]);
  return [mpurse, addr];
}

function sign(mpurse, msg) {
  if (mpurse === 0) { // for debug
    return new Promise((resolve, reject) => {
      resolve('ILa8xzQq66D2M+n8NEtpqEi3SJdrZURbpd+CCef0uDOfH9fgiTna/6kvw1JofRLexJ422RYTCK2WeFLCF5ayqTY=');
    });
  }
  return mpurse.signMessage(msg);
}

function send(mpurse, addr, value) {
  if (mpurse === 0) { // for debug
    return new Promise((resolve, reject) => {
      resolve('864d928f595e9e29d423e5ef7293c45aa6c0d409d6967f1494a7694ebaea4017');
    });
  }
  return mpurse.sendAsset(
    addr,
    'MONA', 
    value, 
    'no',
    ''
  );
}

export default function Mpurse(props) {
  const [mpurse, addr] = useMpurse();
  const [tx, setTx] = useState('');
  const [signedText, setSignedText] = useState('');
  if (addr !== null) {
    const hash = window.location.hash.substr(1);
    const vs = hash.split(',');
    const msg = vs[0];
    const toAddr = vs[1];
    const value = parseFloat(vs[2]);
    return (
      <>
        <table>
          <tbody>
            <tr>
              <th>Mpurseアドレス</th>
              <td>{addr}</td>
            </tr>
            <tr>
              <th>署名ボタン</th>
              <td><button onClick={() => {
                      sign(mpurse, msg)
                        .then((x) => setSignedText(x))
                    }
                  }>
                "{msg}"に署名する</button>
              </td>
            </tr>
            <tr>
              <th>署名済みテキスト</th>
              <td>{signedText}</td>
            </tr>
            <tr>
              <th>送信ボタン</th>
              <td><button onClick={() => {
                      send(mpurse, toAddr, value)
                        .then((x) => setTx(x))
                    }
                  }>
                {toAddr}に{value}MONA送信する</button>
              </td>
            </tr>
            <tr>
              <th>Transaction ID</th>
              <td>{tx}</td>
            </tr>
          </tbody>
        </table>
      </>
    );
  }
  return (
    <>Mpurse検出中...</>
  );
}