Skip to content

Commit

Permalink
Merge pull request #274 from tronprotocol/develop
Browse files Browse the repository at this point in the history
Release v4.3.0
  • Loading branch information
llwslc authored Aug 10, 2022
2 parents 15543c6 + dfb5103 commit 2d3b0d1
Show file tree
Hide file tree
Showing 15 changed files with 759 additions and 257 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ indent_size = 4

[*.js]
indent_size = 4
quote_type = single

[*.html]
indent_size = 4
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ In order to contribute you can

## Recent History

__4.3.0__
- Support `_signTypedData`

__4.2.0__
- Add the name key when the `call()` and `send()` methods has only one return value
- Optimize the `TriggerConstantContract()` method
Expand Down Expand Up @@ -279,7 +282,7 @@ __2.5.4__
* Adds cache in Trx to cache Contracts locally and make the process more efficient

__2.5.2__
* Adds static methods `Trx.signString` and `Trx.verifySignature
* Adds static methods `Trx.signString` and `Trx.verifySignature`

__2.5.0__
* Allows freeBandwidth, freeBandwidthLimit, frozenAmount and frozenDuration to be zero
Expand Down
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const basePlugins = [
'source-map-support'
];

const files = globby.sync([ 'test/**/*.test.js', '!test/**/abi.test.js' ]);
const files = globby.sync([ 'test/**/*.test.js', '!test/**/abi.test.js', '!test/**/typedData.test.js' ]);

module.exports = function (config) {
config.set({
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tronweb",
"version": "4.2.0",
"version": "4.3.0",
"description": "JavaScript SDK that encapsulates the TRON HTTP API",
"main": "dist/TronWeb.node.js",
"scripts": {
Expand Down
52 changes: 52 additions & 0 deletions src/lib/trx.js
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,37 @@ export default class Trx {
return base58Address == TronWeb.address.fromHex(address);
}

verifyTypedData(domain, types, value, signature, address = this.tronWeb.defaultAddress.base58, callback = false) {
if (utils.isFunction(address)) {
callback = address;
address = this.tronWeb.defaultAddress.base58;
}

if (!callback)
return this.injectPromise(this.verifyTypedData, domain, types, value, signature, address);

if (Trx.verifyTypedData(domain, types, value, signature, address))
return callback(null, true);

callback('Signature does not match');
}

static verifyTypedData(domain, types, value, signature, address) {
signature = signature.replace(/^0x/, '');

const messageDigest = utils._TypedDataEncoder.hash(domain, types, value);
const recovered = recoverAddress(messageDigest, {
recoveryParam: signature.substring(128, 130) == '1c' ? 1 : 0,
r: '0x' + signature.substring(0, 64),
s: '0x' + signature.substring(64, 128),
});

const tronAddress = ADDRESS_PREFIX + recovered.substr(2);
const base58Address = TronWeb.address.fromHex(tronAddress);

return base58Address == TronWeb.address.fromHex(address);
}

async sign(transaction = false, privateKey = this.tronWeb.defaultPrivateKey, useTronHeader = true, multisig = false, callback = false) {

if (utils.isFunction(multisig)) {
Expand Down Expand Up @@ -732,6 +763,27 @@ export default class Trx {
return signatureHex
}

_signTypedData(domain, types, value, privateKey = this.tronWeb.defaultPrivateKey, callback = false) {
if (utils.isFunction(privateKey)) {
callback = privateKey;
privateKey = this.tronWeb.defaultPrivateKey;
}

if (!callback)
return this.injectPromise(this._signTypedData, domain, types, value, privateKey);

try {
const signatureHex = Trx._signTypedData(domain, types, value, privateKey);
return callback(null, signatureHex);
} catch (ex) {
callback(ex);
}
}

static _signTypedData(domain, types, value, privateKey) {
return utils.crypto._signTypedData(domain, types, value, privateKey);
}

async multiSign(transaction = false, privateKey = this.tronWeb.defaultPrivateKey, permissionId = false, callback = false) {

if (utils.isFunction(permissionId)) {
Expand Down
23 changes: 22 additions & 1 deletion src/utils/crypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {base64DecodeFromString, hexStr2byteArray} from './code';
import {encode58, decode58} from './base58';
import {byte2hexStr, byteArray2hexStr} from './bytes';
import {ec as EC} from 'elliptic';
import {keccak256, sha256} from './ethersUtils';
import {keccak256, sha256, SigningKey} from './ethersUtils';
import {TypedDataEncoder} from './typedData';

export function getBase58CheckAddress(addressBytes) {
const hash0 = SHA256(addressBytes);
Expand Down Expand Up @@ -76,6 +77,26 @@ export function signBytes(privateKey, contents) {
return signBytes;
}

export function _signTypedData(domain, types, value, privateKey) {
const key = {
toHexString: function () {
return '0x' + privateKey;
},
value: privateKey,
};
const signingKey = new SigningKey(key);

const messageDigest = TypedDataEncoder.hash(domain, types, value);
const signature = signingKey.signDigest(messageDigest);
const signatureHex = [
'0x',
signature.r.substring(2),
signature.s.substring(2),
Number(signature.v).toString(16),
].join('');
return signatureHex;
}

export function getRowBytesFromTransactionBase64(base64Data) {
const bytesDecode = base64DecodeFromString(base64Data);
const transaction = proto.protocol.Transaction.deserializeBinary(bytesDecode);
Expand Down
4 changes: 4 additions & 0 deletions src/utils/ethersUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const AbiCoder = utils.AbiCoder;
const Interface = utils.Interface;
const FormatTypes = utils.FormatTypes;
const arrayify = utils.arrayify;
const splitSignature = utils.splitSignature;
const joinSignature = utils.joinSignature;

export {
keccak256,
Expand All @@ -21,5 +23,7 @@ export {
AbiCoder,
Interface,
FormatTypes,
splitSignature,
joinSignature,
arrayify
};
2 changes: 2 additions & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as crypto from './crypto';
import * as code from './code';
import * as abi from './abi';
import * as ethersUtils from './ethersUtils';
import {TypedDataEncoder as _TypedDataEncoder} from './typedData'

import validator from 'validator';
import BigNumber from 'bignumber.js';
Expand Down Expand Up @@ -150,5 +151,6 @@ export default {
bytes,
crypto,
abi,
_TypedDataEncoder,
ethersUtils
};
Loading

0 comments on commit 2d3b0d1

Please sign in to comment.