@tatumio/tron-connector
Version:
Tron Connector for Tatum API
281 lines (280 loc) • 12.8 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TronService = void 0;
const axios_1 = __importDefault(require("axios"));
const tatum_1 = require("@tatumio/tatum");
const TronError_1 = require("./TronError");
class TronService {
constructor(logger) {
this.logger = logger;
}
static mapTransaction(t) {
var _a;
if (t.internal_tx_id) {
return { ...t, fromAddressBase58: tatum_1.convertAddressFromHex(t.from_address), toAddressBase58: tatum_1.convertAddressFromHex(t.to_address) };
}
const rawData = { ...t.raw_data };
rawData.contract = ((_a = rawData.contract) === null || _a === void 0 ? void 0 : _a.map(c => ({
...c,
parameter: {
...c.parameter,
value: {
...c.parameter.value,
ownerAddressBase58: tatum_1.convertAddressFromHex(c.parameter.value.owner_address),
toAddressBase58: tatum_1.convertAddressFromHex(c.parameter.value.to_address),
contractAddressBase58: tatum_1.convertAddressFromHex(c.parameter.value.contract_address),
}
}
}))) || [];
return {
ret: t.ret,
signature: t.signature,
blockNumber: t.blockNumber,
txID: t.txID,
netFee: t.net_fee,
netUsage: t.net_usage,
energyFee: t.energy_fee,
energyUsage: t.energy_usage,
energyUsageTotal: t.energy_usage_total,
internalTransactions: t.internal_transactions,
rawData: rawData,
log: t.log,
};
}
static mapTransaction20(t) {
return {
txID: t.transaction_id,
tokenInfo: t.token_info,
from: t.from,
to: t.to,
type: t.type,
value: t.value,
};
}
async getNodeAddress() {
return (await this.isTestnet()) ? 'https://api.shasta.trongrid.io' : 'https://api.trongrid.io';
}
async broadcast(txData, signatureId) {
var _a;
const transaction = JSON.parse(txData);
if (Date.now() > ((_a = transaction === null || transaction === void 0 ? void 0 : transaction.raw_data) === null || _a === void 0 ? void 0 : _a.expiration)) {
throw new TronError_1.TronError('Transaction expired', 'tron.error');
}
const url = (await this.getNodesUrl(await this.isTestnet()))[0];
const broadcast = (await axios_1.default.post(`${url}/wallet/broadcasttransaction`, transaction, { headers: { 'TRON-PRO-API-KEY': this.getApiKey() } })).data;
if (broadcast.result) {
if (signatureId) {
try {
await this.completeKMSTransaction(broadcast.txid, signatureId);
}
catch (e) {
this.logger.error(e);
return { txId: broadcast.txid, failed: true };
}
}
return { txId: broadcast.txid };
}
let msg = broadcast.message;
try {
msg = Buffer.from(msg, 'hex').toString();
}
catch (e) {
}
throw new TronError_1.TronError(`Broadcast failed due to ${msg}`, 'tron.error');
}
async getBlockChainInfo(testnet) {
let t;
let apiKey;
if (testnet !== undefined) {
t = testnet;
apiKey = this.getScanningApiKey();
}
else {
t = await this.isTestnet();
apiKey = this.getApiKey();
}
const urls = await this.getNodesUrl(t);
const block = (await axios_1.default.post(urls[0] + '/wallet/getnowblock', undefined, { headers: { 'TRON-PRO-API-KEY': apiKey } })).data;
return { testnet: t, hash: block.blockID, blockNumber: block.block_header.raw_data.number };
}
async getBlock(hashOrHeight, testnet) {
var _a;
let t;
let apiKey;
if (testnet !== undefined) {
t = testnet;
apiKey = this.getScanningApiKey();
}
else {
t = await this.isTestnet();
apiKey = this.getApiKey();
}
const url = (await this.getNodesUrl(t))[0];
let block;
if (hashOrHeight.length > 32) {
block = (await axios_1.default.post(`${url}/wallet/getblockbyid`, { value: hashOrHeight }, { headers: { 'TRON-PRO-API-KEY': apiKey } })).data;
}
else {
block = (await axios_1.default.post(`${url}/wallet/getblockbynum`, { num: parseInt(hashOrHeight) }, { headers: { 'TRON-PRO-API-KEY': apiKey } })).data;
}
return {
blockNumber: block.block_header.raw_data.number,
hash: block.blockID,
parentHash: block.block_header.raw_data.parentHash,
timestamp: block.block_header.raw_data.timestamp,
witnessAddress: block.block_header.raw_data.witness_address,
witnessSignature: block.block_header.witness_signature,
transactions: ((_a = block.transactions) === null || _a === void 0 ? void 0 : _a.map(TronService.mapTransaction)) || [],
};
}
async getTransaction(txId, testnet) {
const url = (await this.getNodesUrl(testnet !== undefined ? testnet : await this.isTestnet()))[0];
let apiKey1, apiKey2;
if (testnet !== undefined) {
apiKey1 = this.getScanningApiKey();
apiKey2 = this.getScanningApiKey();
}
else {
apiKey1 = this.getApiKey();
apiKey2 = this.getApiKey();
}
const [{ data: tx }, { data: info }] = await Promise.all([axios_1.default.post(`${url}/wallet/gettransactionbyid`, { value: txId }, { headers: { 'TRON-PRO-API-KEY': apiKey1 } }),
axios_1.default.post(`${url}/wallet/gettransactioninfobyid`, { value: txId }, { headers: { 'TRON-PRO-API-KEY': apiKey2 } })]);
return TronService.mapTransaction({ ...tx, ...info.receipt, log: info.log, blockNumber: info.blockNumber });
}
async getAccount(address) {
const url = await this.getNodeAddress();
const { data } = (await axios_1.default.get(`${url}/v1/accounts/${address}`, { headers: { 'TRON-PRO-API-KEY': this.getApiKey() } })).data;
if (!(data === null || data === void 0 ? void 0 : data.length)) {
throw new TronError_1.TronError('no such account.', 'tron.error');
}
const account = data[0];
return {
address: account.add,
assetIssuedId: account.asset_issued_ID,
assetIssuedName: account.asset_issued_name,
balance: account.balance,
createTime: account.create_time,
freeNetUsage: account.free_net_usage,
trc10: account.assetV2,
trc20: account.trc20,
};
}
async getTransactionsByAccount(address, next) {
var _a;
const url = await this.getNodeAddress();
let u = `${url}/v1/accounts/${address}/transactions?limit=200`;
if (next) {
u += '&fingerprint=' + next;
}
const result = (await axios_1.default.get(u, { headers: { 'TRON-PRO-API-KEY': this.getApiKey() } })).data;
return {
transactions: result.data.map(TronService.mapTransaction).filter(t => !t.internal_tx_id),
internalTransactions: result.data.map(TronService.mapTransaction).filter(t => t.internal_tx_id),
next: (_a = result.meta) === null || _a === void 0 ? void 0 : _a.fingerprint
};
}
async getTrc20TransactionsByAccount(address, next) {
var _a;
const url = await this.getNodeAddress();
let u = `${url}/v1/accounts/${address}/transactions/trc20?limit=200`;
if (next) {
u += '&fingerprint=' + next;
}
const result = (await axios_1.default.get(u, { headers: { 'TRON-PRO-API-KEY': this.getApiKey() } })).data;
return {
transactions: result.data.map(TronService.mapTransaction20),
next: (_a = result.meta) === null || _a === void 0 ? void 0 : _a.fingerprint
};
}
async generateWallet(mnem) {
return tatum_1.generateWallet(tatum_1.Currency.TRON, await this.isTestnet(), mnem);
}
async generateAddress(xpub, i) {
return { address: await tatum_1.generateAddressFromXPub(tatum_1.Currency.TRON, await this.isTestnet(), xpub, i) };
}
async generatePrivateKey(mnemonic, i) {
return { key: await tatum_1.generatePrivateKeyFromMnemonic(tatum_1.Currency.TRON, await this.isTestnet(), mnemonic, i) };
}
async sendTransaction(body) {
const t = await this.isTestnet();
if (body.signatureId) {
const txData = await tatum_1.prepareTronSignedKMSTransaction(t, body, (await this.getNodesUrl(t))[0]);
return { signatureId: await this.storeKMSTransaction(txData, tatum_1.Currency.TRON, [body.signatureId], body.index) };
}
else {
return this.broadcast(await tatum_1.prepareTronSignedTransaction(t, body, (await this.getNodesUrl(t))[0]));
}
}
async sendTrc10Transaction(body) {
const t = await this.isTestnet();
if (body.signatureId) {
const txData = await tatum_1.prepareTronTrc10SignedKMSTransaction(t, body, undefined, (await this.getNodesUrl(t))[0]);
return { signatureId: await this.storeKMSTransaction(txData, tatum_1.Currency.TRON, [body.signatureId], body.index) };
}
else {
return this.broadcast(await tatum_1.prepareTronTrc10SignedTransaction(t, body, undefined, (await this.getNodesUrl(t))[0]));
}
}
async sendTrc20Transaction(body) {
const t = await this.isTestnet();
if (body.signatureId) {
const txData = await tatum_1.prepareTronTrc20SignedKMSTransaction(t, body, (await this.getNodesUrl(t))[0]);
return { signatureId: await this.storeKMSTransaction(txData, tatum_1.Currency.TRON, [body.signatureId], body.index) };
}
else {
return this.broadcast(await tatum_1.prepareTronTrc20SignedTransaction(t, body, (await this.getNodesUrl(t))[0]));
}
}
async createTrc10Transaction(body) {
const t = await this.isTestnet();
if (body.signatureId) {
const txData = await tatum_1.prepareTronCreateTrc10SignedKMSTransaction(t, body, (await this.getNodesUrl(t))[0]);
return { signatureId: await this.storeKMSTransaction(txData, tatum_1.Currency.TRON, [body.signatureId], body.index) };
}
else {
return this.broadcast(await tatum_1.prepareTronCreateTrc10SignedTransaction(t, body, (await this.getNodesUrl(t))[0]));
}
}
async createTrc20Transaction(body) {
const t = await this.isTestnet();
if (body.signatureId) {
const txData = await tatum_1.prepareTronCreateTrc20SignedKMSTransaction(t, body, (await this.getNodesUrl(t))[0]);
return { signatureId: await this.storeKMSTransaction(txData, tatum_1.Currency.TRON, [body.signatureId], body.index) };
}
else {
return this.broadcast(await tatum_1.prepareTronCreateTrc20SignedTransaction(t, body, (await this.getNodesUrl(t))[0]));
}
}
async freezeBalance(body) {
const t = await this.isTestnet();
if (body.signatureId) {
const txData = await tatum_1.prepareTronFreezeKMSTransaction(t, body, (await this.getNodesUrl(t))[0]);
return { signatureId: await this.storeKMSTransaction(txData, tatum_1.Currency.TRON, [body.signatureId], body.index) };
}
else {
return this.broadcast(await tatum_1.prepareTronFreezeTransaction(t, body, (await this.getNodesUrl(t))[0]));
}
}
async getTrc10Detail(id) {
const url = `${(await this.getNodeAddress())}/v1/assets/${id}`;
const { data } = (await axios_1.default.get(url, { headers: { 'TRON-PRO-API-KEY': this.getApiKey() } })).data;
if (!(data === null || data === void 0 ? void 0 : data.length)) {
throw new TronError_1.TronError('No such asset.', 'tron.error');
}
return {
abbr: data[0].abbr,
description: data[0].description,
id: data[0].id,
name: data[0].name,
ownerAddress: data[0].owner_address,
precision: data[0].precision,
totalSupply: data[0].total_supply,
url: data[0].url,
};
}
}
exports.TronService = TronService;