UNPKG

@celo/connect

Version:

Light Toolkit for connecting with the Celo network

310 lines 12.2 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.inputSignFormatter = exports.inputAddressFormatter = exports.inputAccessListFormatter = exports.parseAccessList = exports.outputBigNumberFormatter = exports.outputLogFormatter = exports.hexToNumber = exports.outputBlockFormatter = exports.outputBlockHeaderFormatter = exports.inputBlockNumberFormatter = exports.inputDefaultBlockNumberFormatter = exports.outputCeloTxReceiptFormatter = exports.outputCeloTxFormatter = exports.inputCeloTxFormatter = void 0; const address_1 = require("@celo/base/lib/address"); const address_2 = require("@celo/utils/lib/address"); const solidity_1 = require("@celo/utils/lib/solidity"); const bignumber_js_1 = __importDefault(require("bignumber.js")); const utf8_1 = require("utf8"); /** * Formats the input of a transaction and converts all values to HEX */ function inputCeloTxFormatter(tx) { const { from, chainId, nonce, to, gas, gasPrice, maxFeePerGas, maxPriorityFeePerGas, maxFeeInFeeCurrency, feeCurrency, data, value, accessList, common, chain, hardfork } = tx, rest = __rest(tx, ["from", "chainId", "nonce", "to", "gas", "gasPrice", "maxFeePerGas", "maxPriorityFeePerGas", "maxFeeInFeeCurrency", "feeCurrency", "data", "value", "accessList", "common", "chain", "hardfork"]); const formattedTX = rest; formattedTX.from = inputAddressFormatter(from === null || from === void 0 ? void 0 : from.toString()); formattedTX.to = inputAddressFormatter(to); formattedTX.gas = numberToHex(gas); formattedTX.value = numberToHex(value === null || value === void 0 ? void 0 : value.toString()); formattedTX.nonce = numberToHex(nonce === null || nonce === void 0 ? void 0 : nonce.toString()); if (feeCurrency) { formattedTX.feeCurrency = inputAddressFormatter(feeCurrency); } if (data && !isHex(data)) { throw new Error('The data field must be HEX encoded data.'); } else if (data) { formattedTX.data = (0, address_1.ensureLeading0x)(data); } if (gasPrice) { formattedTX.gasPrice = numberToHex(gasPrice.toString()); } if (maxFeePerGas) { formattedTX.maxFeePerGas = numberToHex(maxFeePerGas.toString()); } if (maxPriorityFeePerGas) { formattedTX.maxPriorityFeePerGas = numberToHex(maxPriorityFeePerGas.toString()); } if (accessList) { formattedTX.accessList = inputAccessListFormatter(accessList); } if (maxFeeInFeeCurrency) { formattedTX.maxFeeInFeeCurrency = numberToHex(maxFeeInFeeCurrency.toString()); } return formattedTX; } exports.inputCeloTxFormatter = inputCeloTxFormatter; function outputCeloTxFormatter(tx) { if (tx.blockNumber !== null) { tx.blockNumber = hexToNumber(tx.blockNumber); } if (tx.transactionIndex !== null) { tx.transactionIndex = hexToNumber(tx.transactionIndex); } tx.nonce = hexToNumber(tx.nonce); tx.gas = hexToNumber(tx.gas); tx.value = outputBigNumberFormatter(tx.value); if (tx.gasPrice) { tx.gasPrice = outputBigNumberFormatter(tx.gasPrice); } if (tx.maxFeePerGas) { tx.maxFeePerGas = outputBigNumberFormatter(tx.maxFeePerGas); } if (tx.maxPriorityFeePerGas) { tx.maxPriorityFeePerGas = outputBigNumberFormatter(tx.maxPriorityFeePerGas); } tx.to = tx.to && (0, address_2.isValidAddress)(tx.to) ? // tx.to could be `0x0` or `null` while contract creation (tx.to = (0, address_2.toChecksumAddress)(tx.to)) : null; // set to `null` if invalid address if (tx.from) { tx.from = (0, address_2.toChecksumAddress)(tx.from); } if (tx.feeCurrency) { tx.feeCurrency = (0, address_2.toChecksumAddress)(tx.feeCurrency); } return tx; } exports.outputCeloTxFormatter = outputCeloTxFormatter; function outputCeloTxReceiptFormatter(receipt) { if (typeof receipt !== 'object') { throw new Error('Received receipt is invalid: ' + receipt); } if (receipt.blockNumber !== null) { receipt.blockNumber = hexToNumber(receipt.blockNumber); } if (receipt.transactionIndex !== null) { receipt.transactionIndex = hexToNumber(receipt.transactionIndex); } receipt.cumulativeGasUsed = hexToNumber(receipt.cumulativeGasUsed); receipt.gasUsed = hexToNumber(receipt.gasUsed); if (Array.isArray(receipt.logs)) { receipt.logs = receipt.logs.map(outputLogFormatter); } if (receipt.contractAddress) { receipt.contractAddress = (0, address_2.toChecksumAddress)(receipt.contractAddress); } if (typeof receipt.status !== 'undefined' && receipt.status !== null) { receipt.status = Boolean(parseInt((0, address_1.trimLeading0x)(receipt.status), 10)); } return receipt; } exports.outputCeloTxReceiptFormatter = outputCeloTxReceiptFormatter; function inputDefaultBlockNumberFormatter(blockNumber) { if (blockNumber == null) { blockNumber = 'latest'; } return inputBlockNumberFormatter(blockNumber); } exports.inputDefaultBlockNumberFormatter = inputDefaultBlockNumberFormatter; function inputBlockNumberFormatter(blockNumber) { if (blockNumber == null) { return undefined; } if (isPredefinedBlockNumber(blockNumber)) { return blockNumber; } if (blockNumber === 'genesis') { return '0x0'; } return isHexStrict(blockNumber.toString()) ? blockNumber.toString().toLocaleLowerCase() : numberToHex(blockNumber.toString()); } exports.inputBlockNumberFormatter = inputBlockNumberFormatter; // TODO prune after gingerbread hardfork function outputBlockHeaderFormatter(blockHeader) { // transform to number blockHeader.gasLimit = hexToNumber(blockHeader.gasLimit); blockHeader.gasUsed = hexToNumber(blockHeader.gasUsed); blockHeader.size = hexToNumber(blockHeader.size); blockHeader.timestamp = hexToNumber(blockHeader.timestamp); if (blockHeader.number !== null) { blockHeader.number = hexToNumber(blockHeader.number); } if (blockHeader.miner) { blockHeader.miner = (0, address_2.toChecksumAddress)(blockHeader.miner); } return blockHeader; } exports.outputBlockHeaderFormatter = outputBlockHeaderFormatter; function outputBlockFormatter(block) { block = outputBlockHeaderFormatter(block); if (block.difficulty) { block.difficulty = outputBigNumberFormatter(block.difficulty); } if (block.totalDifficulty) { block.totalDifficulty = outputBigNumberFormatter(block.totalDifficulty); } if (Array.isArray(block.transactions)) { block.transactions.forEach((item) => { if (typeof item !== 'string' && !(item instanceof String)) { return outputCeloTxFormatter(item); } }); } return block; } exports.outputBlockFormatter = outputBlockFormatter; function hexToNumber(hex) { if (hex) { return new bignumber_js_1.default(hex).toNumber(); } return undefined; } exports.hexToNumber = hexToNumber; function outputLogFormatter(log) { // generate a custom log id if (typeof log.blockHash === 'string' && typeof log.transactionHash === 'string' && typeof log.logIndex === 'string') { const shaId = (0, solidity_1.sha3)((0, address_1.trimLeading0x)(log.blockHash) + (0, address_1.trimLeading0x)(log.transactionHash) + (0, address_1.trimLeading0x)(log.logIndex)); log.id = 'log_' + (0, address_1.trimLeading0x)(shaId).substring(0, 8); } else if (!log.id) { log.id = null; } if (log.blockNumber !== null) { log.blockNumber = hexToNumber(log.blockNumber); } if (log.transactionIndex !== null) { log.transactionIndex = hexToNumber(log.transactionIndex); } if (log.logIndex !== null) { log.logIndex = hexToNumber(log.logIndex); } if (log.address) { log.address = (0, address_2.toChecksumAddress)(log.address); } return log; } exports.outputLogFormatter = outputLogFormatter; function outputBigNumberFormatter(hex) { return new bignumber_js_1.default(hex).toString(10); } exports.outputBigNumberFormatter = outputBigNumberFormatter; function isHash(value) { return isHex(value) && value.length === 32; } function parseAccessList(accessListRaw) { const accessList = []; if (!accessListRaw) { return accessList; } for (const entry of accessListRaw) { const [address, storageKeys] = entry; throwIfInvalidAddress(address); accessList.push({ address, storageKeys: storageKeys.map((key) => { if (isHash(key)) { return key; } else { // same behavior as web3 throw new Error(`Invalid storage key: ${key}`); } }), }); } return accessList; } exports.parseAccessList = parseAccessList; function throwIfInvalidAddress(address) { if (!(0, address_2.isValidAddress)(address)) { throw new Error(`Invalid address: ${address}`); } } function inputAccessListFormatter(accessList) { if (!accessList || accessList.length === 0) { return []; } return accessList.reduce((acc, { address, storageKeys }) => { throwIfInvalidAddress(address); storageKeys.forEach((storageKey) => { if (storageKey.length - 2 !== 64) { throw new Error(`Invalid storage key: ${storageKey}`); } }); acc.push([address, storageKeys]); return acc; }, []); } exports.inputAccessListFormatter = inputAccessListFormatter; function inputAddressFormatter(address) { if (!address || address === '0x') { return undefined; } if ((0, address_2.isValidAddress)(address)) { return (0, address_1.ensureLeading0x)(address).toLocaleLowerCase(); } throw new Error(`Provided address ${address} is invalid, the capitalization checksum test failed`); } exports.inputAddressFormatter = inputAddressFormatter; function inputSignFormatter(data) { return isHexStrict(data) ? data : utf8ToHex(data); } exports.inputSignFormatter = inputSignFormatter; function utf8ToHex(str) { str = (0, utf8_1.encode)(str); let hex = ''; // remove \u0000 padding from either side str = str.replace(/^(?:\u0000)*/, ''); str = str.split('').reverse().join(''); str = str.replace(/^(?:\u0000)*/, ''); str = str.split('').reverse().join(''); for (let i = 0; i < str.length; i++) { const code = str.charCodeAt(i); // if (code !== 0) { const n = code.toString(16); hex += n.length < 2 ? '0' + n : n; // } } return (0, address_1.ensureLeading0x)(hex); } function isHex(hex) { return /^(-0x|0x)?[0-9a-f]*$/i.test(hex); } function isHexStrict(hex) { return /^(-)?0x[0-9a-f]*$/i.test(hex); } function numberToHex(value) { if (value) { const numberValue = new bignumber_js_1.default(value); const result = (0, address_1.ensureLeading0x)(new bignumber_js_1.default(value).toString(16)); // Seen in web3, copied just in case return (numberValue.lt(new bignumber_js_1.default(0)) ? `-${result}` : result); } return undefined; } function isPredefinedBlockNumber(blockNumber) { return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest'; } //# sourceMappingURL=formatter.js.map