zoukankan      html  css  js  c++  java
  • metamask源码学习-ui/index.js

    The UI-即上图左下角metamask-ui部分,即其图形化界面

    The MetaMask UI is essentially just a website that can be configured by passing it the API and state subscriptions from above. Anyone could make a UI that consumes these, effectively reskinning MetaMask.

    MetaMask UI本质上只是一个网站,可以通过从上面传递API和状态订阅来配置它。任何人都可以创建一个使用这些的UI,有效地重新设计MetaMask

    You can see this in action in our file ui/index.js. There you can see an argument being passed in named accountManager, which is essentially a MetaMask controller (forgive its really outdated parameter name!). With access to that object, the UI is able to initialize a whole React/Redux app that relies on this API for its account/blockchain-related/persistent states.

    你可以从文件ui/index.js中看见它的实现。在这里,您可以看到一个参数在accountManager中传递,accountManager本质上是一个MetaMask控制器(该参数名称已经过时!)通过对该对象的访问,UI能够初始化整个依赖于该API实现其帐户/区块链相关/持久状态的React/Redux应用程序

    metamask-extension/ui/index.js

    const render = require('react-dom').render
    const h = require('react-hyperscript')
    const Root = require('./app/root')
    const actions = require('./app/actions')
    const configureStore = require('./app/store')
    const txHelper = require('./lib/tx-helper')
    const { fetchLocale } = require('./i18n-helper')
    const log = require('loglevel')
    
    module.exports = launchMetamaskUi
    
    log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn')
    
    function launchMetamaskUi (opts, cb) {
      var accountManager = opts.accountManager//accountManager就是一个metamask控制器,所以metamask-controller.js中的函数其都能调用,UI一般就调用getApi ()和getState()两个函数
      actions._setBackgroundConnection(accountManager)//设置后台的连接信息
      // check if we are unlocked first
      accountManager.getState(function (err, metamaskState) {//返回一个javascript对象,表示当前的MetaMask状态
        if (err) return cb(err)
        startApp(metamaskState, accountManager, opts) 
          .then((store) => {
            cb(null, store)
          })
      })
    }
    
    //打开APP async function startApp (metamaskState, accountManager, opts) { // parse opts if (!metamaskState.featureFlags) metamaskState.featureFlags = {} const currentLocaleMessages = metamaskState.currentLocale ? await fetchLocale(metamaskState.currentLocale)//得到`./_locales/${metamaskState.currentLocale}/messages.json`文件,因为选择的语言不同 : {} const enLocaleMessages = await fetchLocale('en')//这个选择的是英语 const store = configureStore({//配置metamask环境信息,如中间件等 // metamaskState represents the cross-tab state metamask: metamaskState, // appState represents the current tab's popup state appState: {}, localeMessages: { current: currentLocaleMessages, en: enLocaleMessages, }, // Which blockchain we are using: networkVersion: opts.networkVersion, }) // if unconfirmed txs, start on txConf page
    //得到时间由小到大排序的所有信息 const unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.unapprovedPersonalMsgs, metamaskState.unapprovedTypedMessages, metamaskState.network) const numberOfUnapprivedTx = unapprovedTxsAll.length if (numberOfUnapprivedTx > 0) { store.dispatch(actions.showConfTxPage({ id: unapprovedTxsAll[numberOfUnapprivedTx - 1].id,//配置actions中showConfTxPage的值,tx里的详细信息可以看本博客metamask源码学习-background.js,其的代码注释中有写,如id... })) } accountManager.on('update', function (metamaskState) {//如果metamaskState由更新时触发 store.dispatch(actions.updateMetamaskState(metamaskState)) }) // global metamask api - used by tooling global.metamask = { updateCurrentLocale: (code) => { store.dispatch(actions.updateCurrentLocale(code)) }, setProviderType: (type) => { store.dispatch(actions.setProviderType(type)) }, } // start app,使用react框架来启动该metamask app render( h(Root, { // inject initial state store: store,//这里的内容就是上面进行相应设置后的状态信息,这个store有的详细内容的解释看本博客metamask源码学习-background.js,其的代码注释中有写本博客metamask源码学习-background.js,其的代码注释中有写
    } ), opts.container) return store }

    metamask-extension/app/scripts/metamask-controller.js

    //=============================================================================
    // EXPOSED TO THE UI SUBSYSTEM
    //=============================================================================
    
      /**
       * The metamask-state of the various controllers是得到多种控制器的状态, made available to the UI
       *
       * @returns {Object} status
       */
      getState () {
        const wallet = this.configManager.getWallet()
        const vault = this.keyringController.store.getState().vault
        const isInitialized = (!!wallet || !!vault)//就是只要两者walletvault中有一个有值,那么就说明初始化过了
    
        return {
          ...{ isInitialized },
          ...this.memStore.getFlatState(),
          ...this.configManager.getConfig(),
          ...{
            lostAccounts: this.configManager.getLostAccounts(),
            seedWords: this.configManager.getSeedWords(),
            forgottenPassword: this.configManager.getPasswordForgotten(),
          },
        }
      }
     !!()。
    
    比如:a默认是undefined,!a是true,!!a则是false,所以b的值是false,而不再是undefined。这样写可以方便后续判断使用。
    
    所以,!!(a)的作用是将a强制转换为布尔型(boolean)。

    metamask-extension/ui/i18n-helper.js

    async function fetchLocale (localeName) {//得到`./_locales/${metamaskState.currentLocale}/messages.json`文件
      try {
        const response = await fetch(`./_locales/${localeName}/messages.json`)
        return await response.json()
      } catch (error) {
        log.error(`failed to fetch ${localeName} locale because of ${error}`)
        return {}
      }
    }

    metamask-extension/ui/app/util.js

    function valuesFor (obj) {//通过keys()得到obj对象中的键值,因为这里面的键值并不是简单的1,2;然后再根据获得的键值去得到obj中对应的值,并再组合起来成新的obj对象,即map()
      if (!obj) return []
      return Object.keys(obj)
        .map(function (key) { return obj[key] })
    }

    举例:

    var obj = {'a':'123','b':'345'};
    console.log(Object.keys(obj));  //['a','b']

    metamask-extension/ui/lib/tx-helper.js

    const valuesFor = require('../app/util').valuesFor
    const log = require('loglevel')
    
    module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, typedMessages, network) {
      log.debug('tx-helper called with params:')
      log.debug({ unapprovedTxs, unapprovedMsgs, personalMsgs, typedMessages, network })
      
    //就是network不为0时,那么就得到unapprovedTxs中满足metamaskNetworkId === network条件的所有没被赞同的Txs;如果为0,则得到所有没被赞同的Txs const txValues = network ? valuesFor(unapprovedTxs).filter(txMeta => txMeta.metamaskNetworkId === network) : valuesFor(unapprovedTxs) log.debug(`tx helper found ${txValues.length} unapproved txs`) const msgValues = valuesFor(unapprovedMsgs)//得到没有签名的信息 log.debug(`tx helper found ${msgValues.length} unsigned messages`) let allValues = txValues.concat(msgValues) const personalValues = valuesFor(personalMsgs)//得到没有签名的个人信息 log.debug(`tx helper found ${personalValues.length} unsigned personal messages`) allValues = allValues.concat(personalValues) const typedValues = valuesFor(typedMessages)//得到没有签名的typed信息 log.debug(`tx helper found ${typedValues.length} unsigned typed messages`) allValues = allValues.concat(typedValues) //并全部串联起来放在allValues中
    allValues = allValues.sort((a, b) => {//一个个去对比,按照每个信息的时间由小到大去排序,如果想要有大到小,就写成a.time < b.time return a.time > b.time }) return allValues }
  • 相关阅读:
    初识《构建之法》
    实验十四 课程学习总结-韩艳艳(201671030109)
    201671030109 韩艳艳 《英文文本统计分析》结对项目报告
    201671030109 词频统计软件项目报告
    201671030109 韩艳艳 实验三作业互评与改进报告
    ----初读《构建之法》的疑虑
    201671030111 李蓉 实验十四 团队项目评审&课程学习总结
    201671030111李蓉《英文文本统计分析》结对项目报告
    201671030111 词频统计软件项目报告
    201671030111李蓉 实验三作业互评与改进报告
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/9714562.html
Copyright © 2011-2022 走看看