简体   繁体   English

如何在 Flutter 中实现 dapp 浏览器

[英]How do I implement a dapp browser in flutter

I have tired to months to inject window.ethereum in flutter webview but to no avail, i found out i can only inject javascript on page load end, but once the page have loaded finished, window.ethereum would not be available to the dapp, is there any way i can inject window.ethereum on page start...我已经厌倦了几个月在flutter webview中注入window.ethereum但无济于事,我发现我只能在页面加载结束时注入javascript,但是一旦页面加载完成,dapp将无法使用window.ethereum,有什么办法可以在页面开始时注入window.ethereum ...

what i have tried我试过的

WebView(
                navigationDelegate: (action) {
                  if (action.isForMainFrame) {
                    return NavigationDecision.navigate;
                  }
                  return NavigationDecision.prevent;
                },
                onProgress: (precent) {
                  setState(() {
                    browserLoadingPercent = precent / 100;
                  });
                },
                onWebViewCreated: (controller) async {
                  _controller = controller;
                },
                initialUrl: widget.data ?? dappBrowserInitialUrl,
                debuggingEnabled: true,
                onPageStarted: (url) async {
                  dappBrowser.text = url;
                  if (urlLoaded == '') {
                    urlLoaded = url;
                  }
                },
                onPageFinished: (url) async {
                  return;
                  try {
                    if (urlLoaded == '') {
                      return;
                    } else {
                      urlLoaded = '';
                    }
                    await _controller.runJavascript(widget.sweetAlert);
                    await _controller.runJavascript(widget.web3);
                    await _controller.runJavascript(widget.provider);

                    var favicon =
                        await _controller.runJavascriptReturningResult('''
                        var getFavicon = function(){
                            var favicon = undefined;
                            var nodeList = document.getElementsByTagName("link");
                            for (var i = 0; i < nodeList.length; i++)
                            {
                                if((nodeList[i].getAttribute("rel") == "icon")||(nodeList[i].getAttribute("rel") == "shortcut icon"))
                                {
                                    favicon = nodeList[i].getAttribute("href");

                                }
                            }

                            return new URL(favicon, document.baseURI).href;        
                        }

                        getFavicon();
                        ''');

                    favicon = favicon.split('"').join('').split("'").join('');
                    await showDialog(
                      barrierDismissible: false,
                      context: context,
                      builder: (_) {
                        return SimpleDialog(
                          title: Column(
                            children: [
                              if (true)
                                Container(
                                  height: 100.0,
                                  width: 100.0,
                                  padding: const EdgeInsets.only(bottom: 8.0),
                                  child: Image.network(favicon),
                                ),
                              Text(url),
                            ],
                          ),
                          contentPadding:
                              const EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 16.0),
                          children: [
                            if (url.isNotEmpty)
                              Padding(
                                padding: const EdgeInsets.only(bottom: 8.0),
                                child: Text('Connection to ${url}'),
                              ),
                            Row(
                              children: [
                                Expanded(
                                  child: TextButton(
                                    style: TextButton.styleFrom(
                                      primary: Colors.white,
                                      backgroundColor: Theme.of(context)
                                          .colorScheme
                                          .secondary,
                                    ),
                                    onPressed: () async {
                                      showDialog(
                                          barrierDismissible: false,
                                          context: context,
                                          builder: (context) {
                                            var ethEnabledBlockChain =
                                                <Widget>[];
                                            for (String i
                                                in getBlockChains().keys) {
                                              ethEnabledBlockChain.add(InkWell(
                                                onTap: () async {
                                                  var count = 0;
                                                  var seedPhrase =
                                                      (await SharedPreferences
                                                              .getInstance())
                                                          .getString(
                                                              'mmemomic');
                                                  await _controller
                                                      .runJavascript('''
                                                        window.web3 = new Web3(
                                                                new HDWalletProvider({
                                                                  mnemonic: {
                                                                    phrase:
                                                                      "${seedPhrase}",
                                                                  },
                                                                  providerOrUrl: "${getBlockChains()[i]['rpc']}",
                                                                  chainId: ${getBlockChains()[i]['chainId']},
                                                                })
                                                              );
                                                        ''');
                                                  Navigator.popUntil(context,
                                                      (route) {
                                                    return count++ == 2;
                                                  });
                                                },
                                                child: buildRow(
                                                    getBlockChains()[i]
                                                                ['image'] !=
                                                            null
                                                        ? getBlockChains()[i]
                                                            ['image']
                                                        : 'assets/ethereum_logo.png',
                                                    i),
                                              ));
                                            }
                                            return Dialog(
                                                shape: RoundedRectangleBorder(
                                                    borderRadius:
                                                        BorderRadius.circular(
                                                            40)),
                                                elevation: 16,
                                                child: Container(
                                                  child: ListView(
                                                    shrinkWrap: true,
                                                    children: <Widget>[
                                                      SizedBox(height: 20),
                                                      Center(
                                                          child: Text(
                                                              'Select BlockChains')),
                                                      SizedBox(height: 20),
                                                    ]..addAll(
                                                        ethEnabledBlockChain),
                                                  ),
                                                ));
                                          });
                                    },
                                    child: Text('APPROVE'),
                                  ),
                                ),
                                const SizedBox(width: 16.0),
                                Expanded(
                                  child: TextButton(
                                    style: TextButton.styleFrom(
                                      primary: Colors.white,
                                      backgroundColor: Theme.of(context)
                                          .colorScheme
                                          .secondary,
                                    ),
                                    onPressed: () {
                                      Navigator.pop(context);
                                    },
                                    child: Text('REJECT'),
                                  ),
                                ),
                              ],
                            ),
                          ],
                        );
                      },
                    );

                    // await _controller.runJavascript(
                    //     'document.documentElement.innerHTML = document.documentElement.innerHTML');
                    // await _controller.runJavascript(widget.reEnableJavascript);
                    // await _controller.runJavascript('''
                    // var load_event = document.createEvent("HTMLEvents");
                    // load_event.initEvent("DOMContentLoaded", true, true);
                    // window.document.dispatchEvent(load_event);
                    // ''');
                    // await _controller.runJavascript('''
                    //   var load_event = document.createEvent("HTMLEvents");
                    //   load_event.initEvent("load", true, true);
                    //   window.document.dispatchEvent(load_event);
                    //   ''');

                    await _controller.runJavascript('''
                    (async function () {
                            const account = (await web3.eth.getAccounts())[0];
                            console.log('web3 dapp browser: ' + account);
                    })();''');

                    print('end of function');
                  } catch (e) {
                    print(e);
                  }
                },
                javascriptMode: JavascriptMode.unrestricted,
                gestureNavigationEnabled: true,
                gestureRecognizers: gestureRecognizers,
              )```

Embedded dApp browser is an antipattern in Web3 design for mobile apps.嵌入式 dApp 浏览器是移动应用程序 Web3 设计中的一种反模式。

Instead, you should use WalletConnect protocol if you want to have Ethereum transaction capabilities on your mobile apps .相反,如果您想在您的移动应用程序上拥有以太坊交易功能,您应该使用 WalletConnect 协议

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM