@tronlink/core
Version:
The library serves as a core module within TronLink Extension, which provides low-level wallet functionality for both Tron and Ethereum networks, primary features includes account generation and transaction signing
134 lines • 5.93 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EvmWallet = void 0;
// @ts-ignore
const bip39_1 = __importDefault(require("bip39"));
const hdkey_1 = require("ethereum-cryptography/hdkey");
const util_1 = require("@ethereumjs/util");
const ethers_1 = require("ethers");
const tx_1 = require("@ethereumjs/tx");
const common_1 = require("@ethereumjs/common");
const eth_sig_util_1 = require("eth-sig-util");
const base_wallet_1 = require("../base_wallet");
const constants_1 = require("../base_wallet/constants");
const util_2 = require("./util");
const utils_1 = require("../utils");
const error_1 = require("../base_wallet/error");
class EvmWallet extends base_wallet_1.BaseWallet {
getCoinType() {
return constants_1.CoinType.ETHER;
}
derivePrivateKey(params) {
const seed = bip39_1.default.mnemonicToSeed(params.mnemonic);
const hdWallet = hdkey_1.HDKey.fromMasterSeed(seed);
const wallet = hdWallet.derive(params.path);
const privateKey = (0, util_1.stripHexPrefix)((0, util_1.bufferToHex)(Buffer.from(wallet.privateKey)));
return privateKey;
}
getAddressBy(params) {
const strippedHexPrivateKey = (0, util_1.stripHexPrefix)(params.privateKey);
const evmPrivateKey = Buffer.from(strippedHexPrivateKey, 'hex');
const publicKey = (0, util_1.privateToPublic)(evmPrivateKey);
const evmAddress = (0, util_1.toChecksumAddress)((0, util_1.bufferToHex)((0, util_1.publicToAddress)(Buffer.from(publicKey), true)));
return evmAddress;
}
validateAddress(params) {
if (!params.address) {
return false;
}
return (0, util_1.isValidAddress)(params.address);
}
async sign(params) {
try {
(0, utils_1.checkSignParams)(params);
const { data } = params;
if (typeof data === 'string') {
return this.signMessage(params);
}
else if (typeof data === 'object' && data.domain && data.types && data.message) {
return this.signTypedData(params);
}
else if (typeof data === 'object' && !Array.isArray(data)) {
return this.signTransaction(params);
}
else {
throw new error_1.InvalidParameterError();
}
}
catch (error) {
throw new error_1.SignError(error.message);
}
}
async signMessage(param) {
if (typeof param.data !== 'string') {
throw new error_1.SignError('The "data" parameter of the function "signMessage" must be passed in string type');
}
const textMessage = (0, util_2.msgHexToText)(param.data);
const signature = (0, util_1.ecsign)((0, util_1.hashPersonalMessage)(Buffer.from(textMessage)), Buffer.from(param.privateKey, 'hex'));
const rawMsgSign = this.signedConvertRSVtoHex({
r: signature.r,
s: signature.s,
v: signature.v,
});
return rawMsgSign;
}
async signTransaction(params) {
const tx = tx_1.TransactionFactory.fromTxData(params.data.unSignedTransaction, {
common: params.data.common,
});
const hexPrivateKey = Buffer.from(params.privateKey, 'hex');
const signedTX = tx.sign(hexPrivateKey);
return signedTX;
}
verifyEthMessageSign(signature, message, expectAddress) {
const { r, s, v } = (0, util_1.fromRpcSig)(signature);
const publicKey = (0, util_1.ecrecover)((0, util_1.hashPersonalMessage)(Buffer.from((0, util_2.msgHexToText)(message))), v, r, s);
const address = (0, util_1.publicToAddress)(publicKey, true);
return `${address.toString('hex').toLowerCase()}` === expectAddress.slice(2).toLowerCase();
}
verifyEthTransactionSign(rawTransaction, rsvSignature, expectAddress) {
const serializedTransaction = ethers_1.ethers.utils.serializeTransaction(rawTransaction);
const txHash = ethers_1.ethers.utils.keccak256(serializedTransaction);
const recoveredAddress = ethers_1.ethers.utils.recoverAddress(txHash, rsvSignature);
return expectAddress.toLowerCase() === recoveredAddress.toLowerCase();
}
async signTypedData(params) {
if (typeof params.data === 'string') {
throw new error_1.SignError('The "data" parameter of the function "signTypedData" must be passed in type of a specific structure');
}
return (0, eth_sig_util_1.signTypedData_v4)(Buffer.from(params.privateKey, 'hex'), { data: params.data });
}
signedConvertRSVtoHex({ r, s, v }) {
const vBuffer = (0, util_1.bigIntToBuffer)(v);
const rHex = r.toString('hex');
const sHex = s.toString('hex');
const vHex = vBuffer.toString('hex');
const rPadded = rHex.padStart(64, '0');
const sPadded = sHex.padStart(64, '0');
const vPadded = vHex;
return `0x${rPadded}${sPadded}${vPadded}`;
}
getCommonConfiguration({ isSupportsEIP1559, chain, chainId, chainName, }) {
const hardfork = isSupportsEIP1559 ? common_1.Hardfork.London : common_1.Hardfork.Berlin;
if (chain && [common_1.Chain.Sepolia, common_1.Chain.Goerli, common_1.Chain.Mainnet].includes(chain)) {
return new common_1.Common({
chain,
hardfork,
});
}
else {
return common_1.Common.custom({
name: chainName,
chainId: parseInt(chainId, 16),
networkId: parseInt(chainId, 16),
// @ts-ignore
hardfork,
});
}
}
}
exports.EvmWallet = EvmWallet;
//# sourceMappingURL=EvmWallet.js.map