Native DAppsをFlutterで作ってみる(失敗した)
Native DAppsをFlutterで作ってみる(失敗した)
リソース
やること
- Native DAppsをFlutterで作りたい
- Flutter + MetaMask連携でNFTを表示する
メモ
- Flutter Webの連携方法は結構情報がある
- ネイティブ連携の場合は?
- 理想の挙動
- Wallet Connect?
- Wallet ConnectのDartライブラリはあるか?
-
JubiterWallet/wallet-connect-flutter
- ネイティブSDKをMethodChannelで呼ぶコードはやってる人がいた
-
RootSoft/walletconnect-dart-sdk: Open protocol for connecting dApps to mobile wallets with QR code scanning or deep linking.
- algorandしか対応してない。wallet connectとの連携のコードは参考になりそう
-
JubiterWallet/wallet-connect-flutter
- Wallet ConnectのDartライブラリはあるか?
- MetaMaskと連携するにはDeepLinkを使ってMetaMaskアプリを立ち上げて認証する方法が理想
- Native Dapps with Deep Linking - Applications - Ethereum Research
- DeepLink生成はここでやるっぽい。DAppのurlが必要。
- MetaMask deep link generator
- MetaMask単体のdeeplinkでは全てのtransactionに対応してない。一部connect walletを使う必要がある。
- Mobile Linking with Dapp using metamask as a signer · Issue #1695 · MetaMask/metamask-mobile
-
To answer your questions directly:
-
I don't think metamask should notify you of a complete transaction, metamask should just handle the signing of the transaction and then pass control back to the native app through deeplink, with information on transactionId. The native app would then be responsible for monitoring the transaction to verify if/when it completes.
-
Metamask needs to support signing any kind of transaction through deeplinking, doesn't seem possible right now
-
The only benefit I see to using wallet connect over metamask right now is it allows signing all transactions, it still has a pretty average UX where you need to manually navigate back to your native app and also initiating transaction signs is a bit messy where you have to manually deep link into metamask from my understanding...
-
I think the best option from UX is to write your own wallet in your native app still, unfortunately, however there is obviously security issues with this. Thoughts?
- 何はともあれとりあえずはdeeplinkを扱う準備をしてみる
- iOSで試す
-
apple-app-site-association
をdeeplinkさせるドメイン配下に設置 - entitlementを
applinks:hoge.example.com
のような感じでXcodeで設定 - テストでBlitz.jsの
public/
におけばいいとやっていたら.json
をつけてはいけないAppleの制約にやられた。そのままだとContent-Typeがoctetstremになってしまうのでだめ。とりあえずは下記で解決した。/public/.well-known
において、vercel.json
にContent-Typeを独自で設定する。
-
- iOSで試す
- ローカルでテストするためにMetaMask mobileをインストール
-
MetaMask/metamask-mobile: Mobile web browser providing access to websites that use the Ethereum blockchain
- React Native製。Web3プロダクトはJavascript中心のコミュニティなのでReact Nativeは親和性あるよな〜。
- Flutterアプリと同じ端末にMetaMaskをインストール。これでdeeplinkによる認証の流れを検証したい
-
MetaMask/metamask-mobile: Mobile web browser providing access to websites that use the Ethereum blockchain
- Flutter側からdeeplink generatorで生成したリンクを呼び出すとエラーになる
-
Safari cannot open the page because the address is invalid.
-
apps.apple.com
を開こうとしてる。つまりApp Storeにリダイレクトされてる。やはり厳しいのか...
-
- 実機で試す
- 実機でも同じ。MetaMaskを認識してくれないっぽい。
-
- OrangeWalletがFlutter+WalletConnect連携のライブラリを書いてたのを発見
- https://twitter.com/WalletConnect/status/1444587095159414785
- exampleをビルド&実機で動かしたらできた。MetaMask側との連携もOpenSeaと同様のモーダルで認証を行えそうだった。
- しかしWalletConnectの仕組みがわかってきてさらに絶望が...
- OrangeWalletが作っているexampleのWallet認証の流れ
-
-
https://example.walletconnect.org/
のページをwebviewで読み込んで、Walletのアプリを開き認証を行う。
-
-
- 成功するとwalletconnect側とsessionが確立する
-
- 自分のアプリに戻ると先ほど確立したsessionを利用できるようになっている。
-
- という感じ。つまり認証にはwebページが必要になる。
https://example.walletconnect.org/
はその認証ページの例ということでexample
とドメインに入っているようだ。てことはUIのカスタマイズは必須だしログイン画面用に自分でwebページを作らないといけないわけか。
- OrangeWalletが作っているexampleのWallet認証の流れ
- walletconnectのwebページの静的HTMLをFlutter上で表示させると外部ホスティングいらないのでは
- 変更しづらいしwalletconnectのライブラリのコードもたくさんあるのでCDNで落とすとかでも煩雑すぎる
- ネイティブアプリでMetaMask等のWalletをSignerにしてTransactionを伴うアプリを作るのは筋悪すぎるしほぼ無理。OpenSeaがViewerアプリになってるのはこういう理由からか。とはいえOpenSeaのモバイルアプリはMetaMaskをdeeplink(or UniversalLink)で開いてアドレス取得してるんだけどあれどうやるのか...。MetaMask公式Doc読んでもUniversalLinkでアプリを開けないが。
- とにかくわからんことが色々あって疲れたので一旦終わり
おなじくわからない。。
Metamaskの公式SDKが来ていた。ReactNativeならモバイルアプリでも望みの挙動ができるかも。