tronweb.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. import { providers } from './lib/providers/index.js';
  2. import utils from './utils/index.js';
  3. import { BigNumber } from 'bignumber.js';
  4. import EventEmitter from 'eventemitter3';
  5. import semver from 'semver';
  6. import { TransactionBuilder } from './lib/TransactionBuilder/TransactionBuilder.js';
  7. import { Trx } from './lib/trx.js';
  8. import { Contract } from './lib/contract/index.js';
  9. import { Plugin } from './lib/plugin.js';
  10. import { Event } from './lib/event.js';
  11. import { keccak256 } from './utils/ethersUtils.js';
  12. import { fromHex, fromPrivateKey, isAddress, toHex, toChecksumAddress, isChecksumAddress } from './utils/address.js';
  13. import { isString } from './utils/validations.js';
  14. const DEFAULT_VERSION = '4.7.1';
  15. const FEE_LIMIT = 150000000;
  16. const version = '6.0.3';
  17. function isValidOptions(options) {
  18. return (!!options &&
  19. typeof options === 'object' &&
  20. (!!options.fullNode || !!options.fullHost));
  21. }
  22. export class TronWeb extends EventEmitter {
  23. providers;
  24. BigNumber;
  25. transactionBuilder;
  26. trx;
  27. plugin;
  28. event;
  29. version;
  30. static version = version;
  31. utils;
  32. defaultBlock;
  33. defaultPrivateKey;
  34. defaultAddress;
  35. fullnodeVersion;
  36. feeLimit;
  37. fullNode;
  38. solidityNode;
  39. eventServer;
  40. constructor(options, solidityNode = '', eventServer, privateKey = '') {
  41. super();
  42. let fullNode;
  43. let headers = false;
  44. let eventHeaders = false;
  45. if (isValidOptions(options)) {
  46. fullNode = options.fullNode || options.fullHost;
  47. solidityNode = (options.solidityNode || options.fullHost);
  48. eventServer = (options.eventServer || options.fullHost);
  49. headers = options.headers || false;
  50. eventHeaders = options.eventHeaders || headers;
  51. privateKey = options.privateKey;
  52. }
  53. else {
  54. fullNode = options;
  55. }
  56. if (utils.isString(fullNode))
  57. fullNode = new providers.HttpProvider(fullNode);
  58. if (utils.isString(solidityNode))
  59. solidityNode = new providers.HttpProvider(solidityNode);
  60. if (utils.isString(eventServer))
  61. eventServer = new providers.HttpProvider(eventServer);
  62. this.event = new Event(this);
  63. this.transactionBuilder = new TransactionBuilder(this);
  64. this.trx = new Trx(this);
  65. this.plugin = new Plugin(this, {
  66. disablePlugins: isValidOptions(options) ? options.disablePlugins : false,
  67. });
  68. this.utils = utils;
  69. this.setFullNode(fullNode);
  70. this.setSolidityNode(solidityNode);
  71. this.setEventServer(eventServer);
  72. this.providers = providers;
  73. this.BigNumber = BigNumber;
  74. this.defaultBlock = false;
  75. this.defaultPrivateKey = false;
  76. this.defaultAddress = {
  77. hex: false,
  78. base58: false,
  79. };
  80. this.version = TronWeb.version;
  81. this.sha3 = TronWeb.sha3;
  82. this.fromUtf8 = TronWeb.fromUtf8;
  83. this.address = TronWeb.address;
  84. this.toAscii = TronWeb.toAscii;
  85. this.toUtf8 = TronWeb.toUtf8;
  86. this.isAddress = TronWeb.isAddress;
  87. this.fromAscii = TronWeb.fromAscii;
  88. this.toHex = TronWeb.toHex;
  89. this.toBigNumber = TronWeb.toBigNumber;
  90. this.toDecimal = TronWeb.toDecimal;
  91. this.fromDecimal = TronWeb.fromDecimal;
  92. this.toSun = TronWeb.toSun;
  93. this.fromSun = TronWeb.fromSun;
  94. this.createAccount = TronWeb.createAccount;
  95. this.createRandom = TronWeb.createRandom;
  96. this.fromMnemonic = TronWeb.fromMnemonic;
  97. if (privateKey)
  98. this.setPrivateKey(privateKey);
  99. this.fullnodeVersion = DEFAULT_VERSION;
  100. this.feeLimit = FEE_LIMIT;
  101. if (headers) {
  102. this.setFullNodeHeader(headers);
  103. }
  104. if (eventHeaders) {
  105. this.setEventHeader(eventHeaders);
  106. }
  107. }
  108. async getFullnodeVersion() {
  109. try {
  110. const nodeInfo = await this.trx.getNodeInfo();
  111. this.fullnodeVersion = nodeInfo.configNodeInfo.codeVersion;
  112. if (this.fullnodeVersion.split('.').length === 2) {
  113. this.fullnodeVersion += '.0';
  114. }
  115. }
  116. catch (err) {
  117. this.fullnodeVersion = DEFAULT_VERSION;
  118. }
  119. }
  120. setDefaultBlock(blockID = false) {
  121. if ([false, 'latest', 'earliest', 0].includes(blockID)) {
  122. return (this.defaultBlock = blockID);
  123. }
  124. if (!utils.isInteger(blockID) || !blockID)
  125. throw new Error('Invalid block ID provided');
  126. return (this.defaultBlock = Math.abs(blockID));
  127. }
  128. setPrivateKey(privateKey) {
  129. try {
  130. this.setAddress(TronWeb.address.fromPrivateKey(privateKey));
  131. }
  132. catch {
  133. throw new Error('Invalid private key provided');
  134. }
  135. this.defaultPrivateKey = privateKey;
  136. this.emit('privateKeyChanged', privateKey);
  137. }
  138. setAddress(address) {
  139. if (!TronWeb.isAddress(address))
  140. throw new Error('Invalid address provided');
  141. const hex = TronWeb.address.toHex(address);
  142. const base58 = TronWeb.address.fromHex(address);
  143. if (this.defaultPrivateKey && TronWeb.address.fromPrivateKey(this.defaultPrivateKey) !== base58)
  144. this.defaultPrivateKey = false;
  145. this.defaultAddress = {
  146. hex,
  147. base58,
  148. };
  149. this.emit('addressChanged', { hex, base58 });
  150. }
  151. fullnodeSatisfies(version) {
  152. return semver.satisfies(this.fullnodeVersion, version);
  153. }
  154. isValidProvider(provider) {
  155. return Object.values(providers).some((knownProvider) => provider instanceof knownProvider);
  156. }
  157. setFullNode(fullNode) {
  158. if (isString(fullNode))
  159. fullNode = new providers.HttpProvider(fullNode);
  160. if (!this.isValidProvider(fullNode))
  161. throw new Error('Invalid full node provided');
  162. this.fullNode = fullNode;
  163. this.fullNode.setStatusPage('wallet/getnowblock');
  164. }
  165. setSolidityNode(solidityNode) {
  166. if (utils.isString(solidityNode))
  167. solidityNode = new providers.HttpProvider(solidityNode);
  168. if (!this.isValidProvider(solidityNode))
  169. throw new Error('Invalid solidity node provided');
  170. this.solidityNode = solidityNode;
  171. this.solidityNode.setStatusPage('walletsolidity/getnowblock');
  172. }
  173. setEventServer(eventServer, healthcheck) {
  174. this.event.setServer(eventServer, healthcheck);
  175. }
  176. setHeader(headers = {}) {
  177. const fullNode = new providers.HttpProvider(this.fullNode.host, 30000, '', '', headers);
  178. const solidityNode = new providers.HttpProvider(this.solidityNode.host, 30000, '', '', headers);
  179. const eventServer = new providers.HttpProvider(this.eventServer.host, 30000, '', '', headers);
  180. this.setFullNode(fullNode);
  181. this.setSolidityNode(solidityNode);
  182. this.setEventServer(eventServer);
  183. }
  184. setFullNodeHeader(headers = {}) {
  185. const fullNode = new providers.HttpProvider(this.fullNode.host, 30000, '', '', headers);
  186. const solidityNode = new providers.HttpProvider(this.solidityNode.host, 30000, '', '', headers);
  187. this.setFullNode(fullNode);
  188. this.setSolidityNode(solidityNode);
  189. }
  190. setEventHeader(headers = {}) {
  191. const eventServer = new providers.HttpProvider(this.eventServer.host, 30000, '', '', headers);
  192. this.setEventServer(eventServer);
  193. }
  194. currentProviders() {
  195. return {
  196. fullNode: this.fullNode,
  197. solidityNode: this.solidityNode,
  198. eventServer: this.eventServer,
  199. };
  200. }
  201. currentProvider() {
  202. return this.currentProviders();
  203. }
  204. getEventResult(...params) {
  205. return this.event.getEventsByContractAddress(...params);
  206. }
  207. getEventByTransactionID(...params) {
  208. return this.event.getEventsByTransactionID(...params);
  209. }
  210. contract(abi = [], address) {
  211. return new Contract(this, abi, address);
  212. }
  213. address;
  214. static get address() {
  215. return {
  216. fromHex(address) {
  217. return fromHex(address);
  218. },
  219. toHex(address) {
  220. return toHex(address);
  221. },
  222. toChecksumAddress(address) {
  223. return toChecksumAddress(address);
  224. },
  225. isChecksumAddress(address) {
  226. return isChecksumAddress(address);
  227. },
  228. fromPrivateKey(privateKey, strict = false) {
  229. return fromPrivateKey(privateKey, strict);
  230. },
  231. };
  232. }
  233. sha3;
  234. static sha3(string, prefix = true) {
  235. return (prefix ? '0x' : '') + keccak256(Buffer.from(string, 'utf-8')).toString().substring(2);
  236. }
  237. toHex;
  238. static toHex(val) {
  239. if (utils.isBoolean(val))
  240. return TronWeb.fromDecimal(+val);
  241. if (utils.isBigNumber(val))
  242. return TronWeb.fromDecimal(val);
  243. if (typeof val === 'object')
  244. return TronWeb.fromUtf8(JSON.stringify(val));
  245. if (utils.isString(val)) {
  246. if (/^(-|)0x/.test(val))
  247. return val;
  248. // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  249. // @ts-ignore
  250. if (!isFinite(val) || /^\s*$/.test(val))
  251. return TronWeb.fromUtf8(val);
  252. }
  253. const result = TronWeb.fromDecimal(val);
  254. if (result === '0xNaN') {
  255. throw new Error('The passed value is not convertible to a hex string');
  256. }
  257. else {
  258. return result;
  259. }
  260. }
  261. toUtf8;
  262. static toUtf8(hex) {
  263. if (utils.isHex(hex)) {
  264. hex = hex.replace(/^0x/, '');
  265. return Buffer.from(hex, 'hex').toString('utf8');
  266. }
  267. else {
  268. throw new Error('The passed value is not a valid hex string');
  269. }
  270. }
  271. fromUtf8;
  272. static fromUtf8(string) {
  273. if (!utils.isString(string)) {
  274. throw new Error('The passed value is not a valid utf-8 string');
  275. }
  276. return '0x' + Buffer.from(string, 'utf8').toString('hex');
  277. }
  278. toAscii;
  279. static toAscii(hex) {
  280. if (utils.isHex(hex)) {
  281. let str = '';
  282. let i = 0;
  283. const l = hex.length;
  284. if (hex.substring(0, 2) === '0x') {
  285. i = 2;
  286. }
  287. for (; i < l; i += 2) {
  288. const code = parseInt(hex.substr(i, 2), 16);
  289. str += String.fromCharCode(code);
  290. }
  291. return str;
  292. }
  293. else {
  294. throw new Error('The passed value is not a valid hex string');
  295. }
  296. }
  297. fromAscii;
  298. static fromAscii(string, padding) {
  299. if (!utils.isString(string)) {
  300. throw new Error('The passed value is not a valid utf-8 string');
  301. }
  302. return '0x' + Buffer.from(string, 'ascii').toString('hex').padEnd(padding, '0');
  303. }
  304. toDecimal;
  305. static toDecimal(value) {
  306. return TronWeb.toBigNumber(value).toNumber();
  307. }
  308. fromDecimal;
  309. static fromDecimal(value) {
  310. const number = TronWeb.toBigNumber(value);
  311. const result = number.toString(16);
  312. return number.isLessThan(0) ? '-0x' + result.substr(1) : '0x' + result;
  313. }
  314. fromSun;
  315. static fromSun(sun) {
  316. const trx = TronWeb.toBigNumber(sun).div(1_000_000);
  317. return utils.isBigNumber(sun) ? trx : trx.toString(10);
  318. }
  319. toSun;
  320. static toSun(trx) {
  321. const sun = TronWeb.toBigNumber(trx).times(1_000_000);
  322. return utils.isBigNumber(trx) ? sun : sun.toString(10);
  323. }
  324. toBigNumber;
  325. static toBigNumber(amount = 0) {
  326. if (utils.isBigNumber(amount))
  327. return amount;
  328. if (utils.isString(amount) && /^(-|)0x/.test(amount))
  329. return new BigNumber(amount.replace('0x', ''), 16);
  330. return new BigNumber(amount.toString(10), 10);
  331. }
  332. isAddress;
  333. static isAddress(address = '') {
  334. return isAddress(address);
  335. }
  336. createAccount;
  337. static async createAccount() {
  338. const account = utils.accounts.generateAccount();
  339. return account;
  340. }
  341. createRandom;
  342. static createRandom(...params) {
  343. const account = utils.accounts.generateRandom(...params);
  344. return account;
  345. }
  346. fromMnemonic;
  347. static fromMnemonic(...params) {
  348. const account = utils.accounts.generateAccountWithMnemonic(...params);
  349. return account;
  350. }
  351. async isConnected() {
  352. return {
  353. fullNode: await this.fullNode.isConnected(),
  354. solidityNode: await this.solidityNode.isConnected(),
  355. eventServer: this.eventServer && (await this.eventServer.isConnected()),
  356. };
  357. }
  358. }
  359. export default TronWeb;
  360. //# sourceMappingURL=tronweb.js.map