UNPKG

@machinomy/hdwallet-provider

Version:

HD Wallet-enabled Web3 provider

110 lines 4.69 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.NonceSubprovider = void 0; const subprovider_1 = require("./subprovider"); const util_1 = require("./util"); const ethUtil = __importStar(require("ethereumjs-util")); const transaction_util_1 = require("./util/transaction.util"); class NonceSubprovider extends subprovider_1.SubProvider { constructor() { super(...arguments); this.nonceCache = new Map(); } updateNonce(address, nonce, cb) { const cached = this.nonceCache.get(address); const isNewerNonce = typeof cached === "number" && nonce > cached; if (!cached || isNewerNonce) { this.nonceCache.set(address, nonce); } cb(); } handleRequest(payload, next, end) { switch (payload.method) { case "eth_getTransactionCount": const blockTag = util_1.blockTagForPayload(payload); const address = payload.params[0].toLowerCase(); const cachedResult = this.nonceCache.get(address); // only handle requests against the 'pending' blockTag if (blockTag === "pending") { // has a result if (cachedResult) { end(null, cachedResult); // fallthrough then populate cache } else { next((err, result, cb) => { if (err) return cb(); this.updateNonce(address, ethUtil.bufferToInt(result), () => { cb(); }); }); } } else { next(); } return; case "eth_sendRawTransaction": if (!this.engine) throw new Error("Should have set engine"); this.engine.sendAsync(util_1.createPayload({ method: "net_version" }), (err, result) => { if (err) { end(err); } else { const networkId = Number(result.result); // allow the request to continue normally next((err, result, cb) => { // only update local nonce if tx was submitted correctly if (err) return cb(); // parse raw tx const rawTx = ethUtil.toBuffer(payload.params[0]); const tx = transaction_util_1.buildTransaction(rawTx, networkId); // extract address const address = ethUtil.bufferToHex(tx.getSenderAddress()); // extract nonce and increment let nonce = ethUtil.bufferToInt(tx.nonce); nonce++; // dont update our record on the nonce until the submit was successful // update cache this.updateNonce(address, nonce, () => { cb(); }); }); } }); return; // Clear cache on a testrpc revert case "evm_revert": this.nonceCache = new Map(); next(); return; default: next(); return; } } } exports.NonceSubprovider = NonceSubprovider; //# sourceMappingURL=nonce.subprovider.js.map