diff --git a/README.md b/README.md index 8b9d0bef..f8814167 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Project [honeybadger](https://github.com/Cryptonomic/honeybadger), which is the diff --git a/grammar/tezos/Micheline.ne b/grammar/tezos/Micheline.ne index d7f1cbc5..65de0edc 100644 --- a/grammar/tezos/Micheline.ne +++ b/grammar/tezos/Micheline.ne @@ -1,8 +1,8 @@ @preprocessor typescript @{% -const moo = require("moo"); -const bigInt = require("big-integer"); +import { TezosMessageUtils } from '../TezosMessageUtil'; +import * as moo from 'moo'; // https://gitlab.com/tezos/tezos/-/blob/master/src/proto_008_PtEdoTez/lib_protocol/michelson_v1_primitives.ml#L1088 export const DefaultMichelsonKeywords = ['"parameter"', '"storage"', '"code"', '"False"', '"Elt"', '"Left"', '"None"', '"Pair"', '"Right"', '"Some"', '"True"', '"Unit"', '"PACK"', '"UNPACK"', '"BLAKE2B"', '"SHA256"', '"SHA512"', '"ABS"', '"ADD"', '"AMOUNT"', '"AND"', '"BALANCE"', '"CAR"', '"CDR"', '"CHECK_SIGNATURE"', '"COMPARE"', '"CONCAT"', '"CONS"', '"CREATE_ACCOUNT"', '"CREATE_CONTRACT"', '"IMPLICIT_ACCOUNT"', '"DIP"', '"DROP"', '"DUP"', '"EDIV"', '"EMPTY_MAP"', '"EMPTY_SET"', '"EQ"', '"EXEC"', '"FAILWITH"', '"GE"', '"GET"', '"GT"', '"HASH_KEY"', '"IF"', '"IF_CONS"', '"IF_LEFT"', '"IF_NONE"', '"INT"', '"LAMBDA"', '"LE"', '"LEFT"', '"LOOP"', '"LSL"', '"LSR"', '"LT"', '"MAP"', '"MEM"', '"MUL"', '"NEG"', '"NEQ"', '"NIL"', '"NONE"', '"NOT"', '"NOW"', '"OR"', '"PAIR"', '"PUSH"', '"RIGHT"', '"SIZE"', '"SOME"', '"SOURCE"', '"SENDER"', '"SELF"', '"STEPS_TO_QUOTA"', '"SUB"', '"SWAP"', '"TRANSFER_TOKENS"', '"SET_DELEGATE"', '"UNIT"', '"UPDATE"', '"XOR"', '"ITER"', '"LOOP_LEFT"', '"ADDRESS"', '"CONTRACT"', '"ISNAT"', '"CAST"', '"RENAME"', '"bool"', '"contract"', '"int"', '"key"', '"key_hash"', '"lambda"', '"list"', '"map"', '"big_map"', '"nat"', '"option"', '"or"', '"pair"', '"set"', '"signature"', '"string"', '"bytes"', '"mutez"', '"timestamp"', '"unit"', '"operation"', '"address"', '"SLICE"', '"DIG"', '"DUG"', '"EMPTY_BIG_MAP"', '"APPLY"', '"chain_id"', '"CHAIN_ID"', '"LEVEL"', '"SELF_ADDRESS"', '"never"', '"NEVER"', '"UNPAIR"', '"VOTING_POWER"', '"TOTAL_VOTING_POWER"', '"KECCAK"', '"SHA3"', '"PAIRING_CHECK"', '"bls12_381_g1"', '"bls12_381_g2"', '"bls12_381_fr"', '"sapling_state"', '"sapling_transaction"', '"SAPLING_EMPTY_STATE"', '"SAPLING_VERIFY_UPDATE"', '"ticket"', '"TICKET"', '"READ_TICKET"', '"SPLIT_TICKET"', '"JOIN_TICKETS"', '"GET_AND_UPDATE"']; @@ -59,7 +59,7 @@ anyArray -> %lbracket %rbracket {% function(d) { return '0200000000'; } %} const staticIntToHex = d => { const prefix = '00'; const text = d[6].toString(); - const value = writeSignedInt(parseInt(text.substring(1, text.length - 1))); // strip double quotes + const value = TezosMessageUtils.writeSignedInt(text.substring(1, text.length - 1)); // strip double quotes return prefix + value; }; @@ -194,36 +194,4 @@ const encodePrimitive = p => { const encodeLength = l => { return ('0000000' + l.toString(16)).slice(-8); } - -const writeSignedInt = value => { - if (value === 0) { return '00'; } - - const n = bigInt(value).abs(); - const l = n.bitLength().toJSNumber(); - let arr: any = []; - let v = n; - for (let i = 0; i < l; i += 7) { - let byte = bigInt.zero; - - if (i === 0) { - byte = v.and(0x3f); // first byte makes room for sign flag - v = v.shiftRight(6); - } else { - byte = v.and(0x7f); // NOT base128 encoded - v = v.shiftRight(7); - } - - if (value < 0 && i === 0) { byte = byte.or(0x40); } // set sign flag - - if (i + 7 < l) { byte = byte.or(0x80); } // set next byte flag - arr.push(byte.toJSNumber()); - } - - if (l % 7 === 0) { - arr[arr.length - 1] = arr[arr.length - 1] | 0x80; - arr.push(1); - } - - return arr.map(v => ('0' + v.toString(16)).slice(-2)).join(''); - } %} diff --git a/package-lock.json b/package-lock.json index 9ae38d27..03de075f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "conseiljs", - "version": "5.0.6-1", + "version": "5.0.7-2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -235,9 +235,9 @@ } }, "@eslint/eslintrc": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", - "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", + "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -247,15 +247,15 @@ "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", - "lodash": "^4.17.19", + "lodash": "^4.17.20", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "dependencies": { "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -269,6 +269,12 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true } } }, @@ -351,9 +357,9 @@ } }, "@types/chai": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.12.tgz", - "integrity": "sha512-aN5IAC8QNtSUdQzxu7lGBgYAOuU1tmRU4c9dIq5OKGf/SBVjXo+ffM2wEjudAWbgpOhy60nLoAGH1xm8fpCKFQ==", + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", + "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", "dev": true }, "@types/chai-as-promised": { @@ -390,9 +396,9 @@ "dev": true }, "@types/mocha": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.3.tgz", - "integrity": "sha512-vyxR57nv8NfcU0GZu8EUXZLTbCMupIUwy95LJ6lllN+JRPG25CwMHoB1q5xKh8YKhQnHYRAn4yW2yuHbf/5xgg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.0.tgz", + "integrity": "sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ==", "dev": true }, "@types/nock": { @@ -485,6 +491,12 @@ "eslint-visitor-keys": "^1.1.0" } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -673,9 +685,9 @@ "dev": true }, "acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-jsx": { @@ -809,18 +821,6 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "array.prototype.map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", - "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.4" - } - }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -896,9 +896,9 @@ "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async-each": { @@ -1443,6 +1443,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", "dev": true, + "optional": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -1459,6 +1460,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, + "optional": true, "requires": { "fill-range": "^7.0.1" } @@ -1468,6 +1470,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, + "optional": true, "requires": { "to-regex-range": "^5.0.1" } @@ -1476,13 +1479,15 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "dev": true, + "optional": true }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "optional": true, "requires": { "is-number": "^7.0.0" } @@ -1668,6 +1673,14 @@ "jsonpath-plus": "4.0.0", "moo": "0.5.0", "nearley": "2.19.1" + }, + "dependencies": { + "jsonpath-plus": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-4.0.0.tgz", + "integrity": "sha512-e0Jtg4KAzDJKKwzbLaUtinCn0RZseWBVRTRGihSpvFlM3wTR7ExSp+PTdeTsDrLNJUe7L7JYJe8mblHX5SCT6A==", + "dev": true + } } }, "conseiljs-softsigner": { @@ -2128,65 +2141,6 @@ "prr": "~1.0.1" } }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "es-get-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", - "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", - "dev": true, - "requires": { - "es-abstract": "^1.17.4", - "has-symbols": "^1.0.1", - "is-arguments": "^1.0.4", - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "es5-ext": { "version": "0.10.53", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", @@ -2232,26 +2186,26 @@ "dev": true }, "eslint": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.9.0.tgz", - "integrity": "sha512-V6QyhX21+uXp4T+3nrNfI3hQNBDa/P8ga7LoQOenwrlEFXrEnUEE+ok1dMtaS3b6rmLXhT1TkTIsG75HMLbknA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz", + "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.1.3", + "@eslint/eslintrc": "^0.3.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", - "eslint-scope": "^5.1.0", + "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^1.3.0", - "espree": "^7.3.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", "esquery": "^1.2.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", @@ -2262,7 +2216,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", + "lodash": "^4.17.20", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -2271,18 +2225,17 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^5.2.3", + "table": "^6.0.4", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -2311,18 +2264,60 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2360,13 +2355,13 @@ "dev": true }, "espree": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", - "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { "acorn": "^7.4.0", - "acorn-jsx": "^5.2.0", + "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" } }, @@ -2629,12 +2624,12 @@ "dev": true }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-uri-to-path": { @@ -2745,37 +2740,36 @@ } }, "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "is-buffer": "~2.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } } } }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, "flush-write-stream": { @@ -2890,15 +2884,15 @@ "dev": true }, "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "requires": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", - "universalify": "^1.0.0" + "universalify": "^2.0.0" } }, "fs-minipass": { @@ -3128,15 +3122,6 @@ "har-schema": "^2.0.0" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -3225,9 +3210,9 @@ "dev": true }, "highlight.js": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.2.0.tgz", - "integrity": "sha512-OryzPiqqNCfO/wtFo619W+nPYALM6u7iCQkum4bqRmmlcTikOkmlL06i009QelynBPAlNByTQU6cBB2cOBQtCw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.5.0.tgz", + "integrity": "sha512-xTmvd9HiIHR6L53TMC7TKolEj65zG1XU+Onr8oi86mYa+nLcIbxTTWkpW7CsEwv/vK7u1zb8alZIMLDqqN6KTw==", "dev": true }, "hmac-drbg": { @@ -3292,9 +3277,9 @@ "dev": true }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -3376,12 +3361,6 @@ } } }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3397,12 +3376,6 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -3423,12 +3396,6 @@ } } }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -3475,12 +3442,6 @@ "is-extglob": "^2.1.1" } }, - "is-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", - "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", - "dev": true - }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -3502,9 +3463,9 @@ } }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-plain-object": { @@ -3516,36 +3477,6 @@ "isobject": "^3.0.1" } }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", - "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", - "dev": true - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -3753,22 +3684,6 @@ "istanbul-lib-report": "^3.0.0" } }, - "iterate-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", - "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==", - "dev": true - }, - "iterate-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", - "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", - "dev": true, - "requires": { - "es-get-iterator": "^1.0.2", - "iterate-iterator": "^1.0.1" - } - }, "jest-worker": { "version": "26.1.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.1.0.tgz", @@ -3864,19 +3779,19 @@ } }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" } }, "jsonpath-plus": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-4.0.0.tgz", - "integrity": "sha512-e0Jtg4KAzDJKKwzbLaUtinCn0RZseWBVRTRGihSpvFlM3wTR7ExSp+PTdeTsDrLNJUe7L7JYJe8mblHX5SCT6A==" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-5.0.2.tgz", + "integrity": "sha512-J1StEInJIb5INbUkzf/DM6mby0hEyU2o6kw+AUzrJnrgMunvDKdZgGFXEqH5qA2TVF3mVH7A6ZZQJpcNXXg90A==" }, "jsprim": { "version": "1.4.1", @@ -3988,9 +3903,9 @@ } }, "loglevel": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.0.tgz", - "integrity": "sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", + "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", "dev": true }, "loglevelnext": { @@ -4057,9 +3972,9 @@ } }, "marked": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.1.1.tgz", - "integrity": "sha512-mJzT8D2yPxoPh7h0UXkB+dBj4FykPJ2OIfxAWeIHrvoHDkFxukV/29QxoFQoPM6RLEwhIFdJpmKBlqVM3s2ZIw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.7.tgz", + "integrity": "sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA==", "dev": true }, "md5.js": { @@ -4264,15 +4179,16 @@ } }, "mocha": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.1.3.tgz", - "integrity": "sha512-ZbaYib4hT4PpF4bdSO2DohooKXIn4lDeiYqB+vTmCdr6l2woW0b6H3pf5x4sM5nwQMru9RvjjHYWVGltR50ZBw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", "dev": true, "requires": { + "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.4.2", - "debug": "4.1.1", + "chokidar": "3.4.3", + "debug": "4.2.0", "diff": "4.0.2", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", @@ -4283,17 +4199,16 @@ "log-symbols": "4.0.0", "minimatch": "3.0.4", "ms": "2.1.2", - "object.assign": "4.1.0", - "promise.allsettled": "1.0.2", - "serialize-javascript": "4.0.0", - "strip-json-comments": "3.0.1", - "supports-color": "7.1.0", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.0.0", + "workerpool": "6.0.2", "yargs": "13.3.2", "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.1" + "yargs-unparser": "2.0.0" }, "dependencies": { "ansi-regex": { @@ -4303,15 +4218,23 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -4322,6 +4245,22 @@ "supports-color": "^7.1.0" } }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4337,12 +4276,30 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -4365,6 +4322,12 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4384,12 +4347,12 @@ } }, "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { @@ -4407,6 +4370,24 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -4427,21 +4408,24 @@ "ansi-regex": "^4.1.0" } }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true - }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", @@ -4539,6 +4523,12 @@ "dev": true, "optional": true }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "dev": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -4595,9 +4585,9 @@ "dev": true }, "nock": { - "version": "13.0.4", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.4.tgz", - "integrity": "sha512-alqTV8Qt7TUbc74x1pKRLSENzfjp4nywovcJgi/1aXDiUxXdt7TkruSTF5MDWPP7UoPVgea4F9ghVdmX0xxnSA==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.6.tgz", + "integrity": "sha512-W81UZ1Tv21SWDZcA8Lu9LXYVl2gO9ADY5GadC6gFV9690h4TXz0oCkEoMckN/sPMHkDA79Ka9dXga9Mt1+j+Sg==", "dev": true, "requires": { "debug": "^4.1.0", @@ -4831,12 +4821,6 @@ } } }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -5126,19 +5110,6 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, - "promise.allsettled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", - "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", - "dev": true, - "requires": { - "array.prototype.map": "^1.0.1", - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "iterate-value": "^1.0.0" - } - }, "propagate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", @@ -5289,6 +5260,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", "dev": true, + "optional": true, "requires": { "picomatch": "^2.2.1" } @@ -5403,6 +5375,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -5644,20 +5622,38 @@ "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true } } @@ -5987,26 +5983,6 @@ } } }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -6047,48 +6023,46 @@ } }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", + "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^7.0.2", + "lodash": "^4.17.20", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "ajv": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", + "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true } } }, @@ -6387,50 +6361,39 @@ } }, "typedoc": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.19.2.tgz", - "integrity": "sha512-oDEg1BLEzi1qvgdQXc658EYgJ5qJLVSeZ0hQ57Eq4JXy6Vj2VX4RVo18qYxRWz75ifAaYuYNBUCnbhjd37TfOg==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.18.0.tgz", + "integrity": "sha512-UgDQwapCGQCCdYhEQzQ+kGutmcedklilgUGf62Vw6RdI29u6FcfAXFQfRTiJEbf16aK3YnkB20ctQK1JusCRbA==", "dev": true, "requires": { "fs-extra": "^9.0.1", "handlebars": "^4.7.6", - "highlight.js": "^10.2.0", - "lodash": "^4.17.20", - "lunr": "^2.3.9", + "highlight.js": "^10.0.0", + "lodash": "^4.17.15", + "lunr": "^2.3.8", "marked": "^1.1.1", "minimatch": "^3.0.0", "progress": "^2.0.3", - "semver": "^7.3.2", "shelljs": "^0.8.4", - "typedoc-default-themes": "^0.11.4" - }, - "dependencies": { - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - } + "typedoc-default-themes": "^0.10.2" } }, "typedoc-default-themes": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.11.4.tgz", - "integrity": "sha512-Y4Lf+qIb9NTydrexlazAM46SSLrmrQRqWiD52593g53SsmUFioAsMWt8m834J6qsp+7wHRjxCXSZeiiW5cMUdw==", - "dev": true + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.10.2.tgz", + "integrity": "sha512-zo09yRj+xwLFE3hyhJeVHWRSPuKEIAsFK5r2u47KL/HBKqpwdUSanoaz5L34IKiSATFrjG5ywmIu98hPVMfxZg==", + "dev": true, + "requires": { + "lunr": "^2.3.8" + } }, "typedoc-plugin-markdown": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.0.3.tgz", - "integrity": "sha512-cVa9BUkJw5IeadihNDlTy4e5yq1T0ZpNXzc+/vkgxdVJwgt1BQVQHSZYUNDa2R8nrlYmP9yt3ZQDxG9nIg4++A==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-2.4.2.tgz", + "integrity": "sha512-BBH+9/Uq5XbsqfzCDl8Jq4iaLXRMXRuAHZRFarAZX7df8+F3vUjDx/WHWoWqbZ/XUFzduLC2Iuy2qwsJX8SQ7A==", "dev": true, "requires": { + "fs-extra": "^9.0.1", "handlebars": "^4.7.6" } }, @@ -6441,9 +6404,9 @@ "dev": true }, "uglify-js": { - "version": "3.10.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.4.tgz", - "integrity": "sha512-kBFT3U4Dcj4/pJ52vfjCSfyLyvG9VYYuGYPmrPvAxRw/i7xHiT4VvCev+uiEMcEEiu6UNB6KgWmGtSUYIWScbw==", + "version": "3.12.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.5.tgz", + "integrity": "sha512-SgpgScL4T7Hj/w/GexjnBHi3Ien9WS1Rpfg5y91WXMj9SY997ZCQU76mH4TpLwwfmMvoOU8wiaRkIf6NaH3mtg==", "dev": true, "optional": true }, @@ -6478,9 +6441,9 @@ } }, "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, "unset-value": { @@ -7199,9 +7162,9 @@ } }, "workerpool": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", - "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", "dev": true }, "wrap-ansi": { @@ -7255,15 +7218,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -7417,78 +7371,28 @@ } }, "yargs-unparser": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.1.tgz", - "integrity": "sha512-qZV14lK9MWsGCmcr7u5oXGH0dbGqZAIxTDrWXZDo5zUr6b6iUmelNKO6x6R1dQT24AH3LgRxJpr8meWy2unolA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { - "camelcase": "^5.3.1", - "decamelize": "^1.2.0", - "flat": "^4.1.0", - "is-plain-obj": "^1.1.0", - "yargs": "^14.2.3" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "yargs": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.1" - } - }, - "yargs-parser": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -7497,6 +7401,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index b59aaf15..a6c98243 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "conseiljs", - "version": "5.0.7", + "version": "5.0.7-2", "description": "Client-side library for Tezos dApp development.", "browser": "dist/index-web.js", "main": "dist/index.js", @@ -70,14 +70,14 @@ "big-integer": "1.6.48", "blakejs": "1.1.0", "bs58check": "2.1.2", - "jsonpath-plus": "4.0.0", + "jsonpath-plus": "5.0.2", "moo": "0.5.0", "nearley": "2.19.1" }, "devDependencies": { - "@types/chai": "4.2.12", + "@types/chai": "4.2.14", "@types/chai-as-promised": "7.1.3", - "@types/mocha": "8.0.3", + "@types/mocha": "8.2.0", "@types/nock": "11.1.0", "@types/node": "14.0.13", "@types/node-fetch": "2.5.7", @@ -88,18 +88,18 @@ "conseiljs-softsigner": "5.0.3", "copyfiles": "2.3.0", "coveralls": "3.1.0", - "eslint": "7.9.0", + "eslint": "7.18.0", "glob": "7.1.6", - "loglevel": "1.7.0", - "mocha": "8.1.3", - "nock": "13.0.4", + "loglevel": "1.7.1", + "mocha": "8.2.1", + "nock": "13.0.6", "node-fetch": "2.6.1", "nyc": "15.1.0", "terser-webpack-plugin": "3.0.8", "ts-node": "8.10.2", "tsconfig-paths-webpack-plugin": "3.3.0", - "typedoc": "0.19.2", - "typedoc-plugin-markdown": "3.0.3", + "typedoc": "0.18.0", + "typedoc-plugin-markdown": "2.4.2", "typescript": "3.8.3", "webpack": "4.44.2", "webpack-cli": "3.3.12" diff --git a/src/chain/tezos/TezosLanguageUtil.ts b/src/chain/tezos/TezosLanguageUtil.ts index b19d62d0..b7b7f00e 100644 --- a/src/chain/tezos/TezosLanguageUtil.ts +++ b/src/chain/tezos/TezosLanguageUtil.ts @@ -4,6 +4,8 @@ import * as nearley from 'nearley'; import { TezosMessageUtils } from './TezosMessageUtil'; +const primitiveRecordOrder = ["prim", "args", "annots"]; + /** * A collection of functions to encode and decode Michelson and Micheline code */ @@ -258,7 +260,7 @@ export namespace TezosLanguageUtil { offset += anns.consumed; break; } - case '09': { // primitive with an argument array and an optional anotation set + case '09': { // primitive with an argument array and an optional annotation set code += `( ${hexToMichelsonKeyword(hex, offset)} `; offset += 2; @@ -430,6 +432,27 @@ export namespace TezosLanguageUtil { return parts.map(p => p.trim().split('\n').map(l => l.replace(/\#[\s\S]+$/, '').trim()).filter(v => v.length > 0).join(' ')); } + /** + * This util function is used to ensure the correct order in primitive records before parsing it. + * + * Micheline parser expects the following JSON order { prim: ..., args: ..., annots: ... } + */ + export function normalizePrimitiveRecordOrder(obj: object) { + if (Array.isArray(obj)) { + return obj.map(normalizePrimitiveRecordOrder); + } + + if (typeof obj === "object") { + return Object.keys(obj) + .sort((k1, k2) => primitiveRecordOrder.indexOf(k1) - primitiveRecordOrder.indexOf(k2)) + .reduce((newObj, key) => ({ + ...newObj, + [key]: normalizePrimitiveRecordOrder(obj[key]) + }), {}); + } + return obj; + } + /** * Micheline parser expects certain whitespace arrangement, this function will correct the input string accordingly. */ diff --git a/src/chain/tezos/TezosMessageCodec.ts b/src/chain/tezos/TezosMessageCodec.ts index f651ab54..a64105b9 100644 --- a/src/chain/tezos/TezosMessageCodec.ts +++ b/src/chain/tezos/TezosMessageCodec.ts @@ -20,6 +20,9 @@ const operationTypes: Map = new Map([ [110, 'delegation'] // >=P005 ]); +/** + * Reverse lookup table for operation types + */ const sepyTnoitarepo: Map = [...operationTypes.keys()].reduce((m, k) => { const v = operationTypes.get(k) || ''; if (m[v] > k) { return m; } return { ...m, [v]: k } }, new Map()); export namespace TezosMessageCodec { @@ -601,11 +604,12 @@ export namespace TezosMessageCodec { } if (!!origination.script) { - let parts: string[] = []; + let parts: object[] = []; parts.push(origination.script['code']); // full contract definition containing code, storage and parameters properties parts.push(origination.script['storage']); // initial storage hex += parts + .map(TezosLanguageUtil.normalizePrimitiveRecordOrder) .map(p => TezosLanguageUtil.normalizeMichelineWhiteSpace(JSON.stringify(p))) .map(p => TezosLanguageUtil.translateMichelineToHex(p)) .reduce((m, p) => { return m + ('0000000' + (p.length / 2).toString(16)).slice(-8) + p; }, ''); diff --git a/src/chain/tezos/TezosMessageUtil.ts b/src/chain/tezos/TezosMessageUtil.ts index 6ac3d10a..cfb0fac5 100644 --- a/src/chain/tezos/TezosMessageUtil.ts +++ b/src/chain/tezos/TezosMessageUtil.ts @@ -44,27 +44,28 @@ export namespace TezosMessageUtils { * Encodes a signed integer into hex. * @param {number} value Number to be obfuscated. */ - export function writeSignedInt(value: number): string { - if (value === 0) { return '00'; } + export function writeSignedInt(value: number | string): string { + if (value === 0 || value === '0') { return '00'; } - const n = bigInt(value).abs(); + let n = bigInt(value as string).abs(); const l = n.bitLength().toJSNumber(); let arr: number[] = []; - let v = n; + for (let i = 0; i < l; i += 7) { let byte = bigInt.zero; if (i === 0) { - byte = v.and(0x3f); // first byte makes room for sign flag - v = v.shiftRight(6); + byte = n.and(0x3f); // first byte makes room for sign flag + n = n.shiftRight(6); } else { - byte = v.and(0x7f); // NOT base128 encoded - v = v.shiftRight(7); + byte = n.and(0x7f); // NOT base128 encoded + n = n.shiftRight(7); } if (value < 0 && i === 0) { byte = byte.or(0x40); } // set sign flag if (i + 7 < l) { byte = byte.or(0x80); } // set next byte flag + arr.push(byte.toJSNumber()); } @@ -346,10 +347,10 @@ export namespace TezosMessageUtils { } /** - * Deserializes a binary buffer and decodes it into a Base58-check string subject to a hint. Calling this method with a blank hint makes it a wraper for base58check.encode(). + * Deserializes a binary buffer and decodes it into a Base58-check string subject to a hint. Calling this method with a blank hint makes it a wrapper for base58check.encode(). * * @param {Buffer | Uint8Array} b Bytes to encode - * @param hint One of: 'op' (operation encoding helper), 'p' (proposal), '' (blank) + * @param hint One of: 'op' (operation encoding helper), 'p' (proposal), expr (expression), '' (blank) */ export function readBufferWithHint(b: Buffer | Uint8Array, hint: string): string { const buffer = !(b instanceof Buffer) ? Buffer.from(b) : b; diff --git a/src/chain/tezos/TezosNodeWriter.ts b/src/chain/tezos/TezosNodeWriter.ts index b559fc03..064c49a7 100644 --- a/src/chain/tezos/TezosNodeWriter.ts +++ b/src/chain/tezos/TezosNodeWriter.ts @@ -16,6 +16,7 @@ const fetch = FetchSelector.fetch; import LogSelector from '../../utils/LoggerSelector'; const log = LogSelector.log; +const counterMatcher = new RegExp(/.*Counter [0-9]{1,} already used for contract.*/, 'gm'); let operationQueues = {} @@ -107,6 +108,28 @@ export namespace TezosNodeWriter { return ops; } + /** + * Pack a Micheline structure subject to the provided type. Returns a hex string from the server. + * + * This method is not a trustless. It is available because the internal Micheline converter is not yet 100% complete. + * + * @deprecated + */ + export async function packDataRemotely(server: string, data: string, type: string, gas: number = TezosConstants.OperationGasCap, chainid: string = 'main'): Promise { + log.debug('TezosNodeWriter.packDataRemotely:'); + log.debug(JSON.stringify(data)); + log.warn('packDataRemotely() is not intrinsically trustless'); + + const response = await performPostRequest(server, `chains/${chainid}/blocks/head/helpers/scripts/pack_data`, { data, type, gas: `${gas}`}); + const jsonResponse = await response.json(); + + try { + return jsonResponse.packed; + } catch (e) { + throw new Error(`Could not pack ${data} as ${type}; error ${e}`); + } + } + /** * Applies an operation using the Tezos RPC client. * @@ -166,9 +189,13 @@ export namespace TezosNodeWriter { * @param {Operation[]} operations The operations to create and send * @param {Signer} signer Cryptographic signature provider * @param {number} offset Age of the block to use as branch, set to 0 for head, default is 54 to force operation expiration with 10 blocks. - * @returns {Promise} The ID of the created operation group + * @returns {Promise} The ID of the created operation group */ - export async function sendOperation(server: string, operations: TezosP2PMessageTypes.Operation[], signer: Signer, offset: number = 54): Promise { + export async function sendOperation( + server: string, + operations: TezosP2PMessageTypes.Operation[], + signer: Signer, + offset: number = TezosConstants.HeadBranchOffset): Promise { const blockHead = await TezosNodeReader.getBlockAtOffset(server, offset); const blockHash = blockHead.hash.slice(0, 51); // consider throwing an error instead @@ -231,8 +258,8 @@ export namespace TezosNodeWriter { source: accountHash, fee: '0', // Reveal Fee will be covered by the appended operation counter: counter.toString(), - gas_limit: '10600', - storage_limit: '0', + gas_limit: TezosConstants.DefaultKeyRevealGasLimit.toString(), + storage_limit: TezosConstants.DefaultKeyRevealStorageLimit.toString(), public_key: publicKey }; @@ -258,7 +285,15 @@ export namespace TezosNodeWriter { * @param {number} offset Age of the block to use as branch, set to 0 for head, default is 54 to force operation expiration with 10 blocks. * @returns {Promise} Result of the operation */ - export async function sendTransactionOperation(server: string, signer: Signer, keyStore: KeyStore, to: string, amount: number, fee: number, offset: number = 54) { + export async function sendTransactionOperation( + server: string, + signer: Signer, + keyStore: KeyStore, + to: string, + amount: number, + fee: number = TezosConstants.DefaultSimpleTransactionFee, + offset: number = TezosConstants.HeadBranchOffset, + optimizeFee: boolean = false) { const counter = await TezosNodeReader.getCounterForAccount(server, keyStore.publicKeyHash) + 1; const transaction: TezosP2PMessageTypes.Transaction = { @@ -272,7 +307,7 @@ export namespace TezosNodeWriter { kind: 'transaction' }; - const operations = await appendRevealOperation(server, keyStore.publicKey, keyStore.publicKeyHash, counter - 1, [transaction]) + const operations = await prepareOperation(server, keyStore, counter, transaction, optimizeFee); return sendOperation(server, operations, signer, offset); } @@ -287,7 +322,14 @@ export namespace TezosNodeWriter { * @param {number} offset Age of the block to use as branch, set to 0 for head, default is 54 to force operation expiration with 10 blocks. * @returns {Promise} Result of the operation */ - export async function sendDelegationOperation(server: string, signer: Signer, keyStore: KeyStore, delegate: string | undefined, fee: number = TezosConstants.DefaultDelegationFee, offset: number = 54) { + export async function sendDelegationOperation( + server: string, + signer: Signer, + keyStore: KeyStore, + delegate: string | undefined, + fee: number = TezosConstants.DefaultDelegationFee, + offset: number = TezosConstants.HeadBranchOffset, + optimizeFee: boolean = false) { const counter = await TezosNodeReader.getCounterForAccount(server, keyStore.publicKeyHash) + 1; const delegation: TezosP2PMessageTypes.Delegation = { @@ -295,11 +337,12 @@ export namespace TezosNodeWriter { source: keyStore.publicKeyHash, fee: fee.toString(), counter: counter.toString(), - storage_limit: TezosConstants.DefaultDelegationStorageLimit + '', - gas_limit: TezosConstants.DefaultDelegationGasLimit + '', + storage_limit: TezosConstants.DefaultDelegationStorageLimit.toString(), + gas_limit: TezosConstants.DefaultDelegationGasLimit.toString(), delegate: delegate - } - const operations = await appendRevealOperation(server, keyStore.publicKey, keyStore.publicKeyHash, counter - 1, [delegation]); + }; + + const operations = await prepareOperation(server, keyStore, counter, delegation, optimizeFee); return sendOperation(server, operations, signer, offset); } @@ -314,8 +357,14 @@ export namespace TezosNodeWriter { * @param {number} offset Age of the block to use as branch, set to 0 for head, default is 54 to force operation expiration with 10 blocks. * @returns {Promise} Result of the operation */ - export async function sendUndelegationOperation(server: string, signer: Signer, keyStore: KeyStore, fee: number = TezosConstants.DefaultDelegationFee, offset: number = 54) { - return sendDelegationOperation(server, signer, keyStore, undefined, fee, offset); + export async function sendUndelegationOperation( + server: string, + signer: Signer, + keyStore: KeyStore, + fee: number = TezosConstants.DefaultDelegationFee, + offset: number = TezosConstants.HeadBranchOffset, + optimizeFee: boolean = false) { + return sendDelegationOperation(server, signer, keyStore, undefined, fee, offset, optimizeFee); } /** @@ -345,10 +394,11 @@ export namespace TezosNodeWriter { code: string, storage: string, codeFormat: TezosTypes.TezosParameterFormat = TezosTypes.TezosParameterFormat.Micheline, - offset: number = 54 + offset: number = TezosConstants.HeadBranchOffset, + optimizeFee: boolean = false ) { const counter = await TezosNodeReader.getCounterForAccount(server, keyStore.publicKeyHash) + 1; - const operation = constructContractOriginationOperation( + const origination = constructContractOriginationOperation( keyStore, amount, delegate, @@ -359,9 +409,10 @@ export namespace TezosNodeWriter { storage, codeFormat, counter - ) + ); + + const operations = await prepareOperation(server, keyStore, counter, origination, optimizeFee); - const operations = await appendRevealOperation(server, keyStore.publicKey, keyStore.publicKeyHash, counter - 1, [operation]); return sendOperation(server, operations, signer, offset); } @@ -372,7 +423,7 @@ export namespace TezosNodeWriter { * @param {number} amount Initial funding amount of new account * @param {string|undefined} delegate Account ID to delegate to, blank if none * @param {number} fee Operation fee - * @param {number} storageLimit Storage fee + * @param {number} storageLimit Storage burn cap * @param {number} gasLimit Gas limit * @param {string} code Contract code * @param {string} storage Initial storage value @@ -395,10 +446,10 @@ export namespace TezosNodeWriter { if (codeFormat === TezosTypes.TezosParameterFormat.Michelson) { parsedCode = JSON.parse(TezosLanguageUtil.translateMichelsonToMicheline(code)); - log.debug(`TezosNodeWriter.sendOriginationOperation code translation:\n${code}\n->\n${JSON.stringify(parsedCode)}`); + log.debug(`TezosNodeWriter.constructContractOriginationOperation code translation:\n${code}\n->\n${JSON.stringify(parsedCode)}`); parsedStorage = JSON.parse(TezosLanguageUtil.translateMichelsonToMicheline(storage)); - log.debug(`TezosNodeWriter.sendOriginationOperation storage translation:\n${storage}\n->\n${JSON.stringify(parsedStorage)}`); + log.debug(`TezosNodeWriter.constructContractOriginationOperation storage translation:\n${storage}\n->\n${JSON.stringify(parsedStorage)}`); } else if (codeFormat === TezosTypes.TezosParameterFormat.Micheline) { parsedCode = JSON.parse(code); parsedStorage = JSON.parse(storage); // TODO: handle empty storage @@ -444,12 +495,15 @@ export namespace TezosNodeWriter { entrypoint: string | undefined, parameters: string | undefined, parameterFormat: TezosTypes.TezosParameterFormat = TezosTypes.TezosParameterFormat.Micheline, - offset: number = 54 + offset: number = TezosConstants.HeadBranchOffset, + optimizeFee: boolean = false ) { const counter = await TezosNodeReader.getCounterForAccount(server, keyStore.publicKeyHash) + 1; const transaction = constructContractInvocationOperation(keyStore.publicKeyHash, counter, contract, amount, fee, storageLimit, gasLimit, entrypoint, parameters, parameterFormat); - const operations = await appendRevealOperation(server, keyStore.publicKey, keyStore.publicKeyHash, counter - 1, [transaction]); + + const operations = await prepareOperation(server, keyStore, counter, transaction, optimizeFee); + return sendOperation(server, operations, signer, offset); } @@ -521,7 +575,7 @@ export namespace TezosNodeWriter { * @param {number} offset Age of the block to use as branch, set to 0 for head, default is 54 to force operation expiration with 10 blocks. * @returns {Promise} Result of the operation */ - export async function sendKeyRevealOperation(server: string, signer: Signer, keyStore: KeyStore, fee: number = TezosConstants.DefaultKeyRevealFee, offset: number = 54) { + export async function sendKeyRevealOperation(server: string, signer: Signer, keyStore: KeyStore, fee: number = TezosConstants.DefaultKeyRevealFee, offset: number = TezosConstants.HeadBranchOffset) { const counter = await TezosNodeReader.getCounterForAccount(server, keyStore.publicKeyHash) + 1; const revealOp: TezosP2PMessageTypes.Reveal = { @@ -580,7 +634,7 @@ export namespace TezosNodeWriter { entrypoint: string | undefined, parameters: string | undefined, parameterFormat: TezosTypes.TezosParameterFormat = TezosTypes.TezosParameterFormat.Micheline - ): Promise<{ gas: number, storageCost: number }> { + ): Promise<{ gas: number, storageCost: number, estimatedFee: number, estimatedStorageBurn: number }> { const counter = await TezosNodeReader.getCounterForAccount(server, keyStore.publicKeyHash) + 1; const transaction = constructContractInvocationOperation( keyStore.publicKeyHash, @@ -595,7 +649,7 @@ export namespace TezosNodeWriter { parameterFormat ); - return estimateOperation(server, chainid, transaction) + return estimateOperation(server, chainid, transaction); } /** @@ -626,7 +680,7 @@ export namespace TezosNodeWriter { code: string, storage: string, codeFormat: TezosTypes.TezosParameterFormat = TezosTypes.TezosParameterFormat.Micheline - ): Promise<{ gas: number, storageCost: number }> { + ): Promise<{ gas: number, storageCost: number, estimatedFee: number, estimatedStorageBurn: number }> { const counter = await TezosNodeReader.getCounterForAccount(server, keyStore.publicKeyHash) + 1; const transaction = constructContractOriginationOperation( keyStore, @@ -641,29 +695,84 @@ export namespace TezosNodeWriter { counter ) - const resources = await estimateOperation(server, chainid, transaction) + return estimateOperation(server, chainid, transaction); + } - // A fixed storage cost is applied to new contract originations which is not included in the estimation response. - const fixedOriginationStorageCost = 257 - return { - gas: resources.gas, - storageCost: resources.storageCost + fixedOriginationStorageCost + /** + * Returns an operation group fee and storage burn estimates along with an array of gas and storage limits for the constituent operations. + * + * Inspired by OperationFeeEstimator.estimateAndApplyFees from @tacoinfra/harbinger-lib. + * + * @see https://github.com/tacoinfra/harbinger-lib/blob/c27cdd4643574c245ddca62bf7013964ae684bd5/src/operation-fee-estimator.ts#L30 + * + * @param {string} server Tezos node to connect to + * @param {string} chainid The chain ID to apply the operation on. + * @param operations An array of operations to process. + * @returns {[gas: number, storageCost: number], estimatedFee: number, estimatedStorageBurn: number} + */ + export async function estimateOperationGroup(server: string, chainid: string, operations: Array): Promise { + let operationResources: { gas: number, storageCost: number }[] = []; + + for (let i = 0; i < operations.length; i++) { // Estimate each operation. + const operation = operations[i]; + + // Estimate resources used in the set of prior transactions. + // If there were no prior transactions, set resource usage to 0. + let priorConsumedResources = { gas: 0, storageCost: 0 }; + if (i > 0) { + const priorTransactions = operations.slice(0, i); + priorConsumedResources = await estimateOperation(server, chainid, ...priorTransactions); + } + + // Estimate resources for everything up to the current transaction. Newer transactions may depend on previous transactions, thus all transactions must be estimated. + const currentTransactions = operations.slice(0, i + 1); + const currentConsumedResources = await TezosNodeWriter.estimateOperation(server, chainid, ...currentTransactions); + + // Find the actual transaction cost by calculating the delta between the two transactions resource usages. + const gasLimitDelta = currentConsumedResources.gas - priorConsumedResources.gas; + const storageLimitDelta = currentConsumedResources.storageCost - priorConsumedResources.storageCost; + + operationResources.push( + { + gas: gasLimitDelta + TezosConstants.GasLimitPadding, + storageCost: storageLimitDelta + TezosConstants.StorageLimitPadding + } + ); } + + const validBranch = 'BMLxA4tQjiu1PT2x3dMiijgvMTQo8AVxkPBPpdtM8hCfiyiC1jz'; + const gasLimitTotal = operationResources.map(r => r.gas).reduce((a, c) => a + c, 0); + const storageLimitTotal = operationResources.map(r => r.storageCost).reduce((a, c) => a + c, 0); + const forgedOperationGroup = forgeOperations(validBranch, operations); + const groupSize = forgedOperationGroup.length / 2 + 64; // operation group bytes + signature bytes + let estimatedFee = Math.ceil(gasLimitTotal / 10) + TezosConstants.BaseOperationFee + groupSize + TezosConstants.DefaultBakerVig; + const estimatedStorageBurn = Math.ceil(storageLimitTotal * TezosConstants.StorageRate); + + // if the fee nat is smaller than the estimate, add a constant to account for possible operation size difference + if (Number(operations[0].fee) < estimatedFee) { estimatedFee += 16; } + + log.debug('group estimate', operationResources, estimatedFee, estimatedStorageBurn); + + return { operationResources, estimatedFee, estimatedStorageBurn }; } + /** - * Dry run the given operation + * Submits the provided operation list to run_operation RPC and extracts gas and storage costs. Also provide estimated fee and storage burn. This function works by calling dryRunOperation() and it may throw an error if the operation is malformed or invalid. * * @param {string} server Tezos node to connect to * @param {string} chainid The chain ID to apply the operation on. - * @param {TezosP2PMessageTypes.Operation} operations A set of operations to update. - * @returns A two-element object gas and storage costs. Throws an error if one was encountered. + * @param {TezosP2PMessageTypes.Operation} operations A set of operations to submit. + * @returns A four-element object containing + * gas, storageCost, estimatedFee and estimatedStorageBurn. These are exact, unpadded numbers, in practice it may be worthwhile to pad gas and storage limits. */ export async function estimateOperation( server: string, chainid: string, ...operations: TezosP2PMessageTypes.Operation[] - ): Promise<{ gas: number, storageCost: number }> { - const responseJSON = await dryRunOperation(server, chainid, ...operations); + ): Promise<{ gas: number, storageCost: number, estimatedFee: number, estimatedStorageBurn: number }> { + const localOperations = [...operations].map(o => { return { ...o, gas_limit: TezosConstants.OperationGasCap.toString(), storage_limit: TezosConstants.OperationStorageCap.toString() } }); + + const responseJSON = await dryRunOperation(server, chainid, ...localOperations); let gas = 0; let storageCost = 0; @@ -672,25 +781,38 @@ export namespace TezosNodeWriter { try { gas += parseInt(c['metadata']['operation_result']['consumed_gas']) || 0; storageCost += parseInt(c['metadata']['operation_result']['paid_storage_size_diff']) || 0; + + if (c.kind === 'origination' || c['metadata']['operation_result']['allocated_destination_contract']) { + storageCost += TezosConstants.EmptyAccountStorageBurn; + } } catch { } // Process internal operations if they are present. const internalOperations = c['metadata']['internal_operation_results'] - if (internalOperations === undefined) { - continue - } + if (internalOperations === undefined) { continue; } + for (const internalOperation of internalOperations) { - const result = internalOperation['result'] - gas += parseInt(result['consumed_gas']) || 0 + const result = internalOperation['result']; + gas += parseInt(result['consumed_gas']) || 0; storageCost += parseInt(result['paid_storage_size_diff']) || 0; + if (result.kind === 'origination' || c['metadata']['operation_result']['allocated_destination_contract']) { + storageCost += TezosConstants.EmptyAccountStorageBurn; + } } } - return { gas, storageCost }; + const validBranch = 'BMLxA4tQjiu1PT2x3dMiijgvMTQo8AVxkPBPpdtM8hCfiyiC1jz'; + const forgedOperationGroup = forgeOperations(validBranch, operations); + const operationSize = forgedOperationGroup.length / 2 + 64; // operation bytes + signature bytes + const estimatedFee = Math.ceil(gas / 10) + TezosConstants.BaseOperationFee + operationSize + TezosConstants.DefaultBakerVig; + const estimatedStorageBurn = Math.ceil(storageCost * TezosConstants.StorageRate); + log.debug(`TezosNodeWriter.estimateOperation; gas: ${gas}, storage: ${storageCost}, fee estimate: ${estimatedFee}, burn estimate: ${estimatedStorageBurn}`); + + return { gas, storageCost, estimatedFee, estimatedStorageBurn }; } /** - * Dry run the given operation and return consumed resources. + * Dry run the given operation and return consumed resources. RPC response will also be parser for errors and if any are found, an exception will be thrown. * * Note: Estimating an operation on an unrevealed account is not supported and will fail. Remember to prepend * the Reveal operation if required. @@ -698,13 +820,9 @@ export namespace TezosNodeWriter { * @param {string} server Tezos node to connect to * @param {string} chainid The chain ID to apply the operation on. * @param {TezosP2PMessageTypes.Operation} operations A set of operations to update. - * @returns {Promise} JSON-encoded response + * @returns {Promise} JSON-encoded response */ - export async function dryRunOperation( - server: string, - chainid: string, - ...operations: TezosP2PMessageTypes.Operation[] - ): Promise { + export async function dryRunOperation(server: string, chainid: string, ...operations: TezosP2PMessageTypes.Operation[]): Promise { const fake_signature = 'edsigu6xFLH2NpJ1VcYshpjW99Yc1TAL1m2XBqJyXrxcZQgBMo8sszw2zm626yjpA3pWMhjpsahLrWdmvX9cqhd4ZEUchuBuFYy'; const fake_chainid = 'NetXdQprcVkpaWU'; const fake_branch = 'BL94i2ShahPx3BoNs6tJdXDdGeoJ9ukwujUA2P8WJwULYNdimmq'; @@ -719,6 +837,30 @@ export namespace TezosNodeWriter { return responseJSON; } + /** + * Adds a Reveal operation if needed and optimizes fees if asked. + * + * @param server + * @param keyStore + * @param counter + * @param operation + * @param optimizeFee + */ + async function prepareOperation(server: string, keyStore: KeyStore, counter: number, operation: any, optimizeFee: boolean = false) { + const operationGroup = await appendRevealOperation(server, keyStore.publicKey, keyStore.publicKeyHash, counter - 1, [operation]); + + if (optimizeFee) { + const estimate = await estimateOperationGroup(server, 'main', operationGroup); + operationGroup[0].fee = estimate.estimatedFee.toString(); + for (let i = 0; i < operationGroup.length; i++) { + operationGroup[i].gas_limit = estimate.operationResources[i].gas.toString(); + operationGroup[i].storage_limit = estimate.operationResources[i].storageCost.toString(); + } + } + + return operationGroup; + } + /** * This function checks if the server response contains an error. There are multiple formats for errors coming * back from the server, this method attempts to normalized them for downstream parsing. @@ -734,8 +876,17 @@ export namespace TezosNodeWriter { const arr = Array.isArray(json) ? json : [json]; if ('kind' in arr[0]) { - // TODO: show counter errors better: e.msg "already used for contract" - errors = arr.map(e => `(${e.kind}: ${e.id})`).join(', '); + errors = arr.map(e => { + if (e.msg) { + if (counterMatcher.test(e.msg)) { + return `(${e.kind}: ${e.id}, counter already used)`; + } + + return `(${e.kind}: ${e.id}, ${e.msg})`; + } + + return `(${e.kind}: ${e.id})`; + }).join(', '); } else if (arr.length === 1 && arr[0].contents.length === 1 && arr[0].contents[0].kind === 'activate_account') { // in CARTHAGE and prior protocols activation failures are caught in the first branch } else { @@ -773,12 +924,18 @@ export namespace TezosNodeWriter { * Processes `operation_result` and `internal_operation_results` objects from the RPC responses into an error string. */ function parseRPCOperationResult(result: any): string { - if (result.status === 'failed') { - return `${result.status}: ${result.errors.map(e => `(${e.kind}: ${e.id})`).join(', ')}`; - } else if (result.status === 'applied') { - return ''; - } else { // backtracked, skipped - return result.status; + if (result.status !== 'applied') { // backtracked, skipped, failed + let error = result.status; + if (result.errors && result.errors.length > 0) { + try { + error += result.errors.map(e => `(${e.kind}: ${e.id})`).join(', '); + } catch { + log.error(`failed to parse errors from '${result}'\n, PLEASE report this to the maintainers`); + } + } + return error; } + + return ''; // applied } } diff --git a/src/chain/tezos/contracts/BabylonDelegationHelper.ts b/src/chain/tezos/contracts/BabylonDelegationHelper.ts index 3e90933e..cd468631 100644 --- a/src/chain/tezos/contracts/BabylonDelegationHelper.ts +++ b/src/chain/tezos/contracts/BabylonDelegationHelper.ts @@ -125,7 +125,7 @@ export namespace BabylonDelegationHelper { return TezosNodeWriter.sendContractInvocationOperation(server, signer, keyStore, contract, amount, fee, 0, TezosConstants.P005ManagerContractDepositGasLimit, undefined, undefined); } - export function deployManagerContract(server: string, signer: Signer, keyStore: KeyStore, delegate: string, fee: number, amount: number): Promise { + export function deployManagerContract(server: string, signer: Signer, keyStore: KeyStore, delegate: string, fee: number, amount: number, optimizeFee = false): Promise { const code = `[ { "prim": "parameter", "args": [ { "prim": "or", @@ -159,6 +159,6 @@ export namespace BabylonDelegationHelper { { "prim": "PAIR" } ] ] } ] ] } ]`; const storage = `{ "string": "${keyStore.publicKeyHash}" }`; - return TezosNodeWriter.sendContractOriginationOperation(server, signer, keyStore, amount, delegate, fee, 600, 20000, code, storage, TezosTypes.TezosParameterFormat.Micheline); + return TezosNodeWriter.sendContractOriginationOperation(server, signer, keyStore, amount, delegate, fee, 600, 20000, code, storage, TezosTypes.TezosParameterFormat.Micheline, TezosConstants.HeadBranchOffset, optimizeFee); } } diff --git a/src/chain/tezos/contracts/KolibriTokenHelper.ts b/src/chain/tezos/contracts/KolibriTokenHelper.ts new file mode 100644 index 00000000..ed30100c --- /dev/null +++ b/src/chain/tezos/contracts/KolibriTokenHelper.ts @@ -0,0 +1,141 @@ +import { JSONPath } from 'jsonpath-plus'; + +import { KeyStore, Signer } from '../../../types/ExternalInterfaces'; +import * as TezosTypes from '../../../types/tezos/TezosChainTypes'; +import { TezosConstants } from '../../../types/tezos/TezosConstants'; +import { TezosMessageUtils } from '../TezosMessageUtil'; +import { TezosNodeReader } from '../TezosNodeReader'; +import { TezosNodeWriter } from '../TezosNodeWriter'; +import { TezosContractUtils } from './TezosContractUtils'; + +/** + * + */ +export namespace KolibriTokenHelper { + /** + * Gets the contract code at the specified address at the head block and compares it to the known hash of the code. This function processes Micheline format contracts. + * + * + * @param server Destination Tezos node. + * @param address Contract address to query. + */ + export async function verifyDestination(server: string, address: string): Promise { + return TezosContractUtils.verifyDestination(server, address, '0e3e137841a959521324b4ce20ca2df7'); + } + + /** + * In contrast to verifyDestination, this function uses compares Michelson hashes. + * + * @param script + */ + export function verifyScript(script: string): boolean { + return TezosContractUtils.verifyScript(script, 'b77ada691b1d630622bea243696c84d7'); + } + + export async function getAccountBalance(server: string, mapid: number, account: string): Promise { + const packedKey = TezosMessageUtils.encodeBigMapKey(Buffer.from(TezosMessageUtils.writePackedData(account, 'address'), 'hex')); + const mapResult = await TezosNodeReader.getValueForBigMapKey(server, mapid, packedKey); + + if (mapResult === undefined) { throw new Error(`Map ${mapid} does not contain a record for ${account}`); } + + const jsonresult = JSONPath({ path: '$.args[1].int', json: mapResult }); + return Number(jsonresult[0]); + } + + export async function getAccountAllowance(server: string, mapid: number, account: string, source: string) { + const packedKey = TezosMessageUtils.encodeBigMapKey(Buffer.from(TezosMessageUtils.writePackedData(source, 'address'), 'hex')); + const mapResult = await TezosNodeReader.getValueForBigMapKey(server, mapid, packedKey); + + if (mapResult === undefined) { throw new Error(`Map ${mapid} does not contain a record for ${source}/${account}`); } + + let allowances = new Map(); + JSONPath({ path: '$.args[1][*].args', json: mapResult }).forEach(v => allowances[v[0]['string']] = Number(v[1]['int'])); + + return allowances[account]; + } + + export async function getSimpleStorage(server: string, address: string): Promise<{mapid: number, supply: number, administrator: string, paused: boolean}> { + const storageResult = await TezosNodeReader.getContractStorage(server, address); + + return { + mapid: Number(JSONPath({ path: '$.args[0].args[0].args[1].int', json: storageResult })[0]), + supply: Number(JSONPath({ path: '$.args[3].int', json: storageResult })[0]), + administrator: JSONPath({ path: '$.args[0].args[0].args[0].string', json: storageResult })[0], + paused: (JSONPath({ path: '$.args[1].args[1].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t') + }; + } + + export async function getTokenSupply(server: string, address: string): Promise { + const storageResult = await TezosNodeReader.getContractStorage(server, address); + + return Number(JSONPath({ path: '$.args[3].int', json: storageResult })[0]); + } + + export async function getAdministrator(server: string, address: string): Promise { + const storageResult = await TezosNodeReader.getContractStorage(server, address); + + return JSONPath({ path: '$.args[1].string', json: storageResult })[0]; + } + + export async function getPaused(server: string, address: string): Promise { + const storageResult = await TezosNodeReader.getContractStorage(server, address); + + return (JSONPath({ path: '$.args[2].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t'); + } + + export async function transferBalance(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, source: string, destination: string, amount: number, gas: number, freight: number) { + const parameters = `(Left (Left (Left (Pair "${source}" (Pair "${destination}" ${amount})))))`; + + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); + + return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); + } + + export async function approveBalance(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, destination: string, amount: number, gas: number, freight: number) { + const parameters = `(Left (Left (Right (Pair "${destination}" ${amount}))))`; + + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); + + return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); + } + + export async function activateLedger(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, gas: number, freight: number) { + const parameters = '(Right (Left (Left False)))'; + + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); + + return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); + } + + export async function deactivateLedger(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, gas: number, freight: number) { + const parameters = '(Right (Left (Left True)))'; + + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); + + return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); + } + + export async function setAdministrator(server: string, signer: Signer, keystore: KeyStore, contract: string, address: string, fee: number, gas: number, freight: number) { + const parameters = `(Right (Left (Right "${address}")))`; + + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); + + return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); + } + + export async function mint(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, destination: string, amount: number, gas: number = 150_000, freight: number = 5_000) { + const parameters = `(Right (Right (Right (Left (Pair "${destination}" ${amount})))))`; + + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); + + return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); + } + + export async function burn(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, source: string, amount: number, gas: number, freight: number) { + const parameters = `(Right (Right (Right (Right (Pair "${source}" ${amount})))))`; + + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); + + return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); + } +} diff --git a/src/chain/tezos/contracts/StakerDAOTokenHelper.ts b/src/chain/tezos/contracts/StakerDAOTokenHelper.ts index 025b3261..21327183 100644 --- a/src/chain/tezos/contracts/StakerDAOTokenHelper.ts +++ b/src/chain/tezos/contracts/StakerDAOTokenHelper.ts @@ -49,12 +49,12 @@ export namespace StakerDAOTokenHelper { const storageResult = await TezosNodeReader.getContractStorage(server, address); return { - mapid: Number(JSONPath({ path: '$.args[1].args[1].args[0].int', json: storageResult })[0]), - council: JSONPath({ path: '$.args[0].args[0].args[1]..string', json: storageResult }), - stage: Number(JSONPath({ path: '$.args[1].args[0].args[0].int', json: storageResult })[0]), - phase: Number(JSONPath({ path: '$.args[1].args[0].args[0].int', json: storageResult })[0]) % 4, - supply: Number(JSONPath({ path: '$.args[1].args[0].args[1].int', json: storageResult })[0]), - paused: (JSONPath({ path: '$.args[1].args[1].args[1].args[0].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t') + mapid: Number(JSONPath({ path: '$.args[2].int', json: storageResult })[0]), + council: JSONPath({ path: '$.args[0].args[0]..string', json: storageResult }), + stage: Number(JSONPath({ path: '$.args[1].args[0].int', json: storageResult })[0]), + phase: Number(JSONPath({ path: '$.args[1].args[0].int', json: storageResult })[0]) % 4, + supply: Number(JSONPath({ path: '$.args[1].args[1].int', json: storageResult })[0]), + paused: (JSONPath({ path: '$.args[3].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t') //policy //proposals //votes diff --git a/src/chain/tezos/contracts/StakerDaoTzip7.ts b/src/chain/tezos/contracts/StakerDaoTzip7.ts index 78619437..5c780c26 100644 --- a/src/chain/tezos/contracts/StakerDaoTzip7.ts +++ b/src/chain/tezos/contracts/StakerDaoTzip7.ts @@ -77,8 +77,6 @@ export const StakerDaoTzip7 = { getSimpleStorage: async function (server: string, address: string): Promise { const storageResult = await TezosNodeReader.getContractStorage(server, address); - console.log(JSON.stringify(storageResult)); - return { balanceMap: Number(JSONPath({ path: '$.args[1].args[0].args[1].args[0].int', json: storageResult })[0]), approvalsMap: Number(JSONPath({ path: '$.args[1].args[0].args[0].args[1].int', json: storageResult })[0]), diff --git a/src/chain/tezos/contracts/Tzip7ReferenceTokenHelper.ts b/src/chain/tezos/contracts/Tzip7ReferenceTokenHelper.ts index 1ef01185..0de94522 100644 --- a/src/chain/tezos/contracts/Tzip7ReferenceTokenHelper.ts +++ b/src/chain/tezos/contracts/Tzip7ReferenceTokenHelper.ts @@ -2,6 +2,7 @@ import { JSONPath } from 'jsonpath-plus'; import { KeyStore, Signer } from '../../../types/ExternalInterfaces'; import * as TezosTypes from '../../../types/tezos/TezosChainTypes'; +import { TezosConstants } from '../../../types/tezos/TezosConstants'; import { TezosMessageUtils } from '../TezosMessageUtil'; import { TezosNodeReader } from '../TezosNodeReader'; import { TezosNodeWriter } from '../TezosNodeWriter'; @@ -41,7 +42,7 @@ export namespace Tzip7ReferenceTokenHelper { code { CAST (pair (or (or (or (pair address (pair address nat)) (pair address nat)) (or (pair (pair address address) (contract nat)) (or (pair address (contract nat)) (pair unit (contract nat))))) (or (or bool address) (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) (pair (big_map address (pair nat (map address nat))) (pair address (pair bool nat)))); DUP; CAR; DIP { CDR }; IF_LEFT { IF_LEFT { IF_LEFT { DIP { DUP; CDR; CDR; CAR; IF { UNIT; PUSH string "TokenOperationsArePaused"; PAIR; FAILWITH } { } }; DUP; DUP; CDR; CAR; DIP { CAR }; COMPARE; EQ; IF { DROP } { DUP; CAR; SENDER; COMPARE; EQ; IF { } { DUP; DIP { DUP; DIP { DIP { DUP }; CAR; SENDER; PAIR; DUP; DIP { CDR; DIP { CAR }; GET; IF_NONE { EMPTY_MAP (address) nat } { CDR } }; CAR; GET; IF_NONE { PUSH nat 0 } { } }; DUP; CAR; DIP { SENDER; DIP { DUP; CDR; CDR; DIP { DIP { DUP }; SWAP }; SWAP; SUB; ISNAT; IF_NONE { DIP { DUP }; SWAP; DIP { DUP }; SWAP; CDR; CDR; PAIR; PUSH string "NotEnoughAllowance"; PAIR; FAILWITH } { } }; PAIR }; PAIR; DIP { DROP; DROP }; DIP { DUP }; SWAP; DIP { DUP; CAR }; SWAP; DIP { CAR }; GET; IF_NONE { PUSH nat 0; DIP { EMPTY_MAP (address) nat }; PAIR; EMPTY_MAP (address) nat } { DUP; CDR }; DIP { DIP { DUP }; SWAP }; SWAP; CDR; CDR; DUP; INT; EQ; IF { DROP; NONE nat } { SOME }; DIP { DIP { DIP { DUP }; SWAP }; SWAP }; SWAP; CDR; CAR; UPDATE; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR; SWAP; CAR; DIP { SOME }; DIP { DIP { DUP; CAR } }; UPDATE; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR } }; DIP { DUP }; SWAP; DIP { DUP }; SWAP; CDR; CAR; DIP { CAR }; GET; IF_NONE { DUP; CDR; CDR; INT; EQ; IF { NONE (pair nat (map address nat)) } { DUP; CDR; CDR; DIP { EMPTY_MAP (address) nat }; PAIR; SOME } } { DIP { DUP }; SWAP; CDR; CDR; DIP { DUP; CAR }; ADD; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR; SOME }; SWAP; DUP; DIP { CDR; CAR; DIP { DIP { DUP; CAR } }; UPDATE; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR }; DUP; DIP { CDR; CDR; INT; DIP { DUP; CDR; CDR; CDR }; ADD; ISNAT; IF_NONE { PUSH string "Internal: Negative total supply"; FAILWITH } { }; DIP { DUP; CDR }; DIP { DUP; DIP { CAR }; CDR }; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR; SWAP; PAIR; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR }; DIP { DUP }; SWAP; DIP { DUP }; SWAP; CAR; DIP { CAR }; GET; IF_NONE { CDR; CDR; PUSH nat 0; SWAP; PAIR; PUSH string "NotEnoughBalance"; PAIR; FAILWITH } { }; DUP; CAR; DIP { DIP { DUP }; SWAP }; SWAP; CDR; CDR; SWAP; SUB; ISNAT; IF_NONE { CAR; DIP { DUP }; SWAP; CDR; CDR; PAIR; PUSH string "NotEnoughBalance"; PAIR; FAILWITH } { }; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR; DIP { DUP }; SWAP; DIP { DUP; CAR; INT; EQ; IF { DUP; CDR; SIZE; INT; EQ; IF { DROP; NONE (pair nat (map address nat)) } { SOME } } { SOME }; SWAP; CAR; DIP { DIP { DUP; CAR } }; UPDATE; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR }; DUP; DIP { CDR; CDR; NEG; DIP { DUP; CDR; CDR; CDR }; ADD; ISNAT; IF_NONE { PUSH string "Internal: Negative total supply"; FAILWITH } { }; DIP { DUP; CDR }; DIP { DUP; DIP { CAR }; CDR }; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR; SWAP; PAIR; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR }; DROP }; NIL operation; PAIR } { SENDER; PAIR; DIP { DUP; CDR; CDR; CAR; IF { UNIT; PUSH string "TokenOperationsArePaused"; PAIR; FAILWITH } { } }; DIP { DUP }; SWAP; DIP { DUP }; SWAP; DUP; DIP { CAR; DIP { CAR }; GET; IF_NONE { EMPTY_MAP (address) nat } { CDR } }; CDR; CAR; GET; IF_NONE { PUSH nat 0 } { }; DUP; INT; EQ; IF { DROP } { DIP { DUP }; SWAP; CDR; CDR; INT; EQ; IF { DROP } { PUSH string "UnsafeAllowanceChange"; PAIR; FAILWITH } }; DIP { DUP }; SWAP; DIP { DUP; CAR }; SWAP; DIP { CAR }; GET; IF_NONE { PUSH nat 0; DIP { EMPTY_MAP (address) nat }; PAIR; EMPTY_MAP (address) nat } { DUP; CDR }; DIP { DIP { DUP }; SWAP }; SWAP; CDR; CDR; DUP; INT; EQ; IF { DROP; NONE nat } { SOME }; DIP { DIP { DIP { DUP }; SWAP }; SWAP }; SWAP; CDR; CAR; UPDATE; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR; SWAP; CAR; DIP { SOME }; DIP { DIP { DUP; CAR } }; UPDATE; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR; NIL operation; PAIR } } { IF_LEFT { DUP; CAR; DIP { CDR }; DIP { DIP { DUP }; SWAP }; PAIR; DUP; CAR; DIP { CDR }; DUP; DIP { CAR; DIP { CAR }; GET; IF_NONE { EMPTY_MAP (address) nat } { CDR } }; CDR; GET; IF_NONE { PUSH nat 0 } { }; DIP { AMOUNT }; TRANSFER_TOKENS; NIL operation; SWAP; CONS; PAIR } { IF_LEFT { DUP; CAR; DIP { CDR }; DIP { DIP { DUP }; SWAP }; PAIR; DUP; CAR; DIP { CDR }; DIP { CAR }; GET; IF_NONE { PUSH nat 0 } { CAR }; DIP { AMOUNT }; TRANSFER_TOKENS; NIL operation; SWAP; CONS; PAIR } { DUP; CAR; DIP { CDR }; DIP { DIP { DUP }; SWAP }; PAIR; CDR; CDR; CDR; CDR; DIP { AMOUNT }; TRANSFER_TOKENS; NIL operation; SWAP; CONS; PAIR } } } } { IF_LEFT { IF_LEFT { DIP { DUP; CDR; CAR; SENDER; COMPARE; EQ; IF { } { UNIT; PUSH string "SenderIsNotAdmin"; PAIR; FAILWITH } }; DIP { DUP; CDR }; DIP { DUP; DIP { CAR }; CDR }; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR; SWAP; PAIR; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR; NIL operation; PAIR } { DIP { DUP; CDR; CAR; SENDER; COMPARE; EQ; IF { } { UNIT; PUSH string "SenderIsNotAdmin"; PAIR; FAILWITH } }; DIP { DUP; CDR }; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR; NIL operation; PAIR } } { IF_LEFT { DUP; CAR; DIP { CDR }; DIP { DIP { DUP }; SWAP }; PAIR; CDR; CDR; CAR; DIP { AMOUNT }; TRANSFER_TOKENS; NIL operation; SWAP; CONS; PAIR } { IF_LEFT { DIP { DUP; CDR; CAR; SENDER; COMPARE; EQ; IF { } { UNIT; PUSH string "SenderIsNotAdmin"; PAIR; FAILWITH } }; DIP { DUP }; SWAP; DIP { DUP }; SWAP; CAR; DIP { CAR }; GET; IF_NONE { DUP; CDR; INT; EQ; IF { NONE (pair nat (map address nat)) } { DUP; CDR; DIP { EMPTY_MAP (address) nat }; PAIR; SOME } } { DIP { DUP }; SWAP; CDR; DIP { DUP; CAR }; ADD; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR; SOME }; SWAP; DUP; DIP { CAR; DIP { DIP { DUP; CAR } }; UPDATE; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR }; DUP; DIP { CDR; INT; DIP { DUP; CDR; CDR; CDR }; ADD; ISNAT; IF_NONE { PUSH string "Internal: Negative total supply"; FAILWITH } { }; DIP { DUP; CDR }; DIP { DUP; DIP { CAR }; CDR }; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR; SWAP; PAIR; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR }; DROP; NIL operation; PAIR } { DIP { DUP; CDR; CAR; SENDER; COMPARE; EQ; IF { } { UNIT; PUSH string "SenderIsNotAdmin"; PAIR; FAILWITH } }; DIP { DUP }; SWAP; DIP { DUP }; SWAP; CAR; DIP { CAR }; GET; IF_NONE { CDR; PUSH nat 0; SWAP; PAIR; PUSH string "NotEnoughBalance"; PAIR; FAILWITH } { }; DUP; CAR; DIP { DIP { DUP }; SWAP }; SWAP; CDR; SWAP; SUB; ISNAT; IF_NONE { CAR; DIP { DUP }; SWAP; CDR; PAIR; PUSH string "NotEnoughBalance"; PAIR; FAILWITH } { }; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR; DIP { DUP }; SWAP; DIP { DUP; CAR; INT; EQ; IF { DUP; CDR; SIZE; INT; EQ; IF { DROP; NONE (pair nat (map address nat)) } { SOME } } { SOME }; SWAP; CAR; DIP { DIP { DUP; CAR } }; UPDATE; DIP { DUP; DIP { CDR }; CAR }; DIP { DROP }; PAIR }; DUP; DIP { CDR; NEG; DIP { DUP; CDR; CDR; CDR }; ADD; ISNAT; IF_NONE { PUSH string "Internal: Negative total supply"; FAILWITH } { }; DIP { DUP; CDR }; DIP { DUP; DIP { CAR }; CDR }; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR; SWAP; PAIR; DIP { DUP; DIP { CAR }; CDR }; DIP { DROP }; SWAP; PAIR }; DROP; NIL operation; PAIR } } } } };`; const storage = `Pair {} (Pair "${administrator}" (Pair ${pause ? 'True' : 'False'} ${supply}))`; - const nodeResult = await TezosNodeWriter.sendContractOriginationOperation(server, signer, keystore, 0, undefined, fee, freight, gas, contract, storage, TezosTypes.TezosParameterFormat.Michelson); + const nodeResult = await TezosNodeWriter.sendContractOriginationOperation(server, signer, keystore, 0, undefined, fee, freight, gas, contract, storage, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); return TezosContractUtils.clearRPCOperationGroupHash(nodeResult['operationGroupID']); } @@ -72,34 +73,34 @@ export namespace Tzip7ReferenceTokenHelper { return { mapid: Number(JSONPath({ path: '$.args[0].int', json: storageResult })[0]), - supply: Number(JSONPath({ path: '$.args[1].args[1].args[1].int', json: storageResult })[0]), - administrator: JSONPath({ path: '$.args[1].args[0].string', json: storageResult })[0], - paused: (JSONPath({ path: '$.args[1].args[1].args[0].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t') + supply: Number(JSONPath({ path: '$.args[3].int', json: storageResult })[0]), + administrator: JSONPath({ path: '$.args[1].string', json: storageResult })[0], + paused: (JSONPath({ path: '$.args[2].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t') }; } export async function getTokenSupply(server: string, address: string): Promise { const storageResult = await TezosNodeReader.getContractStorage(server, address); - return Number(JSONPath({ path: '$.args[1].args[1].args[1].int', json: storageResult })[0]); + return Number(JSONPath({ path: '$.args[3].int', json: storageResult })[0]); } export async function getAdministrator(server: string, address: string): Promise { const storageResult = await TezosNodeReader.getContractStorage(server, address); - return JSONPath({ path: '$.args[1].args[0].string', json: storageResult })[0]; + return JSONPath({ path: '$.args[1].string', json: storageResult })[0]; } export async function getPaused(server: string, address: string): Promise { const storageResult = await TezosNodeReader.getContractStorage(server, address); - return (JSONPath({ path: '$.args[1].args[1].args[0].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t'); + return (JSONPath({ path: '$.args[2].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t'); } export async function transferBalance(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, source: string, destination: string, amount: number, gas: number, freight: number) { const parameters = `(Left (Left (Left (Pair "${source}" (Pair "${destination}" ${amount})))))`; - const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson); + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); } @@ -107,7 +108,7 @@ export namespace Tzip7ReferenceTokenHelper { export async function approveBalance(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, destination: string, amount: number, gas: number, freight: number) { const parameters = `(Left (Left (Right (Pair "${destination}" ${amount}))))`; - const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson); + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); } @@ -115,7 +116,7 @@ export namespace Tzip7ReferenceTokenHelper { export async function activateLedger(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, gas: number, freight: number) { const parameters = '(Right (Left (Left False)))'; - const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson); + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); } @@ -123,7 +124,7 @@ export namespace Tzip7ReferenceTokenHelper { export async function deactivateLedger(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, gas: number, freight: number) { const parameters = '(Right (Left (Left True)))'; - const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson); + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); } @@ -131,7 +132,7 @@ export namespace Tzip7ReferenceTokenHelper { export async function setAdministrator(server: string, signer: Signer, keystore: KeyStore, contract: string, address: string, fee: number, gas: number, freight: number) { const parameters = `(Right (Left (Right "${address}")))`; - const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson); + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); } @@ -139,7 +140,7 @@ export namespace Tzip7ReferenceTokenHelper { export async function mint(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, destination: string, amount: number, gas: number = 150_000, freight: number = 5_000) { const parameters = `(Right (Right (Right (Left (Pair "${destination}" ${amount})))))`; - const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson); + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); } @@ -147,7 +148,7 @@ export namespace Tzip7ReferenceTokenHelper { export async function burn(server: string, signer: Signer, keystore: KeyStore, contract: string, fee: number, source: string, amount: number, gas: number, freight: number) { const parameters = `(Right (Right (Right (Right (Pair "${source}" ${amount})))))`; - const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson); + const nodeResult = await TezosNodeWriter.sendContractInvocationOperation(server, signer, keystore, contract, 0, fee, freight, gas, '', parameters, TezosTypes.TezosParameterFormat.Michelson, TezosConstants.HeadBranchOffset, true); return TezosContractUtils.clearRPCOperationGroupHash(nodeResult.operationGroupID); } diff --git a/src/chain/tezos/contracts/WrappedTezosHelper.ts b/src/chain/tezos/contracts/WrappedTezosHelper.ts index f340b544..2db10453 100644 --- a/src/chain/tezos/contracts/WrappedTezosHelper.ts +++ b/src/chain/tezos/contracts/WrappedTezosHelper.ts @@ -136,16 +136,14 @@ export namespace WrappedTezosHelper { export async function getSimpleStorage(server: string, address: string): Promise { const storageResult = await TezosNodeReader.getContractStorage(server, address); - console.log(JSON.stringify(storageResult)); - return { - balanceMap: Number(JSONPath({ path: '$.args[1].args[0].args[1].args[0].int', json: storageResult })[0]), - approvalsMap: Number(JSONPath({ path: '$.args[1].args[0].args[0].args[1].int', json: storageResult })[0]), - supply: Number(JSONPath({ path: '$.args[1].args[1].args[1].int', json: storageResult })[0]), - administrator: JSONPath({ path: '$.args[1].args[0].args[0].args[0].string', json: storageResult })[0], - paused: (JSONPath({ path: '$.args[1].args[1].args[0].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t'), - pauseGuardian: JSONPath({ path: '$.args[1].args[0].args[1].args[1].string', json: storageResult })[0], - outcomeMap: Number(JSONPath({ path: '$.args[0].args[0].int', json: storageResult })[0]), + balanceMap: Number(JSONPath({ path: '$.args[1].args[1].int', json: storageResult })[0]), + approvalsMap: Number(JSONPath({ path: '$.args[1].args[0].args[1].int', json: storageResult })[0]), + supply: Number(JSONPath({ path: '$.args[3].int', json: storageResult })[0]), + administrator: JSONPath({ path: '$.args[1].args[0].args[0].string', json: storageResult })[0], + paused: (JSONPath({ path: '$.args[2].prim', json: storageResult })[0]).toString().toLowerCase().startsWith('t'), + pauseGuardian: JSONPath({ path: '$.args[1].args[2].string', json: storageResult })[0], + outcomeMap: Number(JSONPath({ path: '$.args[0].args[0].args[1].int', json: storageResult })[0]), swapMap: Number(JSONPath({ path: '$.args[0].args[1].int', json: storageResult })[0]) }; } diff --git a/src/chain/tezos/lexer/Micheline.ts b/src/chain/tezos/lexer/Micheline.ts index 02fcc7aa..634832e8 100644 --- a/src/chain/tezos/lexer/Micheline.ts +++ b/src/chain/tezos/lexer/Micheline.ts @@ -12,8 +12,8 @@ declare var comma: any; declare var lbracket: any; declare var rbracket: any; -const moo = require("moo"); -const bigInt = require("big-integer"); +import { TezosMessageUtils } from '../TezosMessageUtil'; +import * as moo from 'moo'; // https://gitlab.com/tezos/tezos/-/blob/master/src/proto_008_PtEdoTez/lib_protocol/michelson_v1_primitives.ml#L1088 export const DefaultMichelsonKeywords = ['"parameter"', '"storage"', '"code"', '"False"', '"Elt"', '"Left"', '"None"', '"Pair"', '"Right"', '"Some"', '"True"', '"Unit"', '"PACK"', '"UNPACK"', '"BLAKE2B"', '"SHA256"', '"SHA512"', '"ABS"', '"ADD"', '"AMOUNT"', '"AND"', '"BALANCE"', '"CAR"', '"CDR"', '"CHECK_SIGNATURE"', '"COMPARE"', '"CONCAT"', '"CONS"', '"CREATE_ACCOUNT"', '"CREATE_CONTRACT"', '"IMPLICIT_ACCOUNT"', '"DIP"', '"DROP"', '"DUP"', '"EDIV"', '"EMPTY_MAP"', '"EMPTY_SET"', '"EQ"', '"EXEC"', '"FAILWITH"', '"GE"', '"GET"', '"GT"', '"HASH_KEY"', '"IF"', '"IF_CONS"', '"IF_LEFT"', '"IF_NONE"', '"INT"', '"LAMBDA"', '"LE"', '"LEFT"', '"LOOP"', '"LSL"', '"LSR"', '"LT"', '"MAP"', '"MEM"', '"MUL"', '"NEG"', '"NEQ"', '"NIL"', '"NONE"', '"NOT"', '"NOW"', '"OR"', '"PAIR"', '"PUSH"', '"RIGHT"', '"SIZE"', '"SOME"', '"SOURCE"', '"SENDER"', '"SELF"', '"STEPS_TO_QUOTA"', '"SUB"', '"SWAP"', '"TRANSFER_TOKENS"', '"SET_DELEGATE"', '"UNIT"', '"UPDATE"', '"XOR"', '"ITER"', '"LOOP_LEFT"', '"ADDRESS"', '"CONTRACT"', '"ISNAT"', '"CAST"', '"RENAME"', '"bool"', '"contract"', '"int"', '"key"', '"key_hash"', '"lambda"', '"list"', '"map"', '"big_map"', '"nat"', '"option"', '"or"', '"pair"', '"set"', '"signature"', '"string"', '"bytes"', '"mutez"', '"timestamp"', '"unit"', '"operation"', '"address"', '"SLICE"', '"DIG"', '"DUG"', '"EMPTY_BIG_MAP"', '"APPLY"', '"chain_id"', '"CHAIN_ID"', '"LEVEL"', '"SELF_ADDRESS"', '"never"', '"NEVER"', '"UNPAIR"', '"VOTING_POWER"', '"TOTAL_VOTING_POWER"', '"KECCAK"', '"SHA3"', '"PAIRING_CHECK"', '"bls12_381_g1"', '"bls12_381_g2"', '"bls12_381_fr"', '"sapling_state"', '"sapling_transaction"', '"SAPLING_EMPTY_STATE"', '"SAPLING_VERIFY_UPDATE"', '"ticket"', '"TICKET"', '"READ_TICKET"', '"SPLIT_TICKET"', '"JOIN_TICKETS"', '"GET_AND_UPDATE"']; @@ -50,7 +50,7 @@ const lexer = moo.compile({ const staticIntToHex = d => { const prefix = '00'; const text = d[6].toString(); - const value = writeSignedInt(parseInt(text.substring(1, text.length - 1))); // strip double quotes + const value = TezosMessageUtils.writeSignedInt(text.substring(1, text.length - 1)); // strip double quotes return prefix + value; }; @@ -186,38 +186,6 @@ const encodeLength = l => { return ('0000000' + l.toString(16)).slice(-8); } -const writeSignedInt = value => { - if (value === 0) { return '00'; } - - const n = bigInt(value).abs(); - const l = n.bitLength().toJSNumber(); - let arr: any = []; - let v = n; - for (let i = 0; i < l; i += 7) { - let byte = bigInt.zero; - - if (i === 0) { - byte = v.and(0x3f); // first byte makes room for sign flag - v = v.shiftRight(6); - } else { - byte = v.and(0x7f); // NOT base128 encoded - v = v.shiftRight(7); - } - - if (value < 0 && i === 0) { byte = byte.or(0x40); } // set sign flag - - if (i + 7 < l) { byte = byte.or(0x80); } // set next byte flag - arr.push(byte.toJSNumber()); - } - - if (l % 7 === 0) { - arr[arr.length - 1] = arr[arr.length - 1] | 0x80; - arr.push(1); - } - - return arr.map(v => ('0' + v.toString(16)).slice(-2)).join(''); - } - interface NearleyToken { value: any; [key: string]: any; }; diff --git a/src/index-web.ts b/src/index-web.ts index 05195d17..c2ead30e 100644 --- a/src/index-web.ts +++ b/src/index-web.ts @@ -13,6 +13,7 @@ export * from './chain/tezos/contracts/TezosContractUtils'; export * from './chain/tezos/contracts/BabylonDelegationHelper'; export * from './chain/tezos/contracts/CryptonomicNameServiceHelper'; export * from './chain/tezos/contracts/DexterPoolHelper'; +export * from './chain/tezos/contracts/KolibriTokenHelper'; export * from './chain/tezos/contracts/MurbardMultisigHelper'; export * from './chain/tezos/contracts/StakerDAOTokenHelper'; export * from './chain/tezos/contracts/TCFBakerRegistryHelper'; diff --git a/src/index.ts b/src/index.ts index f5434722..b56bcd78 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,7 @@ export * from './chain/tezos/contracts/TezosContractUtils'; export * from './chain/tezos/contracts/BabylonDelegationHelper'; export * from './chain/tezos/contracts/CryptonomicNameServiceHelper'; export * from './chain/tezos/contracts/DexterPoolHelper'; +export * from './chain/tezos/contracts/KolibriTokenHelper'; export * from './chain/tezos/contracts/MurbardMultisigHelper'; export * from './chain/tezos/contracts/StakerDAOTokenHelper'; export * from './chain/tezos/contracts/TCFBakerRegistryHelper'; diff --git a/src/reporting/tezos/TezosConseilClient.ts b/src/reporting/tezos/TezosConseilClient.ts index 6a963595..f4fccd4c 100644 --- a/src/reporting/tezos/TezosConseilClient.ts +++ b/src/reporting/tezos/TezosConseilClient.ts @@ -1,4 +1,4 @@ -import { ConseilQuery, ConseilOperator, ConseilServerInfo, ConseilSortDirection } from "../../types/conseil/QueryTypes" +import { ConseilQuery, ConseilOperator, ConseilServerInfo, ConseilSortDirection, ConseilFunction } from "../../types/conseil/QueryTypes" import { OperationKindType } from "../../types/tezos/TezosChainTypes"; import { ContractMapDetails, ContractMapDetailsItem } from '../../types/conseil/ConseilTezosTypes'; import LogSelector from '../../utils/LoggerSelector'; @@ -423,4 +423,19 @@ export namespace TezosConseilClient { throw new Error('Invalid id parameter'); } + + export async function countKeysInMap(serverInfo: ConseilServerInfo, mapIndex: number): Promise { + let countQuery = ConseilQueryBuilder.blankQuery(); + countQuery = ConseilQueryBuilder.addFields(countQuery, 'key'); + countQuery = ConseilQueryBuilder.addPredicate(countQuery, 'big_map_id', ConseilOperator.EQ, [mapIndex]); + countQuery = ConseilQueryBuilder.addAggregationFunction(countQuery, 'key', ConseilFunction.count); + countQuery = ConseilQueryBuilder.setLimit(countQuery, 1); + const result = await ConseilDataClient.executeEntityQuery(serverInfo, 'tezos', serverInfo.network, 'big_map_contents', countQuery); + + try { + return result[0]['count_key']; + } catch { + return -1; + } + } } diff --git a/src/types/tezos/TezosConstants.ts b/src/types/tezos/TezosConstants.ts index d1d6098e..8b1d1be1 100644 --- a/src/types/tezos/TezosConstants.ts +++ b/src/types/tezos/TezosConstants.ts @@ -1,17 +1,66 @@ +/** + * Various constants for the Tezos platforms. Fees are expressed in µtz unless otherwise noted, storage unit is bytes. + */ export namespace TezosConstants { export const OperationGroupWatermark = '03'; - export const DefaultTransactionStorageLimit = 496; // 300 + + export const DefaultSimpleTransactionFee = 1420; + export const DefaultTransactionStorageLimit = 496; export const DefaultTransactionGasLimit = 10600; + + export const DefaultDelegationFee = 1258; export const DefaultDelegationStorageLimit = 0; - export const DefaultDelegationGasLimit = 1101; + export const DefaultDelegationGasLimit = 1100; + + /** + * Legacy constants for pre-P005 KT1 delegation account origination. Will be removed in a future release. + * + * @deprecated + */ + export const DefaultAccountOriginationFee = 1266; + /** + * Legacy constants for pre-P005 KT1 delegation account origination. Will be removed in a future release. + * + * @deprecated + */ export const DefaultAccountOriginationStorageLimit = 496; // 277 + /** + * Legacy constants for pre-P005 KT1 delegation account origination. Will be removed in a future release. + * + * @deprecated + */ export const DefaultAccountOriginationGasLimit = 10600; - export const DefaultAccountOriginationFee = 1266; + export const DefaultKeyRevealFee = 1270; - export const DefaultDelegationFee = 1258; + export const DefaultKeyRevealStorageLimit = 0; + export const DefaultKeyRevealGasLimit = 1100; + export const P005ManagerContractWithdrawalGasLimit = 26283; export const P005ManagerContractDepositGasLimit = 15285; - export const P005ManagerContractWithdrawalStorageLimit = 496; // 300 + export const P005ManagerContractWithdrawalStorageLimit = 496; + + export const P001StorageRate = 1_000_000 / 1000; + export const P007StorageRate = 250_000 / 1000; + export const StorageRate = P007StorageRate; + + export const BaseOperationFee = 100; + + export const P007OperationGasCap = 1_040_000; + export const OperationGasCap = P007OperationGasCap; + + export const OperationStorageCap = 60_000; + + export const EmptyAccountStorageBurn = 257; + + export const DefaultBakerVig = 100; + + export const GasLimitPadding = 100; + export const StorageLimitPadding = 20; + + /** + * + */ + export const HeadBranchOffset = 54; /** * Outbound operation queue timeout in seconds. After this period, TezosOperationQueue will attempt to submit the transactions currently in queue. diff --git a/test/chain/tezos/TezosContractIntrospector.spec.ts b/test/chain/tezos/TezosContractIntrospector.spec.ts index 0e6a7a1f..c19cfdf0 100644 --- a/test/chain/tezos/TezosContractIntrospector.spec.ts +++ b/test/chain/tezos/TezosContractIntrospector.spec.ts @@ -23,7 +23,7 @@ describe("TezosContractIntrospector test", () => { registerFetch(fetch); })); - it('getAccountForBlock test', mochaAsync(async () => { + it('default/string test', mochaAsync(async () => { const server = nock(serverConfig.url); server .filteringRequestBody(body => '*') diff --git a/test/chain/tezos/TezosLanguageUtil.spec.ts b/test/chain/tezos/TezosLanguageUtil.spec.ts index 0b1804ce..e226dab9 100644 --- a/test/chain/tezos/TezosLanguageUtil.spec.ts +++ b/test/chain/tezos/TezosLanguageUtil.spec.ts @@ -303,6 +303,80 @@ describe("Tezos Michelson/Micheline fragment codec", () => { let result = TezosLanguageUtil.translateMichelineToHex(params); expect(result).to.equal('010000000568656c6c6f'); }); + + it('Normalize Michelson JSON primitive record', () => { + let input = { + "prim": "parameter", + "args": [ + { + "prim": "list", + "args": [ + { + "prim": "pair", + "args": [ + { + "prim": "sapling_transaction", + "annots": ["%transaction"], + "args": [ + { + "int":"8" + } + ], + }, + { + "prim": "option", + "annots": ["%key"], + "args": [ + { + "prim":"key_hash" + } + ], + } + ] + } + ] + } + ] + }; + let expectedOutput = { + "prim": "parameter", + "args": [ + { + "prim": "list", + "args": [ + { + "prim": "pair", + "args": [ + { + "prim": "sapling_transaction", + "args": [ + { + "int":"8" + } + ], + "annots": ["%transaction"], + }, + { + "prim": "option", + "args": [ + { + "prim":"key_hash" + } + ], + "annots": ["%key"], + } + ] + } + ] + } + ] + }; + + /** + * Ensure that { prim: ..., annots: ..., args: ... } is ordered to => { prim: ..., args: ..., annots: ... } + */ + expect(JSON.stringify(TezosLanguageUtil.normalizePrimitiveRecordOrder(input))).equal(JSON.stringify(expectedOutput)); + }); }); function preProcessMicheline(code: string): string[] { diff --git a/test/chain/tezos/TezosMessageCodec.spec.ts b/test/chain/tezos/TezosMessageCodec.spec.ts index 4ccc2d23..62c1e993 100644 --- a/test/chain/tezos/TezosMessageCodec.spec.ts +++ b/test/chain/tezos/TezosMessageCodec.spec.ts @@ -93,11 +93,29 @@ describe("Tezos P2P message decoder test suite", () => { expect(result).to.equal("6c00a8d45bdc966ddaaac83188a1e1c1fde2a3e05e5ca08d06c4e901b15b00904e01f61128c6abd2426d0c49b1fee1fa8c98dcc4ce0a0000"); }); + it("Dexter 2021Q1 tests", () => { + let transaction = { + kind: "transaction", + amount: "100000000", + destination: "KT1XTUGj7Rkgh6vLVDu91h81Xu2WGfyTxpqi", + parameters: { entrypoint: "xtzToToken", value: { "prim": "Pair", "args": [ { "string": "tz1RhnGx9hCxbrN8zKEKLbwU1zKLYZTqRs63" }, { "prim": "Pair", "args": [ { "int": "198180477354428686667" }, { "string": "2021-01-21T18:09:14.519Z" } ] } ] } }, + storage_limit: "0", + gas_limit: "11697", + counter: "29892", + fee: "100000", + source: "tz1RUGhq8sQpfGu1W2kf7MixqWX7oxThBFLr" + } + + + let result = TezosMessageCodec.encodeTransaction(transaction); + expect(result).to.equal("6c003ff84abc64319bda01968fd5269981d7615a6f75a08d06c4e901b15b0080c2d72f01fae98b912bb3644d56b8409cb98f40c779a9befe00ffff0a78747a546f546f6b656e0000005507070100000024747a3152686e47783968437862724e387a4b454b4c627755317a4b4c595a5471527336330707008b858b81c289bfcefc2a0100000018323032312d30312d32315431383a30393a31342e3531395a"); + }); + it("correctly encode a 'root' contract invocation", () => { // TODO }); - it("correctly encode a non-standard contract invocation", () => { + it('correctly encode a "non-standard" contract invocation', () => { // TODO }); @@ -107,7 +125,6 @@ describe("Tezos P2P message decoder test suite", () => { it("correctly parse a reveal (Athens)", () => { let forgedReveal = "97648f6470b21f904cb8d11eaf097f245eb42f5073fa51404d969cdfd4a4579e07000069ef8fb5d47d8a4321c94576a2316a632be8ce890094fe19904e00004c7b0501f6ea08f472b7e88791d3b8da49d64ac1e2c90f93c27e6531473305c6"; - //6b0034a00f9b7964943b4ab583a8d1f7241a0cb9742c00bac104904e0000e92113585804d494a642fb1aa6f0e6c33e5d54a2fe7f05f54de080f30662d554 const result = TezosMessageCodec.parseReveal(forgedReveal); expect(result.operation.kind).to.equal("reveal"); expect(result.operation.source).to.equal("tz1VJAdH2HRUZWfohXW59NPYQKFMe1csroaX"); @@ -159,6 +176,17 @@ describe("Tezos P2P message encoder test suite", () => { expect(result).to.equal("6d0069ef8fb5d47d8a4321c94576a2316a632be8ce89904e09924e914e934e000000003702000000320500035b0501035b0502020000002303160743035b00010312074303690a000000080123456789abcdef0320053d036d034200000002001e"); }); + it("correctly encode an activation operation", () => { + let activation: Activation = { + kind: "activate_account", + pkh: "tz1erMkoyqZBRvhuFoxHRnn8s7EpgTT63HHD", + secret: "912eb565c0194949644c4ef8888ad547aaf28154" + }; + + let result = TezosMessageCodec.encodeOperation(activation); + expect(result).to.equal("6d0069ef8fb5d47d8a4321c94576a2316a632be8ce89904e09924e914e934e000000003702000000320500035b0501035b0502020000002303160743035b00010312074303690a000000080123456789abcdef0320053d036d034200000002001e"); + }); + it("correctly encode a contract origination operation", () => { let origination: Origination = { kind: "origination", diff --git a/test/chain/tezos/TezosMessageUtil.spec.ts b/test/chain/tezos/TezosMessageUtil.spec.ts index 76b98611..eef321d6 100644 --- a/test/chain/tezos/TezosMessageUtil.spec.ts +++ b/test/chain/tezos/TezosMessageUtil.spec.ts @@ -53,7 +53,7 @@ describe('Tezos P2P message codec helper tests', () => { expect(result).to.equal('ff'); }); - it('test boolean read function', () => { + it('test readBoolean function', () => { let result = TezosMessageUtils.readBoolean('00'); expect(result).to.equal(false); @@ -61,7 +61,7 @@ describe('Tezos P2P message codec helper tests', () => { expect(result).to.equal(true); }); - it('test int read function', () => { + it('test readInt function', () => { let result = TezosMessageUtils.readInt('05'); expect(result).to.equal(5); @@ -87,6 +87,11 @@ describe('Tezos P2P message codec helper tests', () => { expect(result).to.equal(834152753920); }); + it('test readSignedInt function', () => { + let result = TezosMessageUtils.readSignedInt('8b858b81c289bfcefc2a'); + expect(result).to.equal(198180477354428686667); + }); + it('test writeInt function', () => { let result = TezosMessageUtils.writeInt(0); expect(result).to.equal('00'); @@ -125,7 +130,10 @@ describe('Tezos P2P message codec helper tests', () => { result = TezosMessageUtils.writeSignedInt(610913435200); expect(result).to.equal('80f9b9d4c723'); - }); + + result = TezosMessageUtils.writeSignedInt('198180477354428686667'); + expect(result).to.equal('8b858b81c289bfcefc2a'); + }); it('test findInt function', () => { let result = TezosMessageUtils.findInt('d3dade57fae2', 0);