diff --git a/README.md b/README.md index 6ef57533..75ca7497 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ __[tronweb.network](https://tronweb.network)__ - Version built for Node.js v6 and above - Version built for browsers with more than 0.25% market share -You can access either version specifically from the [dist](dist) folder. +You can access either version specifically from the dist folder. TronWeb is also compatible with frontend frameworks such as: - Angular @@ -183,6 +183,19 @@ Contact the team at https://cn.developers.tron.network/docs/online-technical-sup ## Recent History +__5.3.2__ +- Support build transactions locally with block header argument. +- Support [Tip586](https://github.com/tronprotocol/tips/blob/master/tip-586.md) by `trx.getBandwidthPrices` and `trx.getEnergyPrices`. +- Support recover transaction signer address by `trx.ecRecover`. +- Support multi-dimension address array such as address[][] https://github.com/tronprotocol/tronweb/issues/433 +- Fix error when triggerSmartContract with error address due to the undefined callback. https://github.com/tronprotocol/tronweb/issues/429 +- Fix getEventResult filter onlyConfirmed/onlyUnconfirmed not working https://github.com/tronprotocol/tronweb/issues/422 +- Axios update https://github.com/tronprotocol/tronweb/issues/445 + +__5.3.1__ +- Fix `getBlockRange()` error for range of 1 ([#398](https://github.com/tronprotocol/tronweb/issues/398)). +- Add support for `estimateenergy` in `TransactionBuilder#deployConstantContract()` API. + __5.3.0__ - Replace `elliptic` with `ethereum-cryptography/secp256k1` - Bump ethers to ^6.6.0 diff --git a/package-lock.json b/package-lock.json index 94cdd8dd..66c02b57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "tronweb", - "version": "5.3.1", + "version": "5.3.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "tronweb", - "version": "5.3.1", + "version": "5.3.2", "license": "MIT", "dependencies": { "@babel/runtime": "^7.0.0", "@ethersproject/abi": "^5.7.0", "@tronweb3/google-protobuf": "^3.21.2", - "axios": "^0.26.1", + "axios": "^1.6.2", "bignumber.js": "^9.0.1", "ethereum-cryptography": "^2.0.0", "ethers": "^6.6.0", @@ -77,11 +77,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -124,21 +126,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.21.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/core/node_modules/@babel/helper-compilation-targets": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", @@ -158,20 +145,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/core/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/core/node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -196,6 +169,35 @@ "semver": "bin/semver.js" } }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.18.6", "dev": true, @@ -256,9 +258,10 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -275,23 +278,25 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -412,28 +417,31 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -474,12 +482,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -487,9 +496,10 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.2", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -1849,67 +1859,40 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", - "debug": "^4.1.0", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.21.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -1920,12 +1903,13 @@ } }, "node_modules/@babel/types": { - "version": "7.21.2", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2909,12 +2893,19 @@ "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "dependencies": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/babel-loader": { @@ -3480,6 +3471,17 @@ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -3662,6 +3664,14 @@ "node": ">=6" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -4643,9 +4653,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "funding": [ { "type": "individual", @@ -4661,6 +4671,19 @@ } } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -4668,9 +4691,9 @@ "dev": true }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" @@ -5356,8 +5379,9 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "3.14.1", @@ -6551,7 +6575,6 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -6559,7 +6582,6 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -7505,7 +7527,6 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "dev": true, "license": "MIT" }, "node_modules/pump": { @@ -9841,9 +9862,10 @@ "license": "MIT" }, "node_modules/word-wrap": { - "version": "1.2.3", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10083,10 +10105,13 @@ } }, "@babel/code-frame": { - "version": "7.18.6", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" } }, "@babel/compat-data": { @@ -10114,18 +10139,6 @@ "semver": "^6.3.0" }, "dependencies": { - "@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", - "dev": true, - "requires": { - "@babel/types": "^7.21.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, "@babel/helper-compilation-targets": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", @@ -10139,17 +10152,6 @@ "semver": "^6.3.0" } }, - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, "convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -10170,6 +10172,31 @@ } } }, + "@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "requires": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, "@babel/helper-annotate-as-pure": { "version": "7.18.6", "dev": true, @@ -10208,7 +10235,9 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.9", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, "@babel/helper-explode-assignable-expression": { @@ -10219,18 +10248,22 @@ } }, "@babel/helper-function-name": { - "version": "7.21.0", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.18.6", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-member-expression-to-functions": { @@ -10309,18 +10342,24 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.18.6", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-string-parser": { - "version": "7.19.4", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.19.1", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -10347,16 +10386,20 @@ } }, "@babel/highlight": { - "version": "7.18.6", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.21.2", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { @@ -11204,53 +11247,34 @@ } }, "@babel/template": { - "version": "7.20.7", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.21.2", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", - "debug": "^4.1.0", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "dependencies": { - "@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", - "dev": true, - "requires": { - "@babel/types": "^7.21.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -11260,11 +11284,13 @@ } }, "@babel/types": { - "version": "7.21.2", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -11902,12 +11928,19 @@ "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "requires": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "babel-loader": { @@ -12344,6 +12377,14 @@ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -12489,6 +12530,11 @@ "type-detect": "^4.0.0" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -13266,9 +13312,19 @@ } }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } }, "function-bind": { "version": "1.1.1", @@ -13277,9 +13333,9 @@ "dev": true }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "get-value": { @@ -13767,6 +13823,8 @@ }, "js-tokens": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { @@ -14674,12 +14732,10 @@ "dev": true }, "mime-db": { - "version": "1.52.0", - "dev": true + "version": "1.52.0" }, "mime-types": { "version": "2.1.35", - "dev": true, "requires": { "mime-db": "1.52.0" } @@ -15337,8 +15393,7 @@ "dev": true }, "proxy-from-env": { - "version": "1.1.0", - "dev": true + "version": "1.1.0" }, "pump": { "version": "3.0.0", @@ -16939,7 +16994,9 @@ "dev": true }, "word-wrap": { - "version": "1.2.3", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wordwrap": { diff --git a/package.json b/package.json index 512e4d8c..e09bceca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tronweb", - "version": "5.3.1", + "version": "5.3.2", "description": "JavaScript SDK that encapsulates the TRON HTTP API", "main": "dist/TronWeb.node.js", "keywords": [ @@ -30,7 +30,7 @@ "@babel/runtime": "^7.0.0", "@ethersproject/abi": "^5.7.0", "@tronweb3/google-protobuf": "^3.21.2", - "axios": "^0.26.1", + "axios": "^1.6.2", "bignumber.js": "^9.0.1", "ethereum-cryptography": "^2.0.0", "ethers": "^6.6.0", diff --git a/src/index.js b/src/index.js index d24747d8..d8787325 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ import providers from 'lib/providers'; import utils from 'utils'; import BigNumber from 'bignumber.js'; import EventEmitter from 'eventemitter3'; -import { version } from '../package.json'; +import Package from '../package.json'; import semver from 'semver'; import injectpromise from 'injectpromise'; @@ -15,6 +15,8 @@ import SideChain from 'lib/sidechain'; import { keccak256 } from 'utils/ethersUtils'; import { ADDRESS_PREFIX, TRON_BIP39_PATH_INDEX_0 } from 'utils/address'; +const { version } = Package; + const DEFAULT_VERSION = '4.7.1'; const FEE_LIMIT = 150000000; diff --git a/src/lib/transactionBuilder.js b/src/lib/transactionBuilder.js index a79cca59..00eb3500 100644 --- a/src/lib/transactionBuilder.js +++ b/src/lib/transactionBuilder.js @@ -85,8 +85,31 @@ function getHeaderInfo(node) { }); } +function checkBlockHeader(options = {}) { + if ( + typeof options['ref_block_bytes'] === 'undefined' && + typeof options['ref_block_hash'] === 'undefined' && + typeof options['expiration'] === 'undefined' && + typeof options['timestamp'] === 'undefined' + ) { + return false; + } + if (typeof options['ref_block_bytes'] !== 'string') { + throw new Error('Invalid ref_block_bytes provided.'); + } + if (typeof options['ref_block_hash'] !== 'string') { + throw new Error('Invalid ref_block_hash provided.'); + } + if (typeof options['expiration'] !== 'number') { + throw new Error('Invalid expiration provided.'); + } + if (typeof options['timestamp'] !== 'number') { + throw new Error('Invalid timestamp provided.'); + } + return true; +} + async function createTransaction(tronWeb, type, value, Permission_id, options = {}) { - const metaData = await getHeaderInfo(tronWeb.fullNode); const tx = { visible: false, txID: '', @@ -99,7 +122,7 @@ async function createTransaction(tronWeb, type, value, Permission_id, options = }, type, }], - ...metaData, + ...(checkBlockHeader(options) ? {} : await getHeaderInfo(tronWeb.fullNode)), ...options, }, }; @@ -112,6 +135,16 @@ async function createTransaction(tronWeb, type, value, Permission_id, options = return tx; } +function getTransactionOptions(options) { + const ret = {}; + if (checkBlockHeader(options?.blockHeader)) { + ['ref_block_bytes', 'ref_block_hash', 'expiration', 'timestamp'].forEach((key) => { + ret[key] = options.blockHeader[key]; + }); + } + return ret; +} + export default class TransactionBuilder { constructor(tronWeb = false) { if (!tronWeb || !tronWeb instanceof TronWeb) @@ -173,7 +206,8 @@ export default class TransactionBuilder { amount: amount, }; - createTransaction(this.tronWeb, 'TransferContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'TransferContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -233,7 +267,8 @@ export default class TransactionBuilder { amount: parseInt(amount) }; - createTransaction(this.tronWeb, 'TransferAssetContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'TransferAssetContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -292,7 +327,8 @@ export default class TransactionBuilder { amount: parseInt(amount) }; - createTransaction(this.tronWeb, 'ParticipateAssetIssueContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ParticipateAssetIssueContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -378,7 +414,8 @@ export default class TransactionBuilder { data.receiver_address = toHex(receiverAddress) } - createTransaction(this.tronWeb, 'FreezeBalanceContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'FreezeBalanceContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -445,7 +482,8 @@ export default class TransactionBuilder { data.receiver_address = toHex(receiverAddress) } - createTransaction(this.tronWeb, 'UnfreezeBalanceContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'UnfreezeBalanceContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -504,7 +542,8 @@ export default class TransactionBuilder { data.resource = resource; } - createTransaction(this.tronWeb, 'FreezeBalanceV2Contract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'FreezeBalanceV2Contract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -563,7 +602,8 @@ export default class TransactionBuilder { data.resource = resource; } - createTransaction(this.tronWeb, 'UnfreezeBalanceV2Contract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'UnfreezeBalanceV2Contract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -599,7 +639,8 @@ export default class TransactionBuilder { owner_address: toHex(address), }; - createTransaction(this.tronWeb, 'CancelAllUnfreezeV2Contract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'CancelAllUnfreezeV2Contract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -711,7 +752,8 @@ export default class TransactionBuilder { } } - createTransaction(this.tronWeb, 'DelegateResourceContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'DelegateResourceContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -780,7 +822,8 @@ export default class TransactionBuilder { data.resource = resource; } - createTransaction(this.tronWeb, 'UnDelegateResourceContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'UnDelegateResourceContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -815,7 +858,8 @@ export default class TransactionBuilder { owner_address: toHex(address) } - createTransaction(this.tronWeb, 'WithdrawExpireUnfreezeContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'WithdrawExpireUnfreezeContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -850,7 +894,8 @@ export default class TransactionBuilder { owner_address: toHex(address) }; - createTransaction(this.tronWeb, 'WithdrawBalanceContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'WithdrawBalanceContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -902,7 +947,8 @@ export default class TransactionBuilder { url: fromUtf8(url), }; - createTransaction(this.tronWeb, 'WitnessCreateContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'WitnessCreateContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -974,7 +1020,8 @@ export default class TransactionBuilder { votes, }; - createTransaction(this.tronWeb, 'VoteWitnessContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'VoteWitnessContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -1114,10 +1161,13 @@ export default class TransactionBuilder { if (!type || !utils.isString(type) || !type.length) return callback('Invalid parameter type provided: ' + type); - if (type === 'address') - value = toHex(value).replace(ADDRESS_PREFIX_REGEX, '0x'); - else if (type.match(/^([^\x5b]*)(\x5b|$)/)[0] === 'address[') - value = value.map(v => toHex(v).replace(ADDRESS_PREFIX_REGEX, '0x')); + const replaceAddressPrefix = (value) => { + if (utils.isArray(value)) { + return value.map((v) => replaceAddressPrefix(v)); + } + return toHex(value).replace(ADDRESS_PREFIX_REGEX, '0x'); + }; + if (type.startsWith('address')) value = replaceAddressPrefix(value); else if (/trcToken/.test(type)) { type = type.replace(/trcToken/, 'uint256') } @@ -1186,7 +1236,11 @@ export default class TransactionBuilder { resolve(contract); }) .then(async contract => { - const tx = await createTransaction(this.tronWeb, 'CreateSmartContract', contract, options?.permissionId, { fee_limit: args.fee_limit }) + const transactionOptions = getTransactionOptions(options); + const tx = await createTransaction(this.tronWeb, 'CreateSmartContract', contract, options?.permissionId, { + ...transactionOptions, + fee_limit: args.fee_limit + }) tx.contract_address = genContractAddress(args.owner_address, tx.txID); return tx; }) @@ -1334,31 +1388,29 @@ export default class TransactionBuilder { let {type, value} = parameters[i]; if (!type || !utils.isString(type) || !type.length) - return callback('Invalid parameter type provided: ' + type); + throw new Error('Invalid parameter type provided: ' + type); - if (type === 'address') - value = toHex(value).replace(ADDRESS_PREFIX_REGEX, '0x'); - else if (type.match(/^([^\x5b]*)(\x5b|$)/)[0] === 'address[') - value = value.map(v => toHex(v).replace(ADDRESS_PREFIX_REGEX, '0x')); + const replaceAddressPrefix = (value) => { + if (utils.isArray(value)) { + return value.map((v) => replaceAddressPrefix(v)); + } + return toHex(value).replace(ADDRESS_PREFIX_REGEX, '0x'); + }; + if (type.startsWith('address')) value = replaceAddressPrefix(value); types.push(type); values.push(value); } - try { - // workaround for unsupported trcToken type - types = types.map(type => { - if (/trcToken/.test(type)) { - type = type.replace(/trcToken/, 'uint256') - } - return type - }) - - parameters = abiCoder.encode(types, values).replace(/^(0x)/, ''); + // workaround for unsupported trcToken type + types = types.map(type => { + if (/trcToken/.test(type)) { + type = type.replace(/trcToken/, 'uint256') + } + return type + }); - } catch (ex) { - return callback(ex); - } + parameters = abiCoder.encode(types, values).replace(/^(0x)/, ''); } else parameters = ''; // work for abiv2 if passed the function abi in options @@ -1483,17 +1535,22 @@ export default class TransactionBuilder { ], callback)) return; - const args = this._getTriggerSmartContractArgs( - contractAddress, - functionSelector, - options, - parameters, - issuerAddress, - tokenValue, - tokenId, - callValue, - feeLimit - ); + let args; + try { + args = this._getTriggerSmartContractArgs( + contractAddress, + functionSelector, + options, + parameters, + issuerAddress, + tokenValue, + tokenId, + callValue, + feeLimit + ); + } catch (err) { + return callback(err); + } if (args.function_selector) { args.data = keccak256(Buffer.from(args.function_selector, 'utf-8')).toString().substring(2, 10) + args.parameter; @@ -1512,12 +1569,15 @@ export default class TransactionBuilder { if (args.token_id) { value.token_id = args.token_id; } + + const transactionOptions = getTransactionOptions(options); createTransaction( this.tronWeb, 'TriggerSmartContract', value, options.permissionId, { + ...transactionOptions, fee_limit: args.fee_limit, } ).then(transaction => { @@ -1616,17 +1676,22 @@ export default class TransactionBuilder { ], callback)) return; - const args = this._getTriggerSmartContractArgs( - contractAddress, - functionSelector, - options, - parameters, - issuerAddress, - tokenValue, - tokenId, - callValue, - feeLimit - ); + let args; + try { + args = this._getTriggerSmartContractArgs( + contractAddress, + functionSelector, + options, + parameters, + issuerAddress, + tokenValue, + tokenId, + callValue, + feeLimit + ); + } catch (err) { + return callback(err); + } let pathInfo = 'triggersmartcontract'; if(options._isConstant) { @@ -1671,7 +1736,8 @@ export default class TransactionBuilder { delete this.tronWeb.trx.cache.contracts[contractAddress] } - createTransaction(this.tronWeb, 'ClearABIContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ClearABIContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); @@ -1708,7 +1774,8 @@ export default class TransactionBuilder { owner_address: toHex(ownerAddress) }; - createTransaction(this.tronWeb, 'UpdateBrokerageContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'UpdateBrokerageContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -1861,7 +1928,8 @@ export default class TransactionBuilder { data.vote_score = parseInt(voteScore) } - createTransaction(this.tronWeb, 'AssetIssueContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'AssetIssueContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -1903,7 +1971,8 @@ export default class TransactionBuilder { account_address: toHex(accountAddress), }; - createTransaction(this.tronWeb, 'AccountCreateContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'AccountCreateContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -1948,7 +2017,8 @@ export default class TransactionBuilder { owner_address: toHex(address), }; - createTransaction(this.tronWeb, 'AccountUpdateContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'AccountUpdateContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2001,7 +2071,8 @@ export default class TransactionBuilder { owner_address: toHex(address), } - createTransaction(this.tronWeb, 'SetAccountIdContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'SetAccountIdContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2065,7 +2136,8 @@ export default class TransactionBuilder { data.new_public_limit = parseInt(freeBandwidthLimit); } - createTransaction(this.tronWeb, 'UpdateAssetContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'UpdateAssetContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2134,7 +2206,8 @@ export default class TransactionBuilder { parameters: parameters }; - createTransaction(this.tronWeb, 'ProposalCreateContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ProposalCreateContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2180,7 +2253,8 @@ export default class TransactionBuilder { proposal_id: parseInt(proposalID) }; - createTransaction(this.tronWeb, 'ProposalDeleteContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ProposalDeleteContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2232,7 +2306,8 @@ export default class TransactionBuilder { is_add_approval: isApproval }; - createTransaction(this.tronWeb, 'ProposalApproveContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ProposalApproveContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2291,7 +2366,8 @@ export default class TransactionBuilder { second_token_balance: trxBalance }; - createTransaction(this.tronWeb, 'ExchangeCreateContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ExchangeCreateContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2356,7 +2432,8 @@ export default class TransactionBuilder { second_token_balance: secondTokenBalance }; - createTransaction(this.tronWeb, 'ExchangeCreateContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ExchangeCreateContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2416,7 +2493,8 @@ export default class TransactionBuilder { quant: parseInt(tokenAmount) }; - createTransaction(this.tronWeb, 'ExchangeInjectContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ExchangeInjectContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2476,7 +2554,8 @@ export default class TransactionBuilder { quant: parseInt(tokenAmount) }; - createTransaction(this.tronWeb, 'ExchangeWithdrawContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ExchangeWithdrawContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2549,7 +2628,8 @@ export default class TransactionBuilder { expected: parseInt(tokenAmountExpected) }; - createTransaction(this.tronWeb, 'ExchangeTransactionContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'ExchangeTransactionContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2605,7 +2685,8 @@ export default class TransactionBuilder { consume_user_resource_percent: userFeePercentage }; - createTransaction(this.tronWeb, 'UpdateSettingContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'UpdateSettingContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2662,7 +2743,8 @@ export default class TransactionBuilder { origin_energy_limit: originEnergyLimit }; - createTransaction(this.tronWeb, 'UpdateEnergyLimitContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'UpdateEnergyLimitContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } @@ -2770,7 +2852,8 @@ export default class TransactionBuilder { data.actives = _activesPermissions; } - createTransaction(this.tronWeb, 'AccountPermissionUpdateContract', data, options?.permissionId) + const transactionOptions = getTransactionOptions(options); + createTransaction(this.tronWeb, 'AccountPermissionUpdateContract', data, options?.permissionId, transactionOptions) .then(transaction => callback(null, transaction)) .catch(err => callback(err)); } diff --git a/src/lib/trx.js b/src/lib/trx.js index 15894ad1..68f69f6f 100644 --- a/src/lib/trx.js +++ b/src/lib/trx.js @@ -1,10 +1,11 @@ import TronWeb from 'index'; import utils from 'utils'; -import { keccak256, toUtf8Bytes, recoverAddress, SigningKey } from 'utils/ethersUtils'; +import { keccak256, toUtf8Bytes, recoverAddress, SigningKey, Signature } from 'utils/ethersUtils'; import { ADDRESS_PREFIX } from 'utils/address'; import Validator from "../paramValidator"; import injectpromise from 'injectpromise'; import { txCheck } from '../utils/transaction'; +import { ecRecover } from '../utils/crypto'; const TRX_MESSAGE_HEADER = '\x19TRON Signed Message:\n32'; // it should be: '\x15TRON Signed Message:\n32'; @@ -606,6 +607,27 @@ export default class Trx { }).catch(err => callback(err)); } + ecRecover(transaction) { + return Trx.ecRecover(transaction); + } + + static ecRecover(transaction) { + if (!txCheck(transaction)) { + throw new Error('Invalid transaction'); + } + if (!transaction.signature?.length) { + throw new Error('Transaction is not signed'); + } + if (transaction.signature.length === 1) { + const tronAddress = ecRecover(transaction.txID, transaction.signature[0]); + return TronWeb.address.fromHex(tronAddress); + } + return transaction.signature.map((sig) => { + const tronAddress = ecRecover(transaction.txID, sig); + return TronWeb.address.fromHex(tronAddress); + }); + } + async verifyMessage(message = false, signature = false, address = this.tronWeb.defaultAddress.base58, useTronHeader = true, callback = false) { if (utils.isFunction(address)) { callback = address; @@ -632,18 +654,13 @@ export default class Trx { static verifySignature(message, address, signature, useTronHeader = true) { message = message.replace(/^0x/, ''); - signature = signature.replace(/^0x/, ''); const messageBytes = [ ...toUtf8Bytes(useTronHeader ? TRX_MESSAGE_HEADER : ETH_MESSAGE_HEADER), ...utils.code.hexStr2byteArray(message) ]; const messageDigest = keccak256(new Uint8Array(messageBytes)); - const recovered = recoverAddress(messageDigest, { - yParity: signature.substring(128, 130) == '1c' ? 1 : 0, - r: '0x' + signature.substring(0, 64), - s: '0x' + signature.substring(64, 128) - }); + const recovered = recoverAddress(messageDigest, Signature.from(`0x${signature.replace(/^0x/, '')}`)); const tronAddress = ADDRESS_PREFIX + recovered.substr(2); const base58Address = TronWeb.address.fromHex(tronAddress); @@ -688,14 +705,8 @@ export default class Trx { } static verifyTypedData(domain, types, value, signature, address) { - signature = signature.replace(/^0x/, ''); - const messageDigest = utils._TypedDataEncoder.hash(domain, types, value); - const recovered = recoverAddress(messageDigest, { - yParity: signature.substring(128, 130) == '1c' ? 1 : 0, - r: '0x' + signature.substring(0, 64), - s: '0x' + signature.substring(64, 128), - }); + const recovered = recoverAddress(messageDigest, Signature.from(`0x${signature.replace(/^0x/, '')}`)); const tronAddress = ADDRESS_PREFIX + recovered.substr(2); const base58Address = TronWeb.address.fromHex(tronAddress); @@ -1737,4 +1748,25 @@ export default class Trx { }).catch(err => callback(err)); } + async getBandwidthPrices() { + return this.tronWeb.fullNode.request('wallet/getbandwidthprices', {}, 'post') + .then((result = {}) => { + if (typeof result.prices === 'undefined') { + throw new Error('Not found.'); + } + + return result.prices; + }); + } + + async getEnergyPrices() { + return this.tronWeb.fullNode.request('wallet/getenergyprices', {}, 'post') + .then((result = {}) => { + if (typeof result.prices === 'undefined') { + throw new Error('Not found.'); + } + + return result.prices; + }); + } }; diff --git a/src/utils/crypto.js b/src/utils/crypto.js index 1aaea1be..9aac967f 100644 --- a/src/utils/crypto.js +++ b/src/utils/crypto.js @@ -3,7 +3,7 @@ import {base64EncodeToString} from './code'; import {base64DecodeFromString, hexStr2byteArray} from './code'; import {encode58, decode58} from './base58'; import {byte2hexStr, byteArray2hexStr} from './bytes'; -import {keccak256, sha256, SigningKey} from './ethersUtils'; +import {arrayify, keccak256, recoverAddress, sha256, Signature, SigningKey} from './ethersUtils'; import {TypedDataEncoder} from './typedData'; import { secp256k1 as secp } from "ethereum-cryptography/secp256k1.js"; @@ -67,6 +67,15 @@ export function signTransaction(priKeyBytes, transaction) { return transaction; } +export function ecRecover(signedData, signature) { + signedData = '0x' + signedData.replace(/^0x/, ''); + signature = '0x' + signature.replace(/^0x/, ''); + + const recovered = recoverAddress(arrayify(signedData), Signature.from(signature)); + const tronAddress = ADDRESS_PREFIX + recovered.substring(2); + return tronAddress; +} + export function arrayToBase64String(a) { return btoa(String.fromCharCode(...a)); } diff --git a/src/utils/ethersUtils.js b/src/utils/ethersUtils.js index eb733059..d6b306b0 100644 --- a/src/utils/ethersUtils.js +++ b/src/utils/ethersUtils.js @@ -42,6 +42,7 @@ export { toUtf8String, recoverAddress, SigningKey, + Signature, AbiCoder, Interface, FormatTypes, diff --git a/test/helpers/getBlockHeader.js b/test/helpers/getBlockHeader.js new file mode 100644 index 00000000..687d123f --- /dev/null +++ b/test/helpers/getBlockHeader.js @@ -0,0 +1,11 @@ +module.exports = function getHeaderInfo(node) { + return node.request('wallet/getblock', { detail: false }, 'post') + .then((data) => { + return { + ref_block_bytes: data.block_header.raw_data.number.toString(16).slice(-4).padStart(4, '0'), + ref_block_hash: data.blockID.slice(16, 32), + expiration: data.block_header.raw_data.timestamp + 60 * 1000, + timestamp: data.block_header.raw_data.timestamp, + }; + }); +}; \ No newline at end of file diff --git a/test/lib/transactionBuilder.test.js b/test/lib/transactionBuilder.test.js index 2a50a46d..0368595c 100644 --- a/test/lib/transactionBuilder.test.js +++ b/test/lib/transactionBuilder.test.js @@ -12,6 +12,7 @@ const assertEqualHex = require('../helpers/assertEqualHex'); const { testRevert, testConstant, arrayParam, rawParam, funcABIV2, funcABIV2_2, funcABIV2_3, funcABIV2_4, testSetVal, testPayable } = require('../fixtures/contracts'); const waitChainData = require('../helpers/waitChainData'); const { equals, getValues } = require('../helpers/testUtils'); +const getBlockHeader = require('../helpers/getBlockHeader'); const TronWeb = tronWebBuilder.TronWeb; const { @@ -53,7 +54,8 @@ describe('TronWeb.transactionBuilder', function () { it(`should send 0.00001 trx from default address to accounts[1]`, async function () { const params = [ [accounts.b58[1], 10, {permissionId: 2}], - [accounts.b58[1], 10] + [accounts.b58[1], 10], + [accounts.b58[1], 10, { blockHeader: await getBlockHeader(tronWeb.fullNode) }] ]; for (let param of params) { const transaction = await tronWeb.transactionBuilder.sendTrx(...param); @@ -65,7 +67,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, ADDRESS_HEX); assert.equal(parameter.value.to_address, accounts.hex[1]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.TransferContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2] ? param[2]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2]?.['permissionId'] || 0); + if (param[2]?.blockHeader) { + Object.keys(param[2].blockHeader).forEach((key) => { + assert.equal(param[2].blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -151,10 +158,19 @@ describe('TronWeb.transactionBuilder', function () { // This test passes only the first time because, in order to test updateToken, we broadcast the token creation it(`should allow accounts[2] to create a TestToken`, async function () { - - const options = getTokenOptions(); - for (let i = 0; i < 2; i++) { - if (i === 1) options.permissionId = 2; + const params = [ + getTokenOptions(), + { + ...getTokenOptions(), + permissionId: 2, + }, + { + ...getTokenOptions(), + blockHeader: await getBlockHeader(tronWeb.fullNode), + } + ]; + for (let i = 0; i < 3; i++) { + const options = params[i]; const transaction = await tronWeb.transactionBuilder.createToken(options, accounts.b58[2]); const parameter = txPars(transaction); assert.equal(transaction.txID.length, 64); @@ -163,7 +179,11 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, accounts.hex[2]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.AssetIssueContract'); assert.equal(transaction.raw_data.contract[0].Permission_id || 0, options.permissionId || 0); - + if (options.blockHeader) { + Object.keys(options.blockHeader).forEach((key) => { + assert.equal(options.blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -518,6 +538,7 @@ describe('TronWeb.transactionBuilder', function () { const params = [ [inactiveAccountAddress, accounts.b58[3], {permissionId: 2}], [inactiveAccountAddress, accounts.b58[3]], + [inactiveAccountAddress, accounts.b58[3], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { @@ -527,7 +548,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, accounts.hex[3]); assert.equal(parameter.value.account_address, tronWeb.address.toHex(inactiveAccountAddress).toLowerCase()); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.AccountCreateContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2] ? param[2]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2]?.['permissionId'] || 0); + if (param[2]?.blockHeader) { + Object.keys(param[2].blockHeader).forEach((key) => { + assert.equal(param[2].blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -557,7 +583,8 @@ describe('TronWeb.transactionBuilder', function () { const newName = 'New name' const params = [ [newName, accounts.b58[3], {permissionId: 2}], - [newName, accounts.b58[3]] + [newName, accounts.b58[3]], + [newName, accounts.b58[3], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { @@ -568,7 +595,12 @@ describe('TronWeb.transactionBuilder', function () { await assertEqualHex(parameter.value.account_name, newName); assert.equal(parameter.value.owner_address, accounts.hex[3]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.AccountUpdateContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2] ? param[2]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2]?.['permissionId'] || 0); + if (param[2]?.blockHeader) { + Object.keys(param[2].blockHeader).forEach((key) => { + assert.equal(param[2].blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -607,6 +639,7 @@ describe('TronWeb.transactionBuilder', function () { const params = [ [TronWeb.toHex('abcabc110'), accounts.b58[4], {permissionId: 2}], [TronWeb.toHex('testtest'), accounts.b58[4]], + [TronWeb.toHex('test2222'), accounts.b58[4], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ] for (let param of params) { @@ -616,7 +649,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.account_id, param[0].slice(2)); assert.equal(parameter.value.owner_address, accounts.hex[4]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.SetAccountIdContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2] ? param[2]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2]?.['permissionId'] || 0); + if (param[2]?.blockHeader) { + Object.keys(param[2].blockHeader).forEach((key) => { + assert.equal(param[2].blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -677,8 +715,19 @@ describe('TronWeb.transactionBuilder', function () { }); it(`should allow accounts[2] to update a TestToken`, async function () { - for (let i = 0; i < 2; i++) { - if (i === 1) UPDATED_TEST_TOKEN_OPTIONS.permissionId = 2; + const params = [ + UPDATED_TEST_TOKEN_OPTIONS, + { + ...UPDATED_TEST_TOKEN_OPTIONS, + permissionId: 2, + }, + { + ...UPDATED_TEST_TOKEN_OPTIONS, + blockHeader: await getBlockHeader(tronWeb.fullNode), + }, + ]; + for (let i = 0; i < 3; i++) { + const UPDATED_TEST_TOKEN_OPTIONS = params[i]; const transaction = await tronWeb.transactionBuilder.updateToken(UPDATED_TEST_TOKEN_OPTIONS, accounts.b58[2]); const parameter = txPars(transaction); assert.equal(transaction.txID.length, 64); @@ -687,6 +736,11 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, accounts.hex[2]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.UpdateAssetContract'); assert.equal(transaction.raw_data.contract[0].Permission_id || 0, UPDATED_TEST_TOKEN_OPTIONS.permissionId || 0); + if (UPDATED_TEST_TOKEN_OPTIONS.blockHeader) { + Object.keys(UPDATED_TEST_TOKEN_OPTIONS.blockHeader).forEach((key) => { + assert.equal(UPDATED_TEST_TOKEN_OPTIONS.blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -848,7 +902,8 @@ describe('TronWeb.transactionBuilder', function () { const params = [ [accounts.b58[5], tokenID, 20, accounts.b58[2], {permissionId: 2}], - [accounts.b58[5], tokenID, 20, accounts.b58[2]] + [accounts.b58[5], tokenID, 20, accounts.b58[2]], + [accounts.b58[5], tokenID, 20, accounts.b58[2], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { @@ -861,7 +916,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, accounts.hex[2]); assert.equal(parameter.value.to_address, accounts.hex[5]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.ParticipateAssetIssueContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[4] ? param[4]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[4]?.['permissionId'] || 0); + if (param[4]?.blockHeader) { + Object.keys(param[4].blockHeader).forEach((key) => { + assert.equal(param[4].blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -977,7 +1037,8 @@ describe('TronWeb.transactionBuilder', function () { const params = [ [accounts.b58[1], 5, tokenID, accounts.b58[7], {permissionId: 2}], - [accounts.b58[1], 5, tokenID, accounts.b58[7]] + [accounts.b58[1], 5, tokenID, accounts.b58[7]], + [accounts.b58[1], 5, tokenID, accounts.b58[7], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { @@ -994,8 +1055,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.amount, 5) assert.equal(parameter.value.owner_address, accounts.hex[7]); assert.equal(parameter.value.to_address, accounts.hex[1]); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[4] ? param[4]['permissionId'] : 0); - + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[4]?.['permissionId'] || 0); + if (param[4]?.blockHeader) { + Object.keys(param[4].blockHeader).forEach((key) => { + assert.equal(param[4].blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -1077,7 +1142,8 @@ describe('TronWeb.transactionBuilder', function () { const inputs = [ [parameters[0], ADDRESS_BASE58, {permissionId: 2}], - [parameters[0], ADDRESS_BASE58] + [parameters[0], ADDRESS_BASE58], + [parameters[0], ADDRESS_BASE58, { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let input of inputs) { const transaction = await tronWeb.transactionBuilder.createProposal(...input) @@ -1087,7 +1153,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, ADDRESS_HEX); assert.equal(parameter.value.parameters[0].value, parameters[0].value); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.ProposalCreateContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, input[2] ? input[2]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, input[2]?.['permissionId'] || 0); + if (input[2]?.blockHeader) { + Object.keys(input[2].blockHeader).forEach((key) => { + assert.equal(input[2].blockHeader[key], transaction.raw_data[key]) + }); + } } }) @@ -1164,7 +1235,8 @@ describe('TronWeb.transactionBuilder', function () { const params = [ [proposals[0].proposal_id, {permissionId: 2}], - [proposals[0].proposal_id] + [proposals[0].proposal_id], + [proposals[0].proposal_id, { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { const transaction = await tronWeb.transactionBuilder.deleteProposal(...param) @@ -1173,7 +1245,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, ADDRESS_HEX); assert.equal(parameter.value.proposal_id, proposals[0].proposal_id); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.ProposalDeleteContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[1] ? param[1]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[1]?.['permissionId'] || 0); + if (param[1]?.blockHeader) { + Object.keys(param[1].blockHeader).forEach((key) => { + assert.equal(param[1].blockHeader[key], transaction.raw_data[key]) + }); + } } }) @@ -1315,7 +1392,8 @@ describe('TronWeb.transactionBuilder', function () { it('should allows accounts[1] to freeze its balance by freezeBalanceV2', async function () { const params = [ [500e6, 'BANDWIDTH', accounts.b58[1], {permissionId: 2}], - [500e6, 'BANDWIDTH', accounts.b58[1]] + [500e6, 'BANDWIDTH', accounts.b58[1]], + [500e6, 'BANDWIDTH', accounts.b58[1], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { @@ -1327,7 +1405,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, accounts.hex[1]); assert.equal(parameter.value.frozen_balance, 500e6); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.FreezeBalanceV2Contract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[3] ? param[3]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[3]?.['permissionId'] || 0); + if (param[3]?.blockHeader) { + Object.keys(param[3].blockHeader).forEach((key) => { + assert.equal(param[3].blockHeader[key], transaction.raw_data[key]) + }); + } } }) @@ -1410,7 +1493,8 @@ describe('TronWeb.transactionBuilder', function () { it('should allows accounts[1] to unfreeze its balance', async function () { const params = [ [100e6, 'BANDWIDTH', accounts.b58[1], {permissionId: 2}], - [100e6, 'BANDWIDTH', accounts.b58[1]] + [100e6, 'BANDWIDTH', accounts.b58[1]], + [100e6, 'BANDWIDTH', accounts.b58[1], { blockHeader: getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { @@ -1422,7 +1506,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, accounts.hex[1]); assert.equal(parameter.value.unfreeze_balance, 100e6); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.UnfreezeBalanceV2Contract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[3] ? param[3]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[3]?.['permissionId'] || 0); + if (param[3]?.blockHeader) { + Object.keys(param[3].blockHeader).forEach((key) => { + assert.equal(param[3].blockHeader[key], transaction.raw_data[key]) + }); + } } }) @@ -1526,6 +1615,7 @@ describe('TronWeb.transactionBuilder', function () { const params = [ [accounts.b58[1], {permissionId: 2}], [accounts.b58[2]], + [accounts.b58[2], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let i = 0; i < 2; i++) { @@ -1537,6 +1627,11 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, accounts.hex[1 + i]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.CancelAllUnfreezeV2Contract'); assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[1] ? param[1]['permissionId'] : 0); + if (param[1]?.blockHeader) { + Object.keys(param[1].blockHeader).forEach((key) => { + assert.equal(param[1].blockHeader[key], transaction.raw_data[key]) + }); + } const tx = await broadcaster(null, accounts.pks[1 + i], transaction); assert.isTrue(tx.receipt.result); } @@ -1566,7 +1661,8 @@ describe('TronWeb.transactionBuilder', function () { it('should allows accounts[1] to delegate its resource', async function () { const params = [ [100e6, accounts.b58[7], 'BANDWIDTH', accounts.b58[1], {permissionId: 2}], - [100e6, accounts.b58[7], 'BANDWIDTH', accounts.b58[1]] + [100e6, accounts.b58[7], 'BANDWIDTH', accounts.b58[1]], + [100e6, accounts.b58[7], 'BANDWIDTH', accounts.b58[1], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { @@ -1579,7 +1675,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.receiver_address, accounts.hex[7]); assert.equal(parameter.value.balance, 100e6); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.DelegateResourceContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[4] ? param[4]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[4]?.['permissionId'] || 0); + if (param[4]?.blockHeader) { + Object.keys(param[4].blockHeader).forEach((key) => { + assert.equal(param[4].blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -1729,7 +1830,7 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.receiver_address, accounts.hex[7]); assert.equal(parameter.value.balance, 100e6); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.DelegateResourceContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2] ? param[2]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2]?.['permissionId'] || 0); } }) @@ -1858,7 +1959,8 @@ describe('TronWeb.transactionBuilder', function () { it('should allows accounts[1] to undelegate its resource', async function () { const params = [ [100e6, accounts.b58[7], 'BANDWIDTH', accounts.b58[1], {permissionId: 2}], - [100e6, accounts.b58[7], 'BANDWIDTH', accounts.b58[1]] + [100e6, accounts.b58[7], 'BANDWIDTH', accounts.b58[1]], + [100e6, accounts.b58[7], 'BANDWIDTH', accounts.b58[1], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { @@ -1871,7 +1973,12 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.receiver_address, accounts.hex[7]); assert.equal(parameter.value.balance, 100e6); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.UnDelegateResourceContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[4] ? param[4]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[4]?.['permissionId'] || 0); + if (param[4]?.blockHeader) { + Object.keys(param[4].blockHeader).forEach((key) => { + assert.equal(param[4].blockHeader[key], transaction.raw_data[key]) + }); + } } }) @@ -1979,7 +2086,7 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.receiver_address, accounts.hex[7]); assert.equal(parameter.value.balance, 100e6); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.UnDelegateResourceContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2] ? param[2]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[2]?.['permissionId'] || 0); } }) @@ -2101,7 +2208,8 @@ describe('TronWeb.transactionBuilder', function () { it('should allows accounts[1] to withdraw its undelegated resource', async function () { const params = [ [accounts.b58[1], {permissionId: 2}], - [accounts.b58[1]] + [accounts.b58[1]], + [accounts.b58[1], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { const transaction = await tronWeb.transactionBuilder.withdrawExpireUnfreeze(...param) @@ -2110,7 +2218,12 @@ describe('TronWeb.transactionBuilder', function () { // jlog(parameter) assert.equal(parameter.value.owner_address, accounts.hex[1]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.WithdrawExpireUnfreezeContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[1] ? param[1]['permissionId'] : 0); + assert.equal(transaction.raw_data.contract[0].Permission_id || 0, param[1]?.['permissionId'] || 0); + if (param[1]?.blockHeader) { + Object.keys(param[1].blockHeader).forEach((key) => { + assert.equal(param[1].blockHeader[key], transaction.raw_data[key]) + }); + } } }) @@ -2164,13 +2277,29 @@ describe('TronWeb.transactionBuilder', function () { bytecode: testRevert.bytecode, feeLimit: 8e7 }; - for (let i = 0; i < 2; i++) { - if (i === 1) options.permissionId = 2; + const params = [ + options, + { + ...options, + permissionId: 2, + }, + { + ...options, + blockHeader: await getBlockHeader(tronWeb.fullNode), + } + ]; + for (let i = 0; i < 3; i++) { + const options = params[i]; const tx = await tronWeb.transactionBuilder.createSmartContract(options) assert.equal(tx.raw_data.contract[0].parameter.value.new_contract.consume_user_resource_percent, 100); assert.equal(tx.raw_data.contract[0].parameter.value.new_contract.origin_energy_limit, 1e7); assert.equal(tx.raw_data.fee_limit, 8e7); assert.equal(tx.raw_data.contract[0].Permission_id || 0, options.permissionId || 0); + if (options.blockHeader) { + Object.keys(options.blockHeader).forEach((key) => { + assert.equal(options.blockHeader[key], tx.raw_data[key]) + }); + } } }); @@ -2342,10 +2471,18 @@ describe('TronWeb.transactionBuilder', function () { {type: 'uint256', value: 1}, {type: 'uint256', value: 2} ] - const options = {}; + const params = [ + {}, + { + permissionId: 2, + }, + { + blockHeader: await getBlockHeader(tronWeb.fullNode), + }, + ]; - for (let i = 0; i < 2; i++) { - if (i === 1) options.permissionId = 2; + for (let i = 0; i < params.length; i++) { + const options = params[i]; transaction = await tronWeb.transactionBuilder.triggerConfirmedConstantContract(contractAddress, functionSelector, options, parameter, issuerAddress); assert.isTrue(transaction.result.result && @@ -2395,6 +2532,7 @@ describe('TronWeb.transactionBuilder', function () { const params = [ [transactions[0], accounts.hex[7], {permissionId: 2}], [transactions[1], accounts.hex[7]], + [transactions[1], accounts.hex[7], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (const param of params) { const contractAddress = param[0].contract_address; @@ -2402,6 +2540,7 @@ describe('TronWeb.transactionBuilder', function () { // verify contract abi before const contract = await tronWeb.trx.getContract(contractAddress); + console.log(JSON.stringify(contract)); assert.isTrue(Object.keys(contract.abi).length > 0) // clear abi @@ -2413,8 +2552,13 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.contract_address, tronWeb.address.toHex(contractAddress)); assert.equal(parameter.value.owner_address, tronWeb.address.toHex(ownerAddress)); assert.equal(transaction.raw_data.contract[0].Permission_id, param[2]?.permissionId); + if (param[2]?.blockHeader) { + Object.keys(param[2].blockHeader).forEach((key) => { + assert.equal(param[2].blockHeader[key], transaction.raw_data[key]) + }); + } - if (param.length === 2) { + if (param?.blockHeader) { const res = await broadcaster(null, accounts.pks[7], transaction); assert.isTrue(res.receipt.result); @@ -2460,6 +2604,7 @@ describe('TronWeb.transactionBuilder', function () { const params = [ [10, accounts.hex[1], {permissionId: 2}], [20, accounts.hex[1]], + [20, accounts.hex[1], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (const param of params) { const transaction = await tronWeb.transactionBuilder.updateBrokerage(...param); @@ -2469,6 +2614,11 @@ describe('TronWeb.transactionBuilder', function () { assert.equal(parameter.value.owner_address, param[1]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.UpdateBrokerageContract'); assert.equal(transaction.raw_data.contract[0].Permission_id, param[2]?.permissionId); + if (param[2]?.blockHeader) { + Object.keys(param[2].blockHeader).forEach((key) => { + assert.equal(param[2].blockHeader[key], transaction.raw_data[key]) + }); + } } }); @@ -2536,9 +2686,20 @@ describe('TronWeb.transactionBuilder', function () { const options = { _isConstant: true, }; + const params = [ + options, + { + ...options, + permissionId: 2, + }, + { + ...options, + blockHeader: await getBlockHeader(tronWeb.fullNode), + }, + ]; - for (let i = 0; i < 2; i++) { - if (i === 1) options.permissionId = 2; + for (let i = 0; i < params.length; i++) { + const options = params[i]; transaction = await tronWeb.transactionBuilder.triggerSmartContract(contractAddress, functionSelector, options, parameter, issuerAddress); assert.isTrue(transaction.result.result && @@ -2591,23 +2752,27 @@ describe('TronWeb.transactionBuilder', function () { }); it('should create token exchange', async function () { - let transaction = await tronWeb.transactionBuilder.createTokenExchange(tokenNames[0], 10e3, tokenNames[1], 10e3, accounts.hex[toIdx1]); - let parameter = txPars(transaction); - - assert.equal(transaction.txID.length, 64); - assert.equal(TronWeb.toUtf8(parameter.value.first_token_id), tokenNames[0]); - assert.equal(TronWeb.toUtf8(parameter.value.second_token_id), tokenNames[1]); - assert.equal(parameter.type_url, 'type.googleapis.com/protocol.ExchangeCreateContract'); - assert.isUndefined(transaction.raw_data.contract[0].Permission_id); + const params = [ + [tokenNames[0], 10e3, tokenNames[1], 10e3, accounts.hex[toIdx1]], + [tokenNames[0], 10e3, tokenNames[1], 10e3, accounts.hex[toIdx1], {permissionId: 2}], + [tokenNames[0], 10e3, tokenNames[1], 10e3, accounts.hex[toIdx1], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], + ]; - transaction = await tronWeb.transactionBuilder.createTokenExchange(tokenNames[0], 10e3, tokenNames[1], 10e3, accounts.hex[toIdx1], {permissionId: 2}); - parameter = txPars(transaction); + for (let param of params) { + let transaction = await tronWeb.transactionBuilder.createTokenExchange(...param); + let parameter = txPars(transaction); - assert.equal(transaction.txID.length, 64); - assert.equal(TronWeb.toUtf8(parameter.value.first_token_id), tokenNames[0]); - assert.equal(TronWeb.toUtf8(parameter.value.second_token_id), tokenNames[1]); - assert.equal(parameter.type_url, 'type.googleapis.com/protocol.ExchangeCreateContract'); - assert.equal(transaction.raw_data.contract[0].Permission_id, 2); + assert.equal(transaction.txID.length, 64); + assert.equal(TronWeb.toUtf8(parameter.value.first_token_id), tokenNames[0]); + assert.equal(TronWeb.toUtf8(parameter.value.second_token_id), tokenNames[1]); + assert.equal(parameter.type_url, 'type.googleapis.com/protocol.ExchangeCreateContract'); + assert.equal(transaction.raw_data.contract[0].Permission_id, param[5]?.permissionId); + if (param[5]?.blockHeader) { + Object.keys(param[5].blockHeader).forEach((key) => { + assert.equal(param[5].blockHeader[key], transaction.raw_data[key]) + }); + } + } }); }); @@ -2652,7 +2817,8 @@ describe('TronWeb.transactionBuilder', function () { it(`should inject exchange tokens`, async function () { const params = [ [exchangeId, tokenNames[0], 10, { permissionId: 2 }], - [exchangeId, tokenNames[0], 10] + [exchangeId, tokenNames[0], 10], + [exchangeId, tokenNames[0], 10, { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { const transaction = await tronWeb.transactionBuilder.injectExchangeTokens( @@ -2708,7 +2874,8 @@ describe('TronWeb.transactionBuilder', function () { it(`should withdraw exchange tokens`, async function () { const params = [ [exchangeId, tokenNames[0], 10, { permissionId: 2 }], - [exchangeId, tokenNames[0], 10] + [exchangeId, tokenNames[0], 10], + [exchangeId, tokenNames[0], 10, { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { const transaction = await tronWeb.transactionBuilder.withdrawExchangeTokens( @@ -2758,7 +2925,8 @@ describe('TronWeb.transactionBuilder', function () { it(`should trade exchange tokens`, async function () { const params = [ [exchangeId, tokenNames[0], 10, 5, { permissionId: 2 }], - [exchangeId, tokenNames[0], 10, 5] + [exchangeId, tokenNames[0], 10, 5], + [exchangeId, tokenNames[0], 10, 5, { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { const transaction = await tronWeb.transactionBuilder.tradeExchangeTokens( @@ -2804,7 +2972,8 @@ describe('TronWeb.transactionBuilder', function () { it(`should update setting`, async function () { const params = [ [transaction.contract_address, 10, accounts.b58[3], { permissionId: 2 }], - [transaction.contract_address, 20, accounts.b58[3]] + [transaction.contract_address, 20, accounts.b58[3]], + [transaction.contract_address, 20, accounts.b58[3], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { const transaction = await tronWeb.transactionBuilder.updateSetting( @@ -2840,7 +3009,8 @@ describe('TronWeb.transactionBuilder', function () { it(`should update energy limit`, async function () { const params = [ [transaction.contract_address, 10e6, accounts.b58[3], { permissionId: 2 }], - [transaction.contract_address, 10e6, accounts.b58[3]] + [transaction.contract_address, 10e6, accounts.b58[3]], + [transaction.contract_address, 10e6, accounts.b58[3], { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { const transaction = await tronWeb.transactionBuilder.updateEnergyLimit( @@ -2913,6 +3083,7 @@ describe('TronWeb.transactionBuilder', function () { const params = [ [accounts.hex[6], permissionData.owner, permissionData.witness, permissionData.actives, {permissionId: 2}], [accounts.hex[6], permissionData.owner, permissionData.witness, permissionData.actives], + [accounts.hex[6], permissionData.owner, permissionData.witness, permissionData.actives, { blockHeader: await getBlockHeader(tronWeb.fullNode) }], ]; for (let param of params) { const transaction = await tronWeb.transactionBuilder.updateAccountPermissions( @@ -2926,6 +3097,11 @@ describe('TronWeb.transactionBuilder', function () { // assert.deepEqual(parameter.value.actives, param[3]); assert.equal(parameter.type_url, 'type.googleapis.com/protocol.AccountPermissionUpdateContract'); assert.equal(transaction.raw_data.contract[0].Permission_id, param[4]?.permissionId); + if (param[4]?.blockHeader) { + Object.keys(param[4].blockHeader).forEach((key) => { + assert.equal(param[4].blockHeader[key], transaction.raw_data[key]) + }); + } } }); }); diff --git a/test/lib/trx.test.js b/test/lib/trx.test.js index 9a8ba8ce..6fbfa606 100644 --- a/test/lib/trx.test.js +++ b/test/lib/trx.test.js @@ -609,6 +609,36 @@ describe('TronWeb.trx', function () { }); }); + describe('#ecRecover', async function () { + const idx = 14; + let transaction; + + before(async function () { + transaction = await tronWeb.transactionBuilder.sendTrx(accounts.b58[idx-1], 10, accounts.b58[idx]); + await tronWeb.trx.sign(transaction, accounts.pks[idx]); + }); + + it('should verify signature of signed transaction', async function () { + const recoveredAddress = await tronWeb.trx.ecRecover(transaction); + assert.equal(recoveredAddress, accounts.b58[idx]); + }); + + it('should throw Invalid transaction error', async function() { + const tx = JSON.parse(JSON.stringify(transaction)); + tx.txID += 't'; + assertThrow(async () => { + await tronWeb.trx.ecRecover(tx); + }, 'Invalid transaction'); + }); + + it('should throw Transaction is not signed error', async function() { + const tx = JSON.parse(JSON.stringify(transaction)); + delete tx.signature; + assertThrow(async () => { + await tronWeb.trx.ecRecover(tx); + }, 'Transaction is not signed'); + }); + }); describe("#signMessage", async function () { @@ -2261,4 +2291,18 @@ describe('TronWeb.trx', function () { }); }); }); + + describe('#getBandwidthPrices', async function () { + it('should getBandwidthPrices from fullNode', async function () { + const prices = await tronWeb.trx.getBandwidthPrices(); + assert.isString(prices); + }) + }); + + describe('#getEnergyPrices', async function () { + it('should getEnergyPrices from fullNode', async function () { + const prices = await tronWeb.trx.getEnergyPrices(); + assert.isString(prices); + }) + }) });