format.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.formatTransactionResponse = exports.formatTransactionReceipt = exports.formatReceiptLog = exports.formatBlock = exports.formatLog = exports.formatUint256 = exports.formatHash = exports.formatData = exports.formatBoolean = exports.object = exports.arrayOf = exports.allowNull = void 0;
  4. /**
  5. * @_ignore
  6. */
  7. const index_js_1 = require("../address/index.js");
  8. const index_js_2 = require("../crypto/index.js");
  9. const index_js_3 = require("../transaction/index.js");
  10. const index_js_4 = require("../utils/index.js");
  11. const BN_0 = BigInt(0);
  12. function allowNull(format, nullValue) {
  13. return (function (value) {
  14. if (value == null) {
  15. return nullValue;
  16. }
  17. return format(value);
  18. });
  19. }
  20. exports.allowNull = allowNull;
  21. function arrayOf(format, allowNull) {
  22. return ((array) => {
  23. if (allowNull && array == null) {
  24. return null;
  25. }
  26. if (!Array.isArray(array)) {
  27. throw new Error("not an array");
  28. }
  29. return array.map((i) => format(i));
  30. });
  31. }
  32. exports.arrayOf = arrayOf;
  33. // Requires an object which matches a fleet of other formatters
  34. // Any FormatFunc may return `undefined` to have the value omitted
  35. // from the result object. Calls preserve `this`.
  36. function object(format, altNames) {
  37. return ((value) => {
  38. const result = {};
  39. for (const key in format) {
  40. let srcKey = key;
  41. if (altNames && key in altNames && !(srcKey in value)) {
  42. for (const altKey of altNames[key]) {
  43. if (altKey in value) {
  44. srcKey = altKey;
  45. break;
  46. }
  47. }
  48. }
  49. try {
  50. const nv = format[key](value[srcKey]);
  51. if (nv !== undefined) {
  52. result[key] = nv;
  53. }
  54. }
  55. catch (error) {
  56. const message = (error instanceof Error) ? error.message : "not-an-error";
  57. (0, index_js_4.assert)(false, `invalid value for value.${key} (${message})`, "BAD_DATA", { value });
  58. }
  59. }
  60. return result;
  61. });
  62. }
  63. exports.object = object;
  64. function formatBoolean(value) {
  65. switch (value) {
  66. case true:
  67. case "true":
  68. return true;
  69. case false:
  70. case "false":
  71. return false;
  72. }
  73. (0, index_js_4.assertArgument)(false, `invalid boolean; ${JSON.stringify(value)}`, "value", value);
  74. }
  75. exports.formatBoolean = formatBoolean;
  76. function formatData(value) {
  77. (0, index_js_4.assertArgument)((0, index_js_4.isHexString)(value, true), "invalid data", "value", value);
  78. return value;
  79. }
  80. exports.formatData = formatData;
  81. function formatHash(value) {
  82. (0, index_js_4.assertArgument)((0, index_js_4.isHexString)(value, 32), "invalid hash", "value", value);
  83. return value;
  84. }
  85. exports.formatHash = formatHash;
  86. function formatUint256(value) {
  87. if (!(0, index_js_4.isHexString)(value)) {
  88. throw new Error("invalid uint256");
  89. }
  90. return (0, index_js_4.zeroPadValue)(value, 32);
  91. }
  92. exports.formatUint256 = formatUint256;
  93. const _formatLog = object({
  94. address: index_js_1.getAddress,
  95. blockHash: formatHash,
  96. blockNumber: index_js_4.getNumber,
  97. data: formatData,
  98. index: index_js_4.getNumber,
  99. removed: allowNull(formatBoolean, false),
  100. topics: arrayOf(formatHash),
  101. transactionHash: formatHash,
  102. transactionIndex: index_js_4.getNumber,
  103. }, {
  104. index: ["logIndex"]
  105. });
  106. function formatLog(value) {
  107. return _formatLog(value);
  108. }
  109. exports.formatLog = formatLog;
  110. const _formatBlock = object({
  111. hash: allowNull(formatHash),
  112. parentHash: formatHash,
  113. parentBeaconBlockRoot: allowNull(formatHash, null),
  114. number: index_js_4.getNumber,
  115. timestamp: index_js_4.getNumber,
  116. nonce: allowNull(formatData),
  117. difficulty: index_js_4.getBigInt,
  118. gasLimit: index_js_4.getBigInt,
  119. gasUsed: index_js_4.getBigInt,
  120. stateRoot: allowNull(formatHash, null),
  121. receiptsRoot: allowNull(formatHash, null),
  122. blobGasUsed: allowNull(index_js_4.getBigInt, null),
  123. excessBlobGas: allowNull(index_js_4.getBigInt, null),
  124. miner: allowNull(index_js_1.getAddress),
  125. prevRandao: allowNull(formatHash, null),
  126. extraData: formatData,
  127. baseFeePerGas: allowNull(index_js_4.getBigInt)
  128. }, {
  129. prevRandao: ["mixHash"]
  130. });
  131. function formatBlock(value) {
  132. const result = _formatBlock(value);
  133. result.transactions = value.transactions.map((tx) => {
  134. if (typeof (tx) === "string") {
  135. return tx;
  136. }
  137. return formatTransactionResponse(tx);
  138. });
  139. return result;
  140. }
  141. exports.formatBlock = formatBlock;
  142. const _formatReceiptLog = object({
  143. transactionIndex: index_js_4.getNumber,
  144. blockNumber: index_js_4.getNumber,
  145. transactionHash: formatHash,
  146. address: index_js_1.getAddress,
  147. topics: arrayOf(formatHash),
  148. data: formatData,
  149. index: index_js_4.getNumber,
  150. blockHash: formatHash,
  151. }, {
  152. index: ["logIndex"]
  153. });
  154. function formatReceiptLog(value) {
  155. return _formatReceiptLog(value);
  156. }
  157. exports.formatReceiptLog = formatReceiptLog;
  158. const _formatTransactionReceipt = object({
  159. to: allowNull(index_js_1.getAddress, null),
  160. from: allowNull(index_js_1.getAddress, null),
  161. contractAddress: allowNull(index_js_1.getAddress, null),
  162. // should be allowNull(hash), but broken-EIP-658 support is handled in receipt
  163. index: index_js_4.getNumber,
  164. root: allowNull(index_js_4.hexlify),
  165. gasUsed: index_js_4.getBigInt,
  166. blobGasUsed: allowNull(index_js_4.getBigInt, null),
  167. logsBloom: allowNull(formatData),
  168. blockHash: formatHash,
  169. hash: formatHash,
  170. logs: arrayOf(formatReceiptLog),
  171. blockNumber: index_js_4.getNumber,
  172. //confirmations: allowNull(getNumber, null),
  173. cumulativeGasUsed: index_js_4.getBigInt,
  174. effectiveGasPrice: allowNull(index_js_4.getBigInt),
  175. blobGasPrice: allowNull(index_js_4.getBigInt, null),
  176. status: allowNull(index_js_4.getNumber),
  177. type: allowNull(index_js_4.getNumber, 0)
  178. }, {
  179. effectiveGasPrice: ["gasPrice"],
  180. hash: ["transactionHash"],
  181. index: ["transactionIndex"],
  182. });
  183. function formatTransactionReceipt(value) {
  184. return _formatTransactionReceipt(value);
  185. }
  186. exports.formatTransactionReceipt = formatTransactionReceipt;
  187. function formatTransactionResponse(value) {
  188. // Some clients (TestRPC) do strange things like return 0x0 for the
  189. // 0 address; correct this to be a real address
  190. if (value.to && (0, index_js_4.getBigInt)(value.to) === BN_0) {
  191. value.to = "0x0000000000000000000000000000000000000000";
  192. }
  193. const result = object({
  194. hash: formatHash,
  195. // Some nodes do not return this, usually test nodes (like Ganache)
  196. index: allowNull(index_js_4.getNumber, undefined),
  197. type: (value) => {
  198. if (value === "0x" || value == null) {
  199. return 0;
  200. }
  201. return (0, index_js_4.getNumber)(value);
  202. },
  203. accessList: allowNull(index_js_3.accessListify, null),
  204. blobVersionedHashes: allowNull(arrayOf(formatHash, true), null),
  205. blockHash: allowNull(formatHash, null),
  206. blockNumber: allowNull(index_js_4.getNumber, null),
  207. transactionIndex: allowNull(index_js_4.getNumber, null),
  208. from: index_js_1.getAddress,
  209. // either (gasPrice) or (maxPriorityFeePerGas + maxFeePerGas) must be set
  210. gasPrice: allowNull(index_js_4.getBigInt),
  211. maxPriorityFeePerGas: allowNull(index_js_4.getBigInt),
  212. maxFeePerGas: allowNull(index_js_4.getBigInt),
  213. maxFeePerBlobGas: allowNull(index_js_4.getBigInt, null),
  214. gasLimit: index_js_4.getBigInt,
  215. to: allowNull(index_js_1.getAddress, null),
  216. value: index_js_4.getBigInt,
  217. nonce: index_js_4.getNumber,
  218. data: formatData,
  219. creates: allowNull(index_js_1.getAddress, null),
  220. chainId: allowNull(index_js_4.getBigInt, null)
  221. }, {
  222. data: ["input"],
  223. gasLimit: ["gas"],
  224. index: ["transactionIndex"]
  225. })(value);
  226. // If to and creates are empty, populate the creates from the value
  227. if (result.to == null && result.creates == null) {
  228. result.creates = (0, index_js_1.getCreateAddress)(result);
  229. }
  230. // @TODO: Check fee data
  231. // Add an access list to supported transaction types
  232. if ((value.type === 1 || value.type === 2) && value.accessList == null) {
  233. result.accessList = [];
  234. }
  235. // Compute the signature
  236. if (value.signature) {
  237. result.signature = index_js_2.Signature.from(value.signature);
  238. }
  239. else {
  240. result.signature = index_js_2.Signature.from(value);
  241. }
  242. // Some backends omit ChainId on legacy transactions, but we can compute it
  243. if (result.chainId == null) {
  244. const chainId = result.signature.legacyChainId;
  245. if (chainId != null) {
  246. result.chainId = chainId;
  247. }
  248. }
  249. // @TODO: check chainID
  250. /*
  251. if (value.chainId != null) {
  252. let chainId = value.chainId;
  253. if (isHexString(chainId)) {
  254. chainId = BigNumber.from(chainId).toNumber();
  255. }
  256. result.chainId = chainId;
  257. } else {
  258. let chainId = value.networkId;
  259. // geth-etc returns chainId
  260. if (chainId == null && result.v == null) {
  261. chainId = value.chainId;
  262. }
  263. if (isHexString(chainId)) {
  264. chainId = BigNumber.from(chainId).toNumber();
  265. }
  266. if (typeof(chainId) !== "number" && result.v != null) {
  267. chainId = (result.v - 35) / 2;
  268. if (chainId < 0) { chainId = 0; }
  269. chainId = parseInt(chainId);
  270. }
  271. if (typeof(chainId) !== "number") { chainId = 0; }
  272. result.chainId = chainId;
  273. }
  274. */
  275. // 0x0000... should actually be null
  276. if (result.blockHash && (0, index_js_4.getBigInt)(result.blockHash) === BN_0) {
  277. result.blockHash = null;
  278. }
  279. return result;
  280. }
  281. exports.formatTransactionResponse = formatTransactionResponse;
  282. //# sourceMappingURL=format.js.map