@faast/tron-payments
Version:
Library to assist in processing tron payments, such as deriving addresses and sweeping funds
797 lines (780 loc) • 28.6 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var TronWeb = _interopDefault(require('tronweb'));
var lodash = require('lodash');
var bip32 = require('bip32');
var jsSha3 = require('js-sha3');
var jsSHA = _interopDefault(require('jssha'));
var elliptic = require('elliptic');
var crypto = _interopDefault(require('crypto'));
var t = require('io-ts');
var tsCommon = require('@faast/ts-common');
var paymentsCommon = require('@faast/payments-common');
const PACKAGE_NAME = 'tron-payments';
const MIN_BALANCE_SUN = 100000;
const MIN_BALANCE_TRX = MIN_BALANCE_SUN / 1e6;
const DECIMAL_PLACES = 6;
const DEFAULT_FULL_NODE = process.env.TRX_FULL_NODE_URL || 'https://api.trongrid.io';
const DEFAULT_SOLIDITY_NODE = process.env.TRX_SOLIDITY_NODE_URL || 'https://api.trongrid.io';
const DEFAULT_EVENT_SERVER = process.env.TRX_EVENT_SERVER_URL || 'https://api.trongrid.io';
const DEFAULT_FEE_LEVEL = paymentsCommon.FeeLevel.Medium;
const { toMainDenominationBigNumber, toMainDenominationString, toMainDenominationNumber, toBaseDenominationBigNumber, toBaseDenominationString, toBaseDenominationNumber, } = paymentsCommon.createUnitConverters(DECIMAL_PLACES);
function isValidXprv(xprv) {
return xprv.startsWith('xprv');
}
function isValidXpub(xpub) {
return xpub.startsWith('xpub');
}
function isValidAddress(address) {
return TronWeb.isAddress(address);
}
function isValidExtraId(extraId) {
return false;
}
function isValidPayport(payport) {
if (!paymentsCommon.Payport.is(payport)) {
return false;
}
const { address, extraId } = payport;
return isValidAddress(address) && (tsCommon.isNil(extraId) ? true : isValidExtraId(extraId));
}
function isValidPrivateKey(privateKey) {
try {
privateKeyToAddress(privateKey);
return true;
}
catch (e) {
return false;
}
}
function privateKeyToAddress(privateKey) {
const address = TronWeb.address.fromPrivateKey(privateKey);
if (isValidAddress(address)) {
return address;
}
else {
throw new Error('Validation failed for address derived from private key');
}
}
function toError(e) {
if (typeof e === 'string') {
return new Error(e);
}
return e;
}
class TronPaymentsUtils {
constructor(config = {}) {
this.isValidXprv = isValidXprv;
this.isValidXpub = isValidXpub;
this.isValidPrivateKey = isValidPrivateKey;
this.privateKeyToAddress = privateKeyToAddress;
tsCommon.assertType(paymentsCommon.BaseConfig, config);
this.networkType = config.network || paymentsCommon.NetworkType.Mainnet;
this.logger = new tsCommon.DelegateLogger(config.logger, PACKAGE_NAME);
}
async isValidExtraId(extraId) {
return isValidExtraId(extraId);
}
async isValidAddress(address) {
return isValidAddress(address);
}
async isValidPayport(payport) {
return isValidPayport(payport);
}
toMainDenomination(amount) {
return toMainDenominationString(amount);
}
toBaseDenomination(amount) {
return toBaseDenominationString(amount);
}
}
class BaseTronPayments extends TronPaymentsUtils {
constructor(config) {
super(config);
this.fullNode = config.fullNode || DEFAULT_FULL_NODE;
this.solidityNode = config.solidityNode || DEFAULT_SOLIDITY_NODE;
this.eventServer = config.eventServer || DEFAULT_EVENT_SERVER;
this.logger = new tsCommon.DelegateLogger(config.logger, PACKAGE_NAME);
this.tronweb = new TronWeb(this.fullNode, this.solidityNode, this.eventServer);
}
requiresBalanceMonitor() {
return false;
}
async getBalance(resolveablePayport) {
try {
const payport = await this.resolvePayport(resolveablePayport);
const balanceSun = await this.tronweb.trx.getBalance(payport.address);
this.logger.debug(`trx.getBalance(${payport.address}) -> ${balanceSun}`);
const sweepable = this.canSweepBalance(balanceSun);
return {
confirmedBalance: this.toMainDenomination(balanceSun).toString(),
unconfirmedBalance: '0',
sweepable,
};
}
catch (e) {
throw toError(e);
}
}
async resolveFeeOption(feeOption) {
let targetFeeLevel;
if (tsCommon.isType(paymentsCommon.FeeOptionCustom, feeOption)) {
if (feeOption.feeRate !== '0') {
throw new Error('tron-payments custom fees are unsupported');
}
targetFeeLevel = paymentsCommon.FeeLevel.Custom;
}
else {
targetFeeLevel = feeOption.feeLevel || DEFAULT_FEE_LEVEL;
}
return {
targetFeeLevel,
targetFeeRate: '0',
targetFeeRateType: paymentsCommon.FeeRateType.Base,
feeBase: '0',
feeMain: '0',
};
}
async createSweepTransaction(from, to, options = {}) {
this.logger.debug('createSweepTransaction', from, to);
try {
const { fromAddress, fromIndex, fromPayport, toAddress, toIndex } = await this.resolveFromTo(from, to);
const { targetFeeLevel, targetFeeRate, targetFeeRateType, feeBase, feeMain } = await this.resolveFeeOption(options);
const feeSun = Number.parseInt(feeBase);
const { confirmedBalance: balanceTrx } = await this.getBalance(fromPayport);
const balanceSun = toBaseDenominationNumber(balanceTrx);
if (!this.canSweepBalance(balanceSun)) {
throw new Error(`Insufficient balance (${balanceTrx}) to sweep with fee of ${feeMain} ` +
`while maintaining a minimum required balance of ${MIN_BALANCE_TRX}`);
}
const amountSun = balanceSun - feeSun - MIN_BALANCE_SUN;
const amountTrx = this.toMainDenomination(amountSun);
const tx = await this.tronweb.transactionBuilder.sendTrx(toAddress, amountSun, fromAddress);
return {
id: tx.txID,
fromAddress,
toAddress,
toExtraId: null,
fromIndex,
toIndex,
amount: amountTrx,
fee: feeMain,
targetFeeLevel,
targetFeeRate,
targetFeeRateType,
status: paymentsCommon.TransactionStatus.Unsigned,
data: tx,
};
}
catch (e) {
throw toError(e);
}
}
async createTransaction(from, to, amountTrx, options = {}) {
this.logger.debug('createTransaction', from, to, amountTrx);
try {
const { fromAddress, fromIndex, fromPayport, toAddress, toIndex } = await this.resolveFromTo(from, to);
const { targetFeeLevel, targetFeeRate, targetFeeRateType, feeBase, feeMain } = await this.resolveFeeOption(options);
const feeSun = Number.parseInt(feeBase);
const { confirmedBalance: balanceTrx } = await this.getBalance(fromPayport);
const balanceSun = toBaseDenominationNumber(balanceTrx);
const amountSun = toBaseDenominationNumber(amountTrx);
if (balanceSun - feeSun - MIN_BALANCE_SUN < amountSun) {
throw new Error(`Insufficient balance (${balanceTrx}) to send ${amountTrx} including fee of ${feeMain} ` +
`while maintaining a minimum required balance of ${MIN_BALANCE_TRX}`);
}
const tx = await this.tronweb.transactionBuilder.sendTrx(toAddress, amountSun, fromAddress);
return {
id: tx.txID,
fromAddress,
toAddress,
toExtraId: null,
fromIndex,
toIndex,
amount: amountTrx,
fee: feeMain,
targetFeeLevel,
targetFeeRate,
targetFeeRateType,
status: paymentsCommon.TransactionStatus.Unsigned,
data: tx,
};
}
catch (e) {
throw toError(e);
}
}
async signTransaction(unsignedTx) {
try {
const fromPrivateKey = await this.getPrivateKey(unsignedTx.fromIndex);
const unsignedRaw = lodash.cloneDeep(unsignedTx.data);
const signedTx = await this.tronweb.trx.sign(unsignedRaw, fromPrivateKey);
return {
...unsignedTx,
status: paymentsCommon.TransactionStatus.Signed,
data: signedTx,
};
}
catch (e) {
throw toError(e);
}
}
async broadcastTransaction(tx) {
try {
const status = await this.tronweb.trx.sendRawTransaction(tx.data);
let success = false;
let rebroadcast = false;
if (status.result || status.code === 'SUCCESS') {
success = true;
}
else {
try {
await this.tronweb.trx.getTransaction(tx.id);
success = true;
rebroadcast = true;
}
catch (e) { }
}
if (success) {
return {
id: tx.id,
rebroadcast,
};
}
else {
let statusCode = status.code;
if (statusCode === 'DUP_TRANSACTION_ERROR') {
statusCode = 'DUP_TX_BUT_TX_NOT_FOUND_SO_PROBABLY_INVALID_TX_ERROR';
}
this.logger.warn(`Tron broadcast tx unsuccessful ${tx.id}`, status);
throw new Error(`Failed to broadcast transaction: ${statusCode} ${status.message}`);
}
}
catch (e) {
throw toError(e);
}
}
async getTransactionInfo(txid) {
try {
const [tx, txInfo, currentBlock] = await Promise.all([
this.tronweb.trx.getTransaction(txid),
this.tronweb.trx.getTransactionInfo(txid),
this.tronweb.trx.getCurrentBlock(),
]);
const { amountTrx, fromAddress, toAddress } = this.extractTxFields(tx);
const contractRet = lodash.get(tx, 'ret[0].contractRet');
const isExecuted = contractRet === 'SUCCESS';
const block = txInfo.blockNumber || null;
const feeTrx = this.toMainDenomination(txInfo.fee || 0);
const currentBlockNumber = lodash.get(currentBlock, 'block_header.raw_data.number', 0);
const confirmations = currentBlockNumber && block ? currentBlockNumber - block : 0;
const isConfirmed = confirmations > 0;
const confirmationTimestamp = txInfo.blockTimeStamp ? new Date(txInfo.blockTimeStamp) : null;
let status = paymentsCommon.TransactionStatus.Pending;
if (isConfirmed) {
if (!isExecuted) {
status = paymentsCommon.TransactionStatus.Failed;
}
status = paymentsCommon.TransactionStatus.Confirmed;
}
return {
id: tx.txID,
amount: amountTrx,
toAddress,
fromAddress,
toExtraId: null,
fromIndex: null,
toIndex: null,
fee: feeTrx,
isExecuted,
isConfirmed,
confirmations,
confirmationId: block ? String(block) : null,
confirmationTimestamp,
status,
data: {
...tx,
...txInfo,
currentBlock: lodash.pick(currentBlock, 'block_header', 'blockID'),
},
};
}
catch (e) {
throw toError(e);
}
}
canSweepBalance(balanceSun) {
return balanceSun > MIN_BALANCE_SUN;
}
extractTxFields(tx) {
const contractParam = lodash.get(tx, 'raw_data.contract[0].parameter.value');
if (!(contractParam && typeof contractParam.amount === 'number')) {
throw new Error('Unable to get transaction');
}
const amountSun = contractParam.amount || 0;
const amountTrx = this.toMainDenomination(amountSun);
const toAddress = this.tronweb.address.fromHex(contractParam.to_address);
const fromAddress = this.tronweb.address.fromHex(contractParam.owner_address);
return {
amountTrx,
amountSun,
toAddress,
fromAddress,
};
}
async resolvePayport(payport) {
if (typeof payport === 'number') {
return this.getPayport(payport);
}
else if (typeof payport === 'string') {
if (!isValidAddress(payport)) {
throw new Error(`Invalid TRON address: ${payport}`);
}
return { address: payport };
}
if (!isValidPayport(payport)) {
throw new Error(`Invalid TRON payport: ${JSON.stringify(payport)}`);
}
return payport;
}
async resolveFromTo(from, to) {
const fromPayport = await this.getPayport(from);
const toPayport = await this.resolvePayport(to);
return {
fromAddress: fromPayport.address,
fromIndex: from,
fromExtraId: fromPayport.extraId,
fromPayport,
toAddress: toPayport.address,
toIndex: typeof to === 'number' ? to : null,
toExtraId: toPayport.extraId,
toPayport,
};
}
}
class Bip44Cache {
constructor() {
this.store = {};
}
put(xpub, index, address) {
lodash.set(this.store, [xpub, 'addresses', index], address);
lodash.set(this.store, [xpub, 'indices', address], index);
}
lookupIndex(xpub, address) {
return lodash.get(this.store, [xpub, 'indices', address]);
}
lookupAddress(xpub, index) {
return lodash.get(this.store, [xpub, 'addresses', index]);
}
}
const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
const ALPHABET_MAP = {};
for (let i = 0; i < ALPHABET.length; i++) {
ALPHABET_MAP[ALPHABET.charAt(i)] = i;
}
const BASE = 58;
function encode58(buffer) {
if (buffer.length === 0) {
return '';
}
let i;
let j;
const digits = [0];
for (i = 0; i < buffer.length; i++) {
for (j = 0; j < digits.length; j++) {
digits[j] <<= 8;
}
digits[0] += buffer[i];
let carry = 0;
for (j = 0; j < digits.length; ++j) {
digits[j] += carry;
carry = (digits[j] / BASE) | 0;
digits[j] %= BASE;
}
while (carry) {
digits.push(carry % BASE);
carry = (carry / BASE) | 0;
}
}
for (i = 0; buffer[i] === 0 && i < buffer.length - 1; i++) {
digits.push(0);
}
return digits
.reverse()
.map(digit => ALPHABET[digit])
.join('');
}
function decode58(s) {
if (s.length === 0) {
return [];
}
let i;
let j;
const bytes = [0];
for (i = 0; i < s.length; i++) {
const c = s[i];
if (!(c in ALPHABET_MAP)) {
throw new Error('Non-base58 character');
}
for (j = 0; j < bytes.length; j++) {
bytes[j] *= BASE;
}
bytes[0] += ALPHABET_MAP[c];
let carry = 0;
for (j = 0; j < bytes.length; ++j) {
bytes[j] += carry;
carry = bytes[j] >> 8;
bytes[j] &= 0xff;
}
while (carry) {
bytes.push(carry & 0xff);
carry >>= 8;
}
}
for (i = 0; s[i] === '1' && i < s.length - 1; i++) {
bytes.push(0);
}
return bytes.reverse();
}
const ec = new elliptic.ec('secp256k1');
const derivationPath = "m/44'/195'/0'";
const derivationPathParts = derivationPath.split('/').slice(1);
function deriveAddress(xpub, index) {
if (!isValidXpub(xpub)) {
throw new Error('Invalid xpub');
}
const key = bip32.fromBase58(xpub);
const derived = deriveBasePath(key)
.derive(0)
.derive(index);
return hdPublicKeyToAddress(derived);
}
function derivePrivateKey(xprv, index) {
if (!isValidXprv(xprv)) {
throw new Error('Invalid xprv');
}
const key = bip32.fromBase58(xprv);
const derived = deriveBasePath(key)
.derive(0)
.derive(index);
return hdPrivateKeyToPrivateKey(derived);
}
function xprvToXpub(xprv) {
const key = typeof xprv === 'string' ? bip32.fromBase58(xprv) : xprv;
const derivedPubKey = deriveBasePath(key);
return derivedPubKey.neutered().toBase58();
}
function generateNewKeys() {
const key = bip32.fromSeed(crypto.randomBytes(32));
const xprv = key.toBase58();
const xpub = xprvToXpub(xprv);
return {
xprv,
xpub,
};
}
function deriveBasePath(key) {
const parts = derivationPathParts.slice(key.depth);
if (parts.length > 0) {
return key.derivePath(`m/${parts.join('/')}`);
}
return key;
}
function hdPublicKeyToAddress(key) {
return addressBytesToB58CheckAddress(pubBytesToTronBytes(bip32PublicToTronPublic(key.publicKey)));
}
function hdPrivateKeyToPrivateKey(key) {
if (key.isNeutered() || typeof key.privateKey === 'undefined') {
throw new Error('Invalid HD private key, must not be neutered');
}
return bip32PrivateToTronPrivate(key.privateKey);
}
function bip32PublicToTronPublic(pubKey) {
const pubkey = ec.keyFromPublic(pubKey).getPublic();
const x = pubkey.x;
const y = pubkey.y;
let xHex = x.toString('hex');
while (xHex.length < 64) {
xHex = `0${xHex}`;
}
let yHex = y.toString('hex');
while (yHex.length < 64) {
yHex = `0${yHex}`;
}
const pubkeyHex = `04${xHex}${yHex}`;
const pubkeyBytes = hexStr2byteArray(pubkeyHex);
return pubkeyBytes;
}
function bip32PrivateToTronPrivate(priKeyBytes) {
const key = ec.keyFromPrivate(priKeyBytes, 'bytes');
const privkey = key.getPrivate();
let priKeyHex = privkey.toString('hex');
while (priKeyHex.length < 64) {
priKeyHex = `0${priKeyHex}`;
}
let privArray = hexStr2byteArray(priKeyHex);
return byteArray2hexStr(privArray);
}
const ADDRESS_PREFIX = '41';
function byte2hexStr(byte) {
const hexByteMap = '0123456789ABCDEF';
let str = '';
str += hexByteMap.charAt(byte >> 4);
str += hexByteMap.charAt(byte & 0x0f);
return str;
}
function hexStr2byteArray(str) {
const byteArray = Array();
let d = 0;
let j = 0;
let k = 0;
for (let i = 0; i < str.length; i++) {
const c = str.charAt(i);
if (isHexChar(c)) {
d <<= 4;
d += hexChar2byte(c);
j++;
if (0 === j % 2) {
byteArray[k++] = d;
d = 0;
}
}
}
return byteArray;
}
function isHexChar(c) {
return (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9');
}
function hexChar2byte(c) {
let d = 0;
if (c >= 'A' && c <= 'F') {
d = c.charCodeAt(0) - 'A'.charCodeAt(0) + 10;
}
else if (c >= 'a' && c <= 'f') {
d = c.charCodeAt(0) - 'a'.charCodeAt(0) + 10;
}
else if (c >= '0' && c <= '9') {
d = c.charCodeAt(0) - '0'.charCodeAt(0);
}
return d;
}
function byteArray2hexStr(byteArray) {
let str = '';
for (let i = 0; i < byteArray.length; i++) {
str += byte2hexStr(byteArray[i]);
}
return str;
}
function pubBytesToTronBytes(pubBytes) {
if (pubBytes.length === 65) {
pubBytes = pubBytes.slice(1);
}
const hash = jsSha3.keccak256(pubBytes).toString();
const addressHex = ADDRESS_PREFIX + hash.substring(24);
return hexStr2byteArray(addressHex);
}
function addressBytesToB58CheckAddress(addressBytes) {
const hash0 = SHA256(addressBytes);
const hash1 = SHA256(hash0);
let checkSum = hash1.slice(0, 4);
checkSum = addressBytes.concat(checkSum);
return encode58(checkSum);
}
function SHA256(msgBytes) {
const shaObj = new jsSHA('SHA-256', 'HEX');
const msgHex = byteArray2hexStr(msgBytes);
shaObj.update(msgHex);
const hashHex = shaObj.getHash('HEX');
return hexStr2byteArray(hashHex);
}
const xpubCache = new Bip44Cache();
class HdTronPayments extends BaseTronPayments {
constructor(config) {
super(config);
this.config = config;
if (isValidXprv(config.hdKey)) {
this.xprv = config.hdKey;
this.xpub = xprvToXpub(this.xprv);
}
else if (isValidXpub(config.hdKey)) {
this.xprv = null;
this.xpub = config.hdKey;
}
else {
throw new Error('Account must be a valid xprv or xpub');
}
}
getXpub() {
return this.xpub;
}
getFullConfig() {
return this.config;
}
getPublicConfig() {
return {
...this.config,
hdKey: this.getXpub(),
};
}
getAccountId(index) {
return this.getXpub();
}
getAccountIds() {
return [this.getXpub()];
}
async getPayport(index, options = {}) {
const cacheIndex = options.cacheIndex || true;
const xpub = this.getXpub();
const address = deriveAddress(xpub, index);
if (!isValidAddress(address)) {
throw new Error(`Cannot get address ${index} - validation failed for derived address`);
}
if (cacheIndex) {
xpubCache.put(xpub, index, address);
}
return { address };
}
async getPrivateKey(index) {
if (!this.xprv) {
throw new Error(`Cannot get private key ${index} - HdTronPayments was created with an xpub`);
}
return derivePrivateKey(this.xprv, index);
}
}
HdTronPayments.generateNewKeys = generateNewKeys;
class KeyPairTronPayments extends BaseTronPayments {
constructor(config) {
super(config);
this.config = config;
this.addresses = {};
this.privateKeys = {};
this.addressIndices = {};
Object.entries(config.keyPairs).forEach(([iString, addressOrKey]) => {
if (typeof addressOrKey === 'undefined' || addressOrKey === null) {
return;
}
const i = Number.parseInt(iString);
if (isValidAddress(addressOrKey)) {
this.addresses[i] = addressOrKey;
this.privateKeys[i] = null;
this.addressIndices[addressOrKey] = i;
return;
}
if (isValidPrivateKey(addressOrKey)) {
const address = privateKeyToAddress(addressOrKey);
this.addresses[i] = address;
this.privateKeys[i] = addressOrKey;
this.addressIndices[address] = i;
return;
}
throw new Error(`KeyPairTronPaymentsConfig.keyPairs[${i}] is not a valid private key or address`);
});
}
getFullConfig() {
return this.config;
}
getPublicConfig() {
return {
...this.config,
keyPairs: this.addresses,
};
}
getAccountId(index) {
const accountId = this.addresses[index];
if (!accountId) {
throw new Error(`No KeyPairTronPayments account configured at index ${index}`);
}
return accountId;
}
getAccountIds() {
return Object.keys(this.addressIndices);
}
async getPayport(index) {
const address = this.addresses[index];
if (typeof address === 'undefined') {
throw new Error(`Cannot get address ${index} - keyPair[${index}] is undefined`);
}
return { address };
}
async getPrivateKey(index) {
const privateKey = this.privateKeys[index];
if (typeof privateKey === 'undefined') {
throw new Error(`Cannot get private key ${index} - keyPair[${index}] is undefined`);
}
if (privateKey === null) {
throw new Error(`Cannot get private key ${index} - keyPair[${index}] is a public address`);
}
return privateKey;
}
}
const BaseTronPaymentsConfig = tsCommon.extendCodec(paymentsCommon.BaseConfig, {}, {
fullNode: t.string,
solidityNode: t.string,
eventServer: t.string,
logger: tsCommon.Logger,
}, 'BaseTronPaymentsConfig');
const HdTronPaymentsConfig = tsCommon.extendCodec(BaseTronPaymentsConfig, {
hdKey: t.string,
}, 'HdTronPaymentsConfig');
const NullableOptionalString = t.union([t.string, t.null, t.undefined]);
const KeyPairTronPaymentsConfig = tsCommon.extendCodec(BaseTronPaymentsConfig, {
keyPairs: t.union([t.array(NullableOptionalString), t.record(t.number, NullableOptionalString)]),
}, 'KeyPairTronPaymentsConfig');
const TronPaymentsConfig = t.union([HdTronPaymentsConfig, KeyPairTronPaymentsConfig], 'TronPaymentsConfig');
const TronUnsignedTransaction = tsCommon.extendCodec(paymentsCommon.BaseUnsignedTransaction, {
id: t.string,
amount: t.string,
fee: t.string,
}, 'TronUnsignedTransaction');
const TronSignedTransaction = tsCommon.extendCodec(paymentsCommon.BaseSignedTransaction, {}, {}, 'TronSignedTransaction');
const TronTransactionInfo = tsCommon.extendCodec(paymentsCommon.BaseTransactionInfo, {}, {}, 'TronTransactionInfo');
const TronBroadcastResult = tsCommon.extendCodec(paymentsCommon.BaseBroadcastResult, {
rebroadcast: t.boolean,
}, 'TronBroadcastResult');
const GetPayportOptions = t.partial({
cacheIndex: t.boolean,
});
class TronPaymentsFactory {
forConfig(config) {
if (HdTronPaymentsConfig.is(config)) {
return new HdTronPayments(config);
}
if (KeyPairTronPaymentsConfig.is(config)) {
return new KeyPairTronPayments(config);
}
throw new Error('Cannot instantiate tron payments for unsupported config');
}
}
exports.CreateTransactionOptions = paymentsCommon.CreateTransactionOptions;
exports.BaseTronPayments = BaseTronPayments;
exports.HdTronPayments = HdTronPayments;
exports.KeyPairTronPayments = KeyPairTronPayments;
exports.TronPaymentsFactory = TronPaymentsFactory;
exports.TronPaymentsUtils = TronPaymentsUtils;
exports.BaseTronPaymentsConfig = BaseTronPaymentsConfig;
exports.HdTronPaymentsConfig = HdTronPaymentsConfig;
exports.KeyPairTronPaymentsConfig = KeyPairTronPaymentsConfig;
exports.TronPaymentsConfig = TronPaymentsConfig;
exports.TronUnsignedTransaction = TronUnsignedTransaction;
exports.TronSignedTransaction = TronSignedTransaction;
exports.TronTransactionInfo = TronTransactionInfo;
exports.TronBroadcastResult = TronBroadcastResult;
exports.GetPayportOptions = GetPayportOptions;
exports.toError = toError;
exports.derivationPath = derivationPath;
exports.deriveAddress = deriveAddress;
exports.derivePrivateKey = derivePrivateKey;
exports.xprvToXpub = xprvToXpub;
exports.generateNewKeys = generateNewKeys;
exports.encode58 = encode58;
exports.decode58 = decode58;
exports.PACKAGE_NAME = PACKAGE_NAME;
exports.MIN_BALANCE_SUN = MIN_BALANCE_SUN;
exports.MIN_BALANCE_TRX = MIN_BALANCE_TRX;
exports.DECIMAL_PLACES = DECIMAL_PLACES;
exports.DEFAULT_FULL_NODE = DEFAULT_FULL_NODE;
exports.DEFAULT_SOLIDITY_NODE = DEFAULT_SOLIDITY_NODE;
exports.DEFAULT_EVENT_SERVER = DEFAULT_EVENT_SERVER;
exports.DEFAULT_FEE_LEVEL = DEFAULT_FEE_LEVEL;
//# sourceMappingURL=index.cjs.js.map