index.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.joinSignature = exports.splitSignature = exports.hexZeroPad = exports.hexStripZeros = exports.hexValue = exports.hexConcat = exports.hexDataSlice = exports.hexDataLength = exports.hexlify = exports.isHexString = exports.zeroPad = exports.stripZeros = exports.concat = exports.arrayify = exports.isBytes = exports.isBytesLike = void 0;
  4. var logger_1 = require("@ethersproject/logger");
  5. var _version_1 = require("./_version");
  6. var logger = new logger_1.Logger(_version_1.version);
  7. ///////////////////////////////
  8. function isHexable(value) {
  9. return !!(value.toHexString);
  10. }
  11. function addSlice(array) {
  12. if (array.slice) {
  13. return array;
  14. }
  15. array.slice = function () {
  16. var args = Array.prototype.slice.call(arguments);
  17. return addSlice(new Uint8Array(Array.prototype.slice.apply(array, args)));
  18. };
  19. return array;
  20. }
  21. function isBytesLike(value) {
  22. return ((isHexString(value) && !(value.length % 2)) || isBytes(value));
  23. }
  24. exports.isBytesLike = isBytesLike;
  25. function isInteger(value) {
  26. return (typeof (value) === "number" && value == value && (value % 1) === 0);
  27. }
  28. function isBytes(value) {
  29. if (value == null) {
  30. return false;
  31. }
  32. if (value.constructor === Uint8Array) {
  33. return true;
  34. }
  35. if (typeof (value) === "string") {
  36. return false;
  37. }
  38. if (!isInteger(value.length) || value.length < 0) {
  39. return false;
  40. }
  41. for (var i = 0; i < value.length; i++) {
  42. var v = value[i];
  43. if (!isInteger(v) || v < 0 || v >= 256) {
  44. return false;
  45. }
  46. }
  47. return true;
  48. }
  49. exports.isBytes = isBytes;
  50. function arrayify(value, options) {
  51. if (!options) {
  52. options = {};
  53. }
  54. if (typeof (value) === "number") {
  55. logger.checkSafeUint53(value, "invalid arrayify value");
  56. var result = [];
  57. while (value) {
  58. result.unshift(value & 0xff);
  59. value = parseInt(String(value / 256));
  60. }
  61. if (result.length === 0) {
  62. result.push(0);
  63. }
  64. return addSlice(new Uint8Array(result));
  65. }
  66. if (options.allowMissingPrefix && typeof (value) === "string" && value.substring(0, 2) !== "0x") {
  67. value = "0x" + value;
  68. }
  69. if (isHexable(value)) {
  70. value = value.toHexString();
  71. }
  72. if (isHexString(value)) {
  73. var hex = value.substring(2);
  74. if (hex.length % 2) {
  75. if (options.hexPad === "left") {
  76. hex = "0x0" + hex.substring(2);
  77. }
  78. else if (options.hexPad === "right") {
  79. hex += "0";
  80. }
  81. else {
  82. logger.throwArgumentError("hex data is odd-length", "value", value);
  83. }
  84. }
  85. var result = [];
  86. for (var i = 0; i < hex.length; i += 2) {
  87. result.push(parseInt(hex.substring(i, i + 2), 16));
  88. }
  89. return addSlice(new Uint8Array(result));
  90. }
  91. if (isBytes(value)) {
  92. return addSlice(new Uint8Array(value));
  93. }
  94. return logger.throwArgumentError("invalid arrayify value", "value", value);
  95. }
  96. exports.arrayify = arrayify;
  97. function concat(items) {
  98. var objects = items.map(function (item) { return arrayify(item); });
  99. var length = objects.reduce(function (accum, item) { return (accum + item.length); }, 0);
  100. var result = new Uint8Array(length);
  101. objects.reduce(function (offset, object) {
  102. result.set(object, offset);
  103. return offset + object.length;
  104. }, 0);
  105. return addSlice(result);
  106. }
  107. exports.concat = concat;
  108. function stripZeros(value) {
  109. var result = arrayify(value);
  110. if (result.length === 0) {
  111. return result;
  112. }
  113. // Find the first non-zero entry
  114. var start = 0;
  115. while (start < result.length && result[start] === 0) {
  116. start++;
  117. }
  118. // If we started with zeros, strip them
  119. if (start) {
  120. result = result.slice(start);
  121. }
  122. return result;
  123. }
  124. exports.stripZeros = stripZeros;
  125. function zeroPad(value, length) {
  126. value = arrayify(value);
  127. if (value.length > length) {
  128. logger.throwArgumentError("value out of range", "value", arguments[0]);
  129. }
  130. var result = new Uint8Array(length);
  131. result.set(value, length - value.length);
  132. return addSlice(result);
  133. }
  134. exports.zeroPad = zeroPad;
  135. function isHexString(value, length) {
  136. if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
  137. return false;
  138. }
  139. if (length && value.length !== 2 + 2 * length) {
  140. return false;
  141. }
  142. return true;
  143. }
  144. exports.isHexString = isHexString;
  145. var HexCharacters = "0123456789abcdef";
  146. function hexlify(value, options) {
  147. if (!options) {
  148. options = {};
  149. }
  150. if (typeof (value) === "number") {
  151. logger.checkSafeUint53(value, "invalid hexlify value");
  152. var hex = "";
  153. while (value) {
  154. hex = HexCharacters[value & 0xf] + hex;
  155. value = Math.floor(value / 16);
  156. }
  157. if (hex.length) {
  158. if (hex.length % 2) {
  159. hex = "0" + hex;
  160. }
  161. return "0x" + hex;
  162. }
  163. return "0x00";
  164. }
  165. if (typeof (value) === "bigint") {
  166. value = value.toString(16);
  167. if (value.length % 2) {
  168. return ("0x0" + value);
  169. }
  170. return "0x" + value;
  171. }
  172. if (options.allowMissingPrefix && typeof (value) === "string" && value.substring(0, 2) !== "0x") {
  173. value = "0x" + value;
  174. }
  175. if (isHexable(value)) {
  176. return value.toHexString();
  177. }
  178. if (isHexString(value)) {
  179. if (value.length % 2) {
  180. if (options.hexPad === "left") {
  181. value = "0x0" + value.substring(2);
  182. }
  183. else if (options.hexPad === "right") {
  184. value += "0";
  185. }
  186. else {
  187. logger.throwArgumentError("hex data is odd-length", "value", value);
  188. }
  189. }
  190. return value.toLowerCase();
  191. }
  192. if (isBytes(value)) {
  193. var result = "0x";
  194. for (var i = 0; i < value.length; i++) {
  195. var v = value[i];
  196. result += HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f];
  197. }
  198. return result;
  199. }
  200. return logger.throwArgumentError("invalid hexlify value", "value", value);
  201. }
  202. exports.hexlify = hexlify;
  203. /*
  204. function unoddify(value: BytesLike | Hexable | number): BytesLike | Hexable | number {
  205. if (typeof(value) === "string" && value.length % 2 && value.substring(0, 2) === "0x") {
  206. return "0x0" + value.substring(2);
  207. }
  208. return value;
  209. }
  210. */
  211. function hexDataLength(data) {
  212. if (typeof (data) !== "string") {
  213. data = hexlify(data);
  214. }
  215. else if (!isHexString(data) || (data.length % 2)) {
  216. return null;
  217. }
  218. return (data.length - 2) / 2;
  219. }
  220. exports.hexDataLength = hexDataLength;
  221. function hexDataSlice(data, offset, endOffset) {
  222. if (typeof (data) !== "string") {
  223. data = hexlify(data);
  224. }
  225. else if (!isHexString(data) || (data.length % 2)) {
  226. logger.throwArgumentError("invalid hexData", "value", data);
  227. }
  228. offset = 2 + 2 * offset;
  229. if (endOffset != null) {
  230. return "0x" + data.substring(offset, 2 + 2 * endOffset);
  231. }
  232. return "0x" + data.substring(offset);
  233. }
  234. exports.hexDataSlice = hexDataSlice;
  235. function hexConcat(items) {
  236. var result = "0x";
  237. items.forEach(function (item) {
  238. result += hexlify(item).substring(2);
  239. });
  240. return result;
  241. }
  242. exports.hexConcat = hexConcat;
  243. function hexValue(value) {
  244. var trimmed = hexStripZeros(hexlify(value, { hexPad: "left" }));
  245. if (trimmed === "0x") {
  246. return "0x0";
  247. }
  248. return trimmed;
  249. }
  250. exports.hexValue = hexValue;
  251. function hexStripZeros(value) {
  252. if (typeof (value) !== "string") {
  253. value = hexlify(value);
  254. }
  255. if (!isHexString(value)) {
  256. logger.throwArgumentError("invalid hex string", "value", value);
  257. }
  258. value = value.substring(2);
  259. var offset = 0;
  260. while (offset < value.length && value[offset] === "0") {
  261. offset++;
  262. }
  263. return "0x" + value.substring(offset);
  264. }
  265. exports.hexStripZeros = hexStripZeros;
  266. function hexZeroPad(value, length) {
  267. if (typeof (value) !== "string") {
  268. value = hexlify(value);
  269. }
  270. else if (!isHexString(value)) {
  271. logger.throwArgumentError("invalid hex string", "value", value);
  272. }
  273. if (value.length > 2 * length + 2) {
  274. logger.throwArgumentError("value out of range", "value", arguments[1]);
  275. }
  276. while (value.length < 2 * length + 2) {
  277. value = "0x0" + value.substring(2);
  278. }
  279. return value;
  280. }
  281. exports.hexZeroPad = hexZeroPad;
  282. function splitSignature(signature) {
  283. var result = {
  284. r: "0x",
  285. s: "0x",
  286. _vs: "0x",
  287. recoveryParam: 0,
  288. v: 0,
  289. yParityAndS: "0x",
  290. compact: "0x"
  291. };
  292. if (isBytesLike(signature)) {
  293. var bytes = arrayify(signature);
  294. // Get the r, s and v
  295. if (bytes.length === 64) {
  296. // EIP-2098; pull the v from the top bit of s and clear it
  297. result.v = 27 + (bytes[32] >> 7);
  298. bytes[32] &= 0x7f;
  299. result.r = hexlify(bytes.slice(0, 32));
  300. result.s = hexlify(bytes.slice(32, 64));
  301. }
  302. else if (bytes.length === 65) {
  303. result.r = hexlify(bytes.slice(0, 32));
  304. result.s = hexlify(bytes.slice(32, 64));
  305. result.v = bytes[64];
  306. }
  307. else {
  308. logger.throwArgumentError("invalid signature string", "signature", signature);
  309. }
  310. // Allow a recid to be used as the v
  311. if (result.v < 27) {
  312. if (result.v === 0 || result.v === 1) {
  313. result.v += 27;
  314. }
  315. else {
  316. logger.throwArgumentError("signature invalid v byte", "signature", signature);
  317. }
  318. }
  319. // Compute recoveryParam from v
  320. result.recoveryParam = 1 - (result.v % 2);
  321. // Compute _vs from recoveryParam and s
  322. if (result.recoveryParam) {
  323. bytes[32] |= 0x80;
  324. }
  325. result._vs = hexlify(bytes.slice(32, 64));
  326. }
  327. else {
  328. result.r = signature.r;
  329. result.s = signature.s;
  330. result.v = signature.v;
  331. result.recoveryParam = signature.recoveryParam;
  332. result._vs = signature._vs;
  333. // If the _vs is available, use it to populate missing s, v and recoveryParam
  334. // and verify non-missing s, v and recoveryParam
  335. if (result._vs != null) {
  336. var vs_1 = zeroPad(arrayify(result._vs), 32);
  337. result._vs = hexlify(vs_1);
  338. // Set or check the recid
  339. var recoveryParam = ((vs_1[0] >= 128) ? 1 : 0);
  340. if (result.recoveryParam == null) {
  341. result.recoveryParam = recoveryParam;
  342. }
  343. else if (result.recoveryParam !== recoveryParam) {
  344. logger.throwArgumentError("signature recoveryParam mismatch _vs", "signature", signature);
  345. }
  346. // Set or check the s
  347. vs_1[0] &= 0x7f;
  348. var s = hexlify(vs_1);
  349. if (result.s == null) {
  350. result.s = s;
  351. }
  352. else if (result.s !== s) {
  353. logger.throwArgumentError("signature v mismatch _vs", "signature", signature);
  354. }
  355. }
  356. // Use recid and v to populate each other
  357. if (result.recoveryParam == null) {
  358. if (result.v == null) {
  359. logger.throwArgumentError("signature missing v and recoveryParam", "signature", signature);
  360. }
  361. else if (result.v === 0 || result.v === 1) {
  362. result.recoveryParam = result.v;
  363. }
  364. else {
  365. result.recoveryParam = 1 - (result.v % 2);
  366. }
  367. }
  368. else {
  369. if (result.v == null) {
  370. result.v = 27 + result.recoveryParam;
  371. }
  372. else {
  373. var recId = (result.v === 0 || result.v === 1) ? result.v : (1 - (result.v % 2));
  374. if (result.recoveryParam !== recId) {
  375. logger.throwArgumentError("signature recoveryParam mismatch v", "signature", signature);
  376. }
  377. }
  378. }
  379. if (result.r == null || !isHexString(result.r)) {
  380. logger.throwArgumentError("signature missing or invalid r", "signature", signature);
  381. }
  382. else {
  383. result.r = hexZeroPad(result.r, 32);
  384. }
  385. if (result.s == null || !isHexString(result.s)) {
  386. logger.throwArgumentError("signature missing or invalid s", "signature", signature);
  387. }
  388. else {
  389. result.s = hexZeroPad(result.s, 32);
  390. }
  391. var vs = arrayify(result.s);
  392. if (vs[0] >= 128) {
  393. logger.throwArgumentError("signature s out of range", "signature", signature);
  394. }
  395. if (result.recoveryParam) {
  396. vs[0] |= 0x80;
  397. }
  398. var _vs = hexlify(vs);
  399. if (result._vs) {
  400. if (!isHexString(result._vs)) {
  401. logger.throwArgumentError("signature invalid _vs", "signature", signature);
  402. }
  403. result._vs = hexZeroPad(result._vs, 32);
  404. }
  405. // Set or check the _vs
  406. if (result._vs == null) {
  407. result._vs = _vs;
  408. }
  409. else if (result._vs !== _vs) {
  410. logger.throwArgumentError("signature _vs mismatch v and s", "signature", signature);
  411. }
  412. }
  413. result.yParityAndS = result._vs;
  414. result.compact = result.r + result.yParityAndS.substring(2);
  415. return result;
  416. }
  417. exports.splitSignature = splitSignature;
  418. function joinSignature(signature) {
  419. signature = splitSignature(signature);
  420. return hexlify(concat([
  421. signature.r,
  422. signature.s,
  423. (signature.recoveryParam ? "0x1c" : "0x1b")
  424. ]));
  425. }
  426. exports.joinSignature = joinSignature;
  427. //# sourceMappingURL=index.js.map