拡張機能サポート機能loadExtension()を使ったが、既存のウォレット情報が表示されず、APIも使えなかった。

ブツ

インストール&実行

NAME='Electron.MyLog.20220918093541'
git clone https://github.com/ytyaru/$NAME
cd $NAME
npm install
npm start

情報源

やったこと

  1. Electron Chrome拡張機能サポートを読む
  2. Chromium拡張機能ディレクトリを調べる
  3. main.jsに実装する

1. Electron Chrome拡張機能サポートを読む

const { session } = require('electron')

session.loadExtension('path/to/unpacked/extension').then(({ id }) => {
  // ...
})

上記のように拡張機能のパスをセットする必要があるようだ。

また、すべての拡張機能をサポートしているわけではないとも明記されていた。mpurseがサポートされるかどうかは試してみないとわからない。

2. Chromium拡張機能ディレクトリを調べる

必要なパスの書式は次の通り。

  • {Chromium設定}/{プロファイル}/Extensions/{ExtId}/{Version}
パス
Windows C:\Users\{username}\AppData\Local\Google\Chrome\User Data\{プロファイル}/Extensions/{ExtId}
Mac Users/{username}/library/Application Support/Google/Chrome/{プロファイル}/Extensions/{ExtId}
Linux ~/.config/chromium/{プロファイル}/Extensions/{ExtId}
表記 意味
~ /home/{username}
{username} OSのユーザ名
{プロファイル} DefaultまたはProfile [1-9]+
{ExtId} 拡張機能のID(32字の英字)

mpurseのIDを調べる

結論からいうと/Extensions/{ExtId}/{Version}/manifest.json内のnameMpurse{ExtId}がそれである

{Chromium設定}/{プロファイル}/Extensions/{ExtId}のうちExtensionsまで特定したら、次はmpurseのID{ExtId}を調べる。

  • Extensions配下にはそのプロファイルにインストールされた拡張機能の数だけディレクトリがある
  • そのディレクトリ名は32字の英字である
  • {Version}はその拡張機能のバージョン値である
  • 拡張機能ごとにひとつmanifest.jsonファイルがある

3. main.jsに実装する

  • src/js/main.js
    • /home/pi/.config/chromium/Profile 3/Extensions/ljkohnccmlcpleonoiabgfggnhpkihaa/0.5.1_0

3-1. 失敗1

const { session } = require('electron')

session.loadExtension('path/to/unpacked/extension').then(({ id }) => {
  // ...
})

公式サイトに書いてあった通りsession.loadExtension()すると以下エラーになった。

(node:8908) UnhandledPromiseRejectionWarning: TypeError: session.loadExtension is not a function

3-2. 失敗2

ググって探した所session.defaultSession.loadExtension()が正しいようだ。公式が嘘を書くのやめてほしい。これ何度目だ。

パスの直下にmanifest.jsonがないと以下のようなエラーになる。ちゃんと{ExtId}/{Version}もいれてパス指定すること。公式にはpath/to/unpacked/extensionとあり、それじゃわからねーよと言いたい。

(node:8992) UnhandledPromiseRejectionWarning: Error: Loading extension at /home/pi/.config/chromium/Default/Extensions failed with: マニフェスト ファイルが見つからないか読み取れません

3-3. 起動したがウォレット表示されずAPIも使えない

CharlieAIO/extensions.jsを参考にした。以下コード抜粋。

function popupMpurse() {
    const ID = 'ljkohnccmlcpleonoiabgfggnhpkihaa'
    const w = new BrowserWindow({
        title: 'Mpurse',
        width: 400,
        height: 640,
        type: 'popup',
    });
    w.loadURL(`chrome-extension://${ID}/index.html`);
}
app.whenReady().then(async() => {
    const json = await session.defaultSession.loadExtension(`/home/pi/.config/chromium/Profile 3/Extensions/ljkohnccmlcpleonoiabgfggnhpkihaa/0.5.1_0`);
    console.log('session.loadExtension:', json)
    createWindow()
    popupMpurse()
    app.on('activate', function () {
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})

これで起動時mpurseが表示される。ただ、新規ウォレット作成する画面になってしまう。

あれ、すでにウォレットは作成済みのはずなんだけど……。

Electronで表示した時

mpurse-electron.png

ブラウザで表示すると以下のようになるのになる。↓と同じようになることを期待していたのに。何がダメなの?

拡張機能ボタンを押した時

mpurse-browser.png

chrome-extension://ljkohnccmlcpleonoiabgfggnhpkihaa/index.htmlをブラウザのURL欄に入力した時

mpurse-browser-2.png

たぶんmpurseはローカルのどこかにウォレット情報をファイル保存している。その読み取りがElectronだとできなくて新規作成画面になってしまうのだろう。

でも、どこにウォレット情報があるかわからない。.../{プロファイル}/Local Extension Settings/{ExtId}/配下にはログっぽいものしかなかったし。

既存のウォレットを取り込むにはどうしたらいいのか。mpurseのインポート機能は新しくウォレットを作ることになってしまうっぽいので違う。

そうでなく、既存のウォレットを使いたいだけ。そもそも、なぜ使えないのか謎。Electronでは動作しないのかな? それとも、単にウォレットデータが参照またはコピーされていないだけ? わからん。

mpurse APIも使えなかった。

mpurse-api-undefined.png

一応、拡張機能をロードしたあとにwindow.mpurse.updateEmitter.removeAllListeners()...をやったが、やはりダメ。

...
const json = await session.defaultSession.loadExtension(`/home/pi/.config/chromium/Profile 3/Extensions/ljkohnccmlcpleonoiabgfggnhpkihaa/0.5.1_0`, {allowFileAccess:true});
try {
    window.mpurse.updateEmitter.removeAllListeners()
      .on('stateChanged', isUnlocked => console.log(isUnlocked))
      .on('addressChanged', address => console.log(address));
} catch(e) { console.debug(e) }
createWindow()
popupMpurse()
...

結論

Electronではmpurseが使えない。

  • mpurseの既存ウォレットが使えない
  • mpurse APIが使えない

もしかしたら新しいウォレットを作れば使えるのかもしれない。でも、私は既存のウォレットが使いたかった。それにAPIも使えないから投げモナボタンが機能しない。