C#（Windowsアプリ）とJavaScriptでSymbolアカウント作成

2020年の大晦日時点では、 .NET Framework（.NET Core）用のSDKはありません。
なのでC#（Windowsアプリ）からJavaScriptのSDKを使ってSymbolアカウントを作ってみます。

<h2>準備</h2>
1. WebView2 ランタイム、または非安定型 Microsoft Edge (Chromium) カナリア チャネルのどちらかをインストールします。
私はWebView2 ランタイムをインストールしました。
<a href="https://developer.microsoft.com/ja-jp/microsoft-edge/webview2/">WebView2 Runtime</a>
<a href="https://www.microsoftedgeinsider.com/ja-jp/download">非安定型 Microsoft Edge (Chromium) カナリア チャネル</a>

2. VisualStudioを起動し、Windowsフォームアプリケーションのプロジェクトを作成します。
（試していませんが、WPFでも出来るはずです。多分）

3. NuGetパッケージの管理から『Microsoft.Web.WebView2』をインストールします。

4. NuGetパッケージの管理から『System.Text.Json』をインストールします。
※JavaScriptからの戻り値をJSON形式で受け取るために『System.Text.Json』を使用します。

<h2>HTML作成</h2>
事前に、以下のようなHTMLファイルを作成しておきます。
これをWebView2で読み込んで、JavaScriptを実行します。
<pre>
<code>
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;C#（Windowsアプリ）とJavaScriptでSymbolアカウント作成&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;C#（Windowsアプリ）とJavaScriptでSymbolアカウント作成&lt;/h1&gt;
    &lt;script src="https://xembook.github.io/nem2-browserify/symbol-sdk-0.22.2.js"&gt;&lt;/script&gt;
    &lt;script language="javascript" type="text/javascript"&gt;
        function createAccount() {
            //インスタンス生成
            var nem = require("/node_modules/symbol-sdk");

            //アカウント作成
            var account = nem.Account.generateNewAccount(nem.NetworkType.TEST_NET);

            //秘密鍵とアドレスをJSONにして返す
            var obj = {
                privateKey: account.privateKey,
                address: account.address.plain()
            };

            return window.JSON.stringify(obj);
        }
    </script>
&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
symbol-sdkをbrowserify化してくださっている方がいらっしゃるので、そちらを使わせてもらっています。
&lt;script src="https://xembook.github.io/nem2-browserify/symbol-sdk-0.22.2.js"&gt;&lt;/script>
<br>
createAccount関数でやっていることはコメントに書いてある通りです。
これだけでアカウントを作れてしまうなんて簡単ですね。

<h2>Windowsアプリ作成</h2>
画面はとりあえずこんな感じで。
![画面サンプル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/992966/c8c3d543-58f1-a106-6a97-83e6ffd2b44f.png)

JavaScriptからの戻り値をJSONで受け取るためにSystem.Text.Jsonを宣言しておきます。
<pre>
<code>
using System.Text.Json;
</code>
</pre>
Form1_Loadイベントで、上記で作成したHTMLを読み込みます。
（デザイナのプロパティから設定することも出来ます）
<pre>
<code>
private void Form1_Load(object sender, EventArgs e)
{
    //HTML読み込み
    webView21.Source = new Uri("file:///C:/WinFormSymbol.html");
}
</code>
</pre>
button1_Clickイベントで、Symbolアカウントを作成するJavaScriptの関数を実行し、秘密鍵とアドレスを受け取ります。
<pre>
<code>
private async void button1_Click(object sender, EventArgs e)
{
    //Symbolアカウント作成
    string result = await webView21.ExecuteScriptAsync("createAccount()");

    //先頭と最後の"を除去
    result = result.Trim('"');
    //\"を"に変換
    result = result.Replace("\\\"", "\"");

    //デシリアライズ
    var json = JsonSerializer.Deserialize<Dictionary<string, string>>(result);

    lblPrivateKey.Text = json["privateKey"];
    lblAddress.Text = json["address"];
}
</code>
</pre>
webView21.ExecuteScriptAsync("createAccount()")で、HTMLファイルで記述したJavaScriptのcreateAccount関数を実行しています。
<br>
戻り値に余計なものが付いてきていたので除去したり変換したり。
その後、デシリアライズしてラベルにセットして完了です。
<br>
まとめたものです。
<pre>
<code>
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        //HTML読み込み
        webView21.Source = new Uri("file:///C:/WinFormSymbol.html");
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        //Symbolアカウント作成
        string result = await webView21.ExecuteScriptAsync("createAccount()");

        //先頭と最後の"を除去
        result = result.Trim('"');
        //\"を"に変換
        result = result.Replace("\\\"", "\"");

        //デシリアライズ
        var json = JsonSerializer.Deserialize<Dictionary<string, string>>(result);

        lblPrivateKey.Text = json["privateKey"];
        lblAddress.Text = json["address"];
    }
}
</code>
</pre>

いずれは.NET Framework（.NET Core）用のSDKを誰かが作ってくれると思いますが、WindowsアプリでSymbolを使うならこういうやり方もあります、ということで。
それでは良いお年を。

<h2>参考にさせていただいたサイト</h2>
<a href="https://qiita.com/bootarouapp/items/f05f8072a7af90188055">Nem Symbol-sdk(testnet)　を使ったアカウントの作り方</a>
<a href="https://qiita.com/nem_takanobu/items/e2b1f0aafe7a2df0fe1b">Symbol from NEM のテストネットで送金を体験する（2020年12月時点）</a>
<a href="https://qiita.com/NagaJun/items/baf00494e0841a5e767e">WebView2 C#とJavaScriptの連携</a>
<a href="https://docs.microsoft.com/ja-jp/microsoft-edge/webview2/gettingstarted/winforms">Windows フォームでの WebView2 の概要</a>