分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

MetaMask/metamask-inpage-provider

发布时间:2023-09-06 02:21责任编辑:彭小芳关键词:meta

https://github.com/MetaMask/metamask-inpage-provider

Used to initialize the inpage ethereum provider injected by MetaMask.

Installation

npm install metamask-inpage-provider -S

 

metamask-inpage-provider/createErrorMiddleware.js

处理JSON-RPC调用是出现的错误,并将错误记录到日志中

loglevel是JavaScript的最小轻量级日志记录,它没有控制台的缺点,替代了console.log()并且对于基于级别的日志和过滤是十分友好的,本博客loglevel-metamask

const log = require(‘loglevel‘)/** * JSON-RPC error object * * @typedef {Object} RpcError * @property {number} code - Indicates the error type that occurred * @property {Object} [data] - Contains additional information about the error * @property {string} [message] - Short description of the error *//** * Middleware configuration object * * @typedef {Object} MiddlewareConfig * @property {boolean} [override] - Use RPC_ERRORS message in place of provider message *//** * Map of standard and non-standard RPC error codes to messages */const RPC_ERRORS = { ?1: ‘An unauthorized action was attempted.‘, ?2: ‘A disallowed action was attempted.‘, ?3: ‘An execution error occurred.‘, ?[-32600]: ‘The JSON sent is not a valid Request object.‘, ?[-32601]: ‘The method does not exist / is not available.‘, ?[-32602]: ‘Invalid method parameter(s).‘, ?[-32603]: ‘Internal JSON-RPC error.‘, ?[-32700]: ‘Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.‘, ?internal: ‘Internal server error.‘, ?unknown: ‘Unknown JSON-RPC error.‘,}/** * Modifies a JSON-RPC error object in-place to add a human-readable message, * optionally overriding any provider-supplied message * * @param {RpcError} error - JSON-RPC error object * @param {boolean} override - Use RPC_ERRORS message in place of provider message */function sanitizeRPCError (error, override) { ?if (error.message && !override) { return error } ?const message = error.code > -31099 && error.code < -32100 ? RPC_ERRORS.internal : RPC_ERRORS[error.code]//判断错误类型并获得错误message ?error.message = message || RPC_ERRORS.unknown}/** * json-rpc-engine middleware that both logs standard and non-standard error * messages and ends middleware stack traversal if an error is encountered * * @param {MiddlewareConfig} [config={override:true}] - Middleware configuration * @returns {Function} json-rpc-engine middleware function */function createErrorMiddleware ({ override = true } = {}) { ?return (req, res, next) => { ???next(done => { ?????const { error } = res ?????if (!error) { return done() } ?????sanitizeRPCError(error) ?????log.error(`MetaMask - RPC Error: ${error.message}`, error) ?????done() ???}) ?}}module.exports = createErrorMiddleware

metamask-inpage-provider/index.js

这个库的作用有设置浏览器本地信息存储publicConfig流、构建RpcProvider双向传送json rpc及其结果流,以及对从浏览器中得到的json rpc进行处理,send/sendsync的处理是不同的,然后将他们根据得到的特殊id存储到数组中,等待传送到区块链进行处理

const pump = require(‘pump‘)//看本博客pump模块的学习-metamaskconst RpcEngine = require(‘json-rpc-engine‘)//看本博客MetaMask/json-rpc-engineconst createErrorMiddleware = require(‘./createErrorMiddleware‘)//检查json rpc产生的错误const createIdRemapMiddleware = require(‘json-rpc-engine/src/idRemapMiddleware‘)创建一个独特的id来标识json rpc,不然它的id很多都是相同的1,2等,看本博客MetaMask/json-rpc-engineconst createJsonRpcStream = require(‘json-rpc-middleware-stream‘)//看本博客的MetaMask/json-rpc-middleware-streamconst LocalStorageStore = require(‘obs-store‘)//看本博客MetaMask/obs-storeconst asStream = require(‘obs-store/lib/asStream‘)//看本博客MetaMask/obs-storeconst ObjectMultiplex = require(‘obj-multiplex‘)//看博客kumavis/obj-multiplexconst util = require(‘util‘)const SafeEventEmitter = require(‘safe-event-emitter‘)//看博客MetaMask/safe-event-emittermodule.exports = MetamaskInpageProviderutil.inherits(MetamaskInpageProvider, SafeEventEmitter)function MetamaskInpageProvider (connectionStream) { ?const self = this ?// super constructor ?SafeEventEmitter.call(self) ?// setup connectionStream multiplexing ?const mux = self.mux = new ObjectMultiplex() ?pump( ???connectionStream, ???mux, ???connectionStream, ???logStreamDisconnectWarning.bind(this, ‘MetaMask‘) ?) ?// subscribe to metamask public config (one-way) ?self.publicConfigStore = new LocalStorageStore({ storageKey: ‘MetaMask-Config‘ })//定义了一个在浏览器中storageKey为‘MetaMask-Config‘的本地存储,用于存储一些区块链的账户信息,网络信息 ?pump(//进行浏览器本地信息存储 ???mux.createStream(‘publicConfig‘),//创建name为publicConfig的子流 ???asStream(self.publicConfigStore), ???logStreamDisconnectWarning.bind(this, ‘MetaMask PublicConfigStore‘)//logStreamDisconnectWarning函数下面有定义,‘MetaMask PublicConfigStore‘为error说明, ?) ?// ignore phishing warning message (handled elsewhere) ?mux.ignoreStream(‘phishing‘)//这里不对name为phishing的流进行处理 ?// connect to async provider ?const jsonRpcConnection = createJsonRpcStream()// ?pump(//构建provider,接受浏览器传来的json rpc,并响应 ???jsonRpcConnection.stream, ???mux.createStream(‘provider‘), ???jsonRpcConnection.stream, ???logStreamDisconnectWarning.bind(this, ‘MetaMask RpcProvider‘) ?) ?// handle sendAsync requests via dapp-side rpc engine ?const rpcEngine = new RpcEngine() 看了本博客MetaMask/json-rpc-engine后,可以知道这是push进将要对接受到的json rpc调用的处理 ?rpcEngine.push(createIdRemapMiddleware())//获得个unique id拿来使用 ?rpcEngine.push(createErrorMiddleware()) //进行错误的处理 ?rpcEngine.push(jsonRpcConnection.middleware) //将json rpc 请求写入createJsonRpcStream双工流中 ?self.rpcEngine = rpcEngine ?// forward json rpc notifications ?jsonRpcConnection.events.on(‘notification‘, function(payload) {//设置json-rpc-middleware-stream流相应的‘notification‘事件 ???self.emit(‘data‘, null, payload) //触发data事件 ?}) ?// Work around for https://github.com/metamask/metamask-extension/issues/5459 ?// drizzle accidently breaking the `this` reference ?self.send = self.send.bind(self) ?self.sendAsync = self.sendAsync.bind(self)}// Web3 1.0 provider uses `send` with a callback for async queriesMetamaskInpageProvider.prototype.send = function (payload, callback) {//web3调用send() ?const self = this ?if (callback) {//如果是异步带回调的,就调用sendAsync ???self.sendAsync(payload, callback) ?} else {//否则就调用_sendSync ???return self._sendSync(payload) ?}}// handle sendAsync requests via asyncProvider// also remap ids inbound and outboundMetamaskInpageProvider.prototype.sendAsync = function (payload, cb) { ?const self = this ?if (payload.method === ‘eth_signTypedData‘) { ???console.warn(‘MetaMask: This experimental version of eth_signTypedData will be deprecated in the next release in favor of the standard as defined in EIP-712. See https://git.io/fNzPl for more information on the new standard.‘) ?} ?self.rpcEngine.handle(payload, cb)//该json rpc就会被处理}MetamaskInpageProvider.prototype._sendSync = function (payload) { ?const self = this ?let selectedAddress ?let result = null ?switch (payload.method) { ???case ‘eth_accounts‘: ?????// read from localStorage ?????selectedAddress = self.publicConfigStore.getState().selectedAddress //从本地存储中获得账户信息 ?????result = selectedAddress ? [selectedAddress] : [] ?????break ???case ‘eth_coinbase‘: ?????// read from localStorage ?????selectedAddress = self.publicConfigStore.getState().selectedAddress//从本地存储中获得账户信息 ?????result = selectedAddress || null ?????break ???case ‘eth_uninstallFilter‘: ?????self.sendAsync(payload, noop) //设置回调为{}再调用sendAsync ?????result = true ?????break ???case ‘net_version‘: ?????const networkVersion = self.publicConfigStore.getState().networkVersion//从本地存储中获得网络信息 ?????result = networkVersion || null ?????break ???// throw not-supported Error ???default: ?????var link = ‘https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-client‘ ?????var message = `The MetaMask Web3 object does not support synchronous methods like ${payload.method} without a callback parameter. See ${link} for details.` ?????throw new Error(message) ?} ?// return the result ?return { ???id: payload.id, ???jsonrpc: payload.jsonrpc, ???result: result, ?}}MetamaskInpageProvider.prototype.isConnected = function () { ?return true}MetamaskInpageProvider.prototype.isMetaMask = true// utilfunction logStreamDisconnectWarning (remoteLabel, err) { ?let warningMsg = `MetamaskInpageProvider - lost connection to ${remoteLabel}` ?if (err) warningMsg += ‘\n‘ + err.stack ?console.warn(warningMsg) ?const listeners = this.listenerCount(‘error‘) ?if (listeners > 0) { ???this.emit(‘error‘, warningMsg) ?}}function noop () {}

Usage

MetamaskInpageProvider的使用:
// Create a stream to a remote provider:var metamaskStream = new LocalMessageDuplexStream({ ?name: ‘inpage‘, ?target: ‘contentscript‘,})// compose the inpage providervar inpageProvider = new MetamaskInpageProvider(metamaskStream)
 

MetaMask/metamask-inpage-provider

原文地址:https://www.cnblogs.com/wanghui-garcia/p/9885472.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved