@layerzerolabs/tron-utilities 2.3.4 → 2.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @layerzerolabs/tron-utilities
2
2
 
3
+ ## 2.3.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 4a92ba6: send and receive with ULN on solana
8
+ - Updated dependencies [4a92ba6]
9
+ - @layerzerolabs/lz-utilities@2.3.6
10
+
11
+ ## 2.3.5
12
+
13
+ ### Patch Changes
14
+
15
+ - 20c33bb: tron v2
16
+ - Updated dependencies [20c33bb]
17
+ - @layerzerolabs/lz-utilities@2.3.5
18
+
3
19
  ## 2.3.4
4
20
 
5
21
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -27,6 +27,50 @@ var Time = {
27
27
  }
28
28
  };
29
29
 
30
+ // src/url.ts
31
+ var DefaultProviderConversionStrategy = class {
32
+ asREST(url) {
33
+ return url.replace(/\/jsonrpc$/, "");
34
+ }
35
+ asJSONRPC(url) {
36
+ return url.trim().replace(/\/?$/, "/jsonrpc");
37
+ }
38
+ };
39
+ var AnkrProviderConversionStrategy = class {
40
+ asREST(url) {
41
+ if (/tron\/[0-9a-fA-F]{10,}/.test(url)) {
42
+ return url.replace(/\/tron_jsonrpc$/, "/premium-http/tron");
43
+ }
44
+ return url.replace(/\/tron_jsonrpc$/, "/http/tron");
45
+ }
46
+ asJSONRPC(url) {
47
+ return url.trim().replace(/\/(premium-http|http)\/tron/, "/tron_jsonrpc");
48
+ }
49
+ };
50
+ var QuiknodeProviderConversionStrategy = class {
51
+ asREST(url) {
52
+ return url.replace(/\/jsonrpc$/, "");
53
+ }
54
+ asJSONRPC(url) {
55
+ return url.trim().replace(/\/?$/, "/jsonrpc");
56
+ }
57
+ };
58
+ var _StrategyFactory = class _StrategyFactory {
59
+ static get(url) {
60
+ for (const [pattern, strategy] of this.strategies) {
61
+ if (pattern.test(url)) {
62
+ return strategy;
63
+ }
64
+ }
65
+ return new DefaultProviderConversionStrategy();
66
+ }
67
+ };
68
+ _StrategyFactory.strategies = /* @__PURE__ */ new Map();
69
+ _StrategyFactory.strategies.set(/api.trongrid.io/, new DefaultProviderConversionStrategy());
70
+ _StrategyFactory.strategies.set(/ankr.com/, new AnkrProviderConversionStrategy());
71
+ _StrategyFactory.strategies.set(/quiknode.pro/, new QuiknodeProviderConversionStrategy());
72
+ var StrategyFactory = _StrategyFactory;
73
+
30
74
  // src/tron.ts
31
75
  var TronTransactionType = /* @__PURE__ */ ((TronTransactionType2) => {
32
76
  TronTransactionType2["TRIGGER_SMART_CONTRACT"] = "TriggerSmartContract";
@@ -35,8 +79,9 @@ var TronTransactionType = /* @__PURE__ */ ((TronTransactionType2) => {
35
79
  var logger = lzUtilities.getLogger();
36
80
  function createTronWeb(signer) {
37
81
  if (!(signer instanceof TronWeb__default.default)) {
82
+ const fullHostUrl = typeof signer.rpcSetting === "string" ? signer.rpcSetting : signer.rpcSetting.url;
38
83
  const client = new TronWeb__default.default({
39
- fullHost: typeof signer.rpcSetting === "string" ? signer.rpcSetting : signer.rpcSetting.url,
84
+ fullHost: StrategyFactory.get(fullHostUrl).asREST(fullHostUrl),
40
85
  headers: {
41
86
  "TRON-PRO-API-KEY": typeof signer.rpcSetting === "string" ? "" : signer.rpcSetting.apiKey ?? ""
42
87
  },
@@ -131,7 +176,7 @@ var energyFactorsCache = /* @__PURE__ */ new Map();
131
176
  async function fullFillTxn(signer, txn, overrides = {}) {
132
177
  const apiKey = signer.fullNode.headers["TRON-PRO-API-KEY"];
133
178
  const etherProvider = new ethers.ethers.providers.StaticJsonRpcProvider({
134
- url: `${signer.fullNode.host}/jsonrpc`,
179
+ url: StrategyFactory.get(signer.fullNode.host).asJSONRPC(signer.fullNode.host),
135
180
  headers: {
136
181
  ...apiKey !== void 0 ? { "TRON-PRO-API-KEY": apiKey } : {}
137
182
  }
@@ -247,6 +292,7 @@ Object.defineProperty(exports, "TronWeb", {
247
292
  enumerable: true,
248
293
  get: function () { return TronWeb__default.default; }
249
294
  });
295
+ exports.StrategyFactory = StrategyFactory;
250
296
  exports.TronTransactionType = TronTransactionType;
251
297
  exports.checkResult = checkResult;
252
298
  exports.createTronWeb = createTronWeb;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tron.ts","../src/time.ts"],"names":["TronTransactionType","overrides","txId","output"],"mappings":"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","sourcesContent":["import { ethers } from 'ethers'\nimport TronWeb from 'tronweb'\n\nimport { CmdExecutor, getLogger, getProjectPackageManager, sleep } from '@layerzerolabs/lz-utilities'\n\nimport { Time } from './time'\n\nimport type {\n BlockTransaction,\n ChainParameter,\n ContractExecutionParams,\n ContractInfo,\n Transaction,\n TransactionInfo,\n} from 'tronweb'\n\nexport enum TronTransactionType {\n TRIGGER_SMART_CONTRACT = 'TriggerSmartContract',\n}\n\nexport interface TransactionOverrides {\n gasLimit?: number\n gasPrice?: number\n energyFactor?: number\n value?: number\n}\n\nexport interface PartialTronTransaction {\n visible: boolean\n txID: string\n raw_data_hex: string\n raw_data: {\n contract: [PartialTronTransactionContract]\n }\n}\n\nexport interface TronTransaction extends PartialTronTransaction {\n raw_data: {\n contract: [FullTronTransactionContract]\n ref_block_bytes: string\n ref_block_hash: string\n expiration: number\n fee_limit: number\n timestamp: number\n }\n}\n\nexport interface SignedTronTransaction extends TronTransaction {\n signature: string[]\n}\n\ninterface PartialTronTransactionParameterValue {\n data: string\n contract_address: string\n owner_address: string\n}\n\ninterface TronTransactionParameterValue extends PartialTronTransactionParameterValue {\n token_id?: number\n call_token_value?: number\n call_value?: number\n}\n\ninterface TronTransactionParameter<T> {\n value: T\n type_url: `type.googleapis.com/protocol.${TronTransactionType}`\n}\n\ninterface TronTransactionContract<T> {\n parameter: TronTransactionParameter<T>\n type: TronTransactionType\n Permission_id?: number\n}\n\ntype PartialTronTransactionContract = TronTransactionContract<PartialTronTransactionParameterValue>\ntype FullTronTransactionContract = TronTransactionContract<TronTransactionParameterValue>\n\ninterface TronBlockHeaderRawData {\n number: number\n txTrieRoot: string\n witness_address: string\n parentHash: string\n timestamp: number\n}\n\ninterface TronBlockHeader {\n raw_data: TronBlockHeaderRawData\n witness_signature: string\n}\n\nexport interface TronBlockData {\n blockID: string\n block_header: TronBlockHeader\n}\n\ninterface TronWebError1 {\n code: string\n message: string\n txid: string\n}\n\ninterface TronWebError2 {\n Error: string\n}\ntype TronWebErrorResponse = TronWebError1 | TronWebError2\n\nexport {\n TronWeb,\n BlockTransaction,\n ContractExecutionParams,\n ChainParameter,\n Transaction,\n TronWebError1,\n TronWebError2,\n TronWebErrorResponse,\n}\n\nconst logger = getLogger()\n\nexport type ProviderSetting =\n | {\n url: string\n apiKey?: string\n }\n | string\n\nexport function createTronWeb(signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb): TronWeb {\n if (!(signer instanceof TronWeb)) {\n const client = new TronWeb({\n fullHost: typeof signer.rpcSetting === 'string' ? signer.rpcSetting : signer.rpcSetting.url,\n headers: {\n 'TRON-PRO-API-KEY': typeof signer.rpcSetting === 'string' ? '' : signer.rpcSetting.apiKey ?? '',\n },\n privateKey: signer.privateKey.replace(/^0x/, ''),\n })\n return client\n }\n return signer\n}\n\nexport async function tronBoxDeploy(\n workspace: string,\n network: string,\n tags: string[],\n executor?: 'yarn' | 'npm' | 'pnpm'\n): Promise<void> {\n // const tagsStr = tags.join(',')\n if (executor === undefined) executor = getProjectPackageManager(workspace)\n // get the package manager from the workspace\n\n for (const tag of tags) {\n const cmd = `${executor} pnpify tronbox migrate --network ${network} --f ${tag} --to ${tag}`\n // NODE: promisify exec may not work here when invoked from testify\n try {\n const cmdExecutor = new CmdExecutor()\n await cmdExecutor.executeCmd(\n cmd,\n [],\n { shell: true, cwd: workspace, env: process.env },\n true,\n undefined,\n logger\n )\n } catch (e) {\n console.log(e)\n }\n }\n}\n\nexport async function signAndSendTronTransaction(\n txn: {\n data: string\n to: string\n } & TransactionOverrides,\n signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb,\n permissionId?: number // for multi-sig\n): Promise<{ txId: string; result: any; wait: () => Promise<any> }> {\n const signedTxn = await signTronTx(txn, signer, permissionId)\n const client = createTronWeb(signer)\n return sendTronTransaction(signedTxn, client)\n}\n\nexport async function sendTronTransaction(\n singedTxn: SignedTronTransaction,\n client: TronWeb\n): Promise<{ txId: string; result: any; wait: () => Promise<TransactionInfo> }> {\n // reference: https://developers.tron.network/reference/json-rpc-api-overview\n // JSON-RPC interface is not fully supported by the TRON network.\n // Furthermore, The JSON-RPC service needs to be enabled and set the port in the node configuration\n // file. If not configured, the service is disable by default.\n // broadcast signedTransaction\n const broadcastResponse = await client.trx.sendRawTransaction(singedTxn)\n if (broadcastResponse.code !== undefined) {\n const err = {\n error: broadcastResponse.code,\n message: TronWeb.toUtf8(broadcastResponse.message ?? ''),\n }\n throw new Error(JSON.stringify(err, null, 2))\n }\n\n return {\n txId: singedTxn.txID,\n result: broadcastResponse,\n wait: async (): Promise<TransactionInfo> => {\n return checkResult(client, singedTxn.txID)\n },\n }\n}\n\nexport async function signTronTx(\n txn: {\n data: string\n to: string\n } & TransactionOverrides,\n _signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb,\n permissionId?: number // for multi-sig\n): Promise<SignedTronTransaction> {\n const signer: TronWeb = createTronWeb(_signer)\n\n // privateKey = privateKey.replace(/^0x/, '') // remove the 0x prefix\n // private key to address\n // const from = TronWeb.address.fromPrivateKey(privateKey)\n if (typeof signer.defaultAddress.hex !== 'string') {\n throw new Error(`signer.defaultAddress.hex is not a valid hex string`)\n }\n\n const partialTxn: PartialTronTransaction = {\n visible: false,\n txID: '',\n raw_data_hex: '',\n raw_data: {\n contract: [\n {\n parameter: {\n value: {\n data: txn.data.replace(/^0x/, ''),\n contract_address: TronWeb.address.toHex(txn.to),\n owner_address: signer.defaultAddress.hex,\n },\n type_url: `type.googleapis.com/protocol.${TronTransactionType.TRIGGER_SMART_CONTRACT}`,\n },\n type: TronTransactionType.TRIGGER_SMART_CONTRACT,\n Permission_id: permissionId,\n },\n ],\n },\n }\n\n const fullTxn = await fullFillTxn(signer, partialTxn, {\n gasLimit: txn.gasLimit,\n gasPrice: txn.gasPrice,\n energyFactor: txn.energyFactor,\n value: txn.value,\n })\n\n // sign transaction\n const signedTransaction = await signer.trx.sign(fullTxn)\n if (signedTransaction.signature === undefined) {\n throw new Error('Invalid private key provided')\n }\n return signedTransaction as SignedTronTransaction\n}\n\nlet gasPriceCache: { time: number; value: string } = { time: 0, value: '' }\nconst energyFactorsCache = new Map<string, { time: number; value: number }>()\n\nexport async function fullFillTxn(\n signer: TronWeb,\n txn: PartialTronTransaction,\n overrides: TransactionOverrides = {}\n): Promise<TronTransaction> {\n const apiKey = signer.fullNode.headers['TRON-PRO-API-KEY']\n const etherProvider = new ethers.providers.StaticJsonRpcProvider({\n url: `${signer.fullNode.host}/jsonrpc`,\n headers: {\n ...(apiKey !== undefined ? { 'TRON-PRO-API-KEY': apiKey } : {}),\n },\n })\n\n // cache the gasPrice with a 15sec TTL\n async function getGasPrice(): Promise<string> {\n const { time, value } = gasPriceCache\n if (time > Time.NOW - 15 * Time.SECOND && value != '') return value\n const newGaspPrice = await etherProvider.getGasPrice().then((x) => x.toString())\n gasPriceCache = { time: Time.NOW, value: newGaspPrice }\n return newGaspPrice\n }\n\n async function getGasLimit(raw: PartialTronTransaction): Promise<number> {\n const gasLimit = await etherProvider.estimateGas({\n to: raw.raw_data.contract[0].parameter.value.contract_address.replace(/^41/, '0x'), // need to slice off the \"41\" prefix that Tron appends to addresses\n data: '0x' + raw.raw_data.contract[0].parameter.value.data,\n from: raw.raw_data.contract[0].parameter.value.owner_address.replace(/^41/, '0x'),\n value: overrides.value ?? 0,\n })\n return gasLimit.toNumber()\n }\n\n // cache the energy_factor with a 10min TTL, energy factors should be updated by Tron every 6h\n async function getEnergyFactor(raw: PartialTronTransaction): Promise<number> {\n /* eslint-disable @typescript-eslint/no-unsafe-assignment */\n const addr = raw.raw_data.contract[0].parameter.value.contract_address\n const cached = energyFactorsCache.get(addr)\n if (cached && cached.time > Time.NOW - 10 * Time.MINUTE) return cached.value\n const MAX_ENERGY_FACTOR = 1.2\n // refers: https://developers.tron.network/reference/getcontractinfo\n const response = await signer.fullNode.request(\n 'wallet/getcontractinfo',\n { value: addr, visible: false },\n 'post'\n )\n const contractInfo: ContractInfo = response as ContractInfo\n const energy_factor = contractInfo.contract_state.energy_factor ?? MAX_ENERGY_FACTOR\n energyFactorsCache.set(addr, { time: Time.NOW, value: energy_factor })\n return energy_factor\n /* eslint-enable @typescript-eslint/no-unsafe-assignment */\n }\n\n async function getFeeLimit(raw: PartialTronTransaction, overrides: TransactionOverrides = {}): Promise<number> {\n // https://developers.tron.network/docs/set-feelimit#how-to-determine-the-feelimit-parameter\n // https://developers.tron.network/reference/getcontractinfo, get energy_factor\n // https://developers.tron.network/docs/resource-model#dynamic-energy-model, max factor\n // Tight FeeLimit of contract transaction = estimated basic energy consumption * (1 + energy_factor) * EnergyPrice\n // Loose FeeLimit of contract transaction = estimated basic energy consumption * (1 + max_energy_factor) * EnergyPrice\n const MAX_FEE_LIMIT = 15000000000\n const energy_factor = overrides.energyFactor ?? (await getEnergyFactor(raw))\n const gasLimit = overrides.gasLimit ?? (await getGasLimit(raw))\n const energyPrice = overrides.gasPrice ?? Number(await getGasPrice())\n const factor = 1 + energy_factor\n const feeLimit = gasLimit * factor * energyPrice\n const feeLimit_adjusted = Math.ceil(feeLimit) * 1.2 // based on reading other parts of the code, we add a 20% cushion on fee limits\n return Math.floor(Math.min(feeLimit_adjusted, MAX_FEE_LIMIT))\n }\n\n const metadata = (await signer.fullNode.request('wallet/getblock', { detail: false }, 'post')) as TronBlockData\n const ref_block_bytes = metadata.block_header.raw_data.number.toString(16).slice(-4).padStart(4, '0')\n const ref_block_hash = metadata.blockID.slice(16, 32)\n const expiration = metadata.block_header.raw_data.timestamp + 60 * 1000\n const { timestamp } = metadata.block_header.raw_data\n\n const tx: TronTransaction = {\n ...txn,\n raw_data: {\n contract: [\n {\n parameter: {\n value: {\n ...txn.raw_data.contract[0].parameter.value,\n call_value: overrides.value ?? 0,\n },\n type_url: txn.raw_data.contract[0].parameter.type_url,\n },\n type: txn.raw_data.contract[0].type,\n },\n ],\n ref_block_bytes,\n ref_block_hash,\n expiration,\n fee_limit: await getFeeLimit(txn, overrides),\n timestamp,\n },\n }\n const pb = signer.utils.transaction.txJsonToPb(tx)\n tx.txID = signer.utils.transaction.txPbToTxID(pb).replace(/^0x/, '')\n tx.raw_data_hex = signer.utils.transaction.txPbToRawDataHex(pb).toLowerCase()\n\n return tx\n}\n\nexport async function checkResult(tronWeb: TronWeb, txId: string): Promise<TransactionInfo> {\n const startTime = Date.now()\n const waitTimeout = 1000 * 60 * 5 // 5 minutes\n // TODO: get the block producer interval from the chain and sleep for that time\n const wait = async function (txId: string): Promise<TransactionInfo> {\n let tries = 0\n while (tries++ < 20) {\n const output = await tronWeb.trx.getTransactionInfo(txId)\n if (Object.keys(output).length > 0) {\n return output\n }\n\n // check if timeout\n if (Date.now() - startTime > waitTimeout) {\n throw new Error('Timeout waiting for transaction to be processed')\n }\n // wait 1 seconds for next check, mainnet block producer interval is 3 seconds,\n // but we need a small interval for the local network to speed up the test\n await sleep(1200)\n }\n throw new Error(`Failed to get transactionInfo for txId: ${txId}`)\n }\n\n const output = await wait(txId)\n\n if (process.env.CI === 'true') {\n console.trace('checkResult txId', txId)\n console.log('checkResult output', Object.keys(output), output)\n }\n\n if (output.result !== undefined && output.result === 'FAILED') {\n throw new Error(TronWeb.toUtf8(output.resMessage ?? ''))\n }\n\n if (!Object.prototype.hasOwnProperty.call(output, 'contractResult')) {\n throw new Error('Failed to execute: ' + JSON.stringify(output, null, 2))\n }\n\n return output\n}\n","// Base unit in milliseconds\nconst MILLISECOND = 1\nconst SECOND = 1000 * MILLISECOND\nconst MINUTE = 60 * SECOND\nconst HOUR = 60 * MINUTE\nconst DAY = 24 * HOUR\n\nexport const Time = {\n MILLISECOND,\n SECOND,\n MINUTE,\n HOUR,\n DAY,\n get NOW() {\n return Date.now()\n },\n} as const\n"]}
1
+ {"version":3,"sources":["../src/tron.ts","../src/time.ts","../src/url.ts"],"names":["TronTransactionType","overrides","txId","output"],"mappings":"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","sourcesContent":["import { ethers } from 'ethers'\nimport TronWeb from 'tronweb'\n\nimport { CmdExecutor, getLogger, getProjectPackageManager, sleep } from '@layerzerolabs/lz-utilities'\n\nimport { Time } from './time'\nimport { StrategyFactory } from './url'\n\nimport type {\n BlockTransaction,\n ChainParameter,\n ContractExecutionParams,\n ContractInfo,\n Transaction,\n TransactionInfo,\n} from 'tronweb'\n\nexport enum TronTransactionType {\n TRIGGER_SMART_CONTRACT = 'TriggerSmartContract',\n}\n\nexport interface TransactionOverrides {\n gasLimit?: number\n gasPrice?: number\n energyFactor?: number\n value?: number\n}\n\nexport interface PartialTronTransaction {\n visible: boolean\n txID: string\n raw_data_hex: string\n raw_data: {\n contract: [PartialTronTransactionContract]\n }\n}\n\nexport interface TronTransaction extends PartialTronTransaction {\n raw_data: {\n contract: [FullTronTransactionContract]\n ref_block_bytes: string\n ref_block_hash: string\n expiration: number\n fee_limit: number\n timestamp: number\n }\n}\n\nexport interface SignedTronTransaction extends TronTransaction {\n signature: string[]\n}\n\ninterface PartialTronTransactionParameterValue {\n data: string\n contract_address: string\n owner_address: string\n}\n\ninterface TronTransactionParameterValue extends PartialTronTransactionParameterValue {\n token_id?: number\n call_token_value?: number\n call_value?: number\n}\n\ninterface TronTransactionParameter<T> {\n value: T\n type_url: `type.googleapis.com/protocol.${TronTransactionType}`\n}\n\ninterface TronTransactionContract<T> {\n parameter: TronTransactionParameter<T>\n type: TronTransactionType\n Permission_id?: number\n}\n\ntype PartialTronTransactionContract = TronTransactionContract<PartialTronTransactionParameterValue>\ntype FullTronTransactionContract = TronTransactionContract<TronTransactionParameterValue>\n\ninterface TronBlockHeaderRawData {\n number: number\n txTrieRoot: string\n witness_address: string\n parentHash: string\n timestamp: number\n}\n\ninterface TronBlockHeader {\n raw_data: TronBlockHeaderRawData\n witness_signature: string\n}\n\nexport interface TronBlockData {\n blockID: string\n block_header: TronBlockHeader\n}\n\ninterface TronWebError1 {\n code: string\n message: string\n txid: string\n}\n\ninterface TronWebError2 {\n Error: string\n}\ntype TronWebErrorResponse = TronWebError1 | TronWebError2\n\nexport {\n TronWeb,\n BlockTransaction,\n ContractExecutionParams,\n ChainParameter,\n Transaction,\n TronWebError1,\n TronWebError2,\n TronWebErrorResponse,\n}\n\nconst logger = getLogger()\n\nexport type ProviderSetting =\n | {\n url: string\n apiKey?: string\n }\n | string\n\nexport function createTronWeb(signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb): TronWeb {\n if (!(signer instanceof TronWeb)) {\n const fullHostUrl = typeof signer.rpcSetting === 'string' ? signer.rpcSetting : signer.rpcSetting.url\n const client = new TronWeb({\n fullHost: StrategyFactory.get(fullHostUrl).asREST(fullHostUrl),\n headers: {\n 'TRON-PRO-API-KEY': typeof signer.rpcSetting === 'string' ? '' : signer.rpcSetting.apiKey ?? '',\n },\n privateKey: signer.privateKey.replace(/^0x/, ''),\n })\n return client\n }\n return signer\n}\n\nexport async function tronBoxDeploy(\n workspace: string,\n network: string,\n tags: string[],\n executor?: 'yarn' | 'npm' | 'pnpm'\n): Promise<void> {\n // const tagsStr = tags.join(',')\n if (executor === undefined) executor = getProjectPackageManager(workspace)\n // get the package manager from the workspace\n\n for (const tag of tags) {\n const cmd = `${executor} pnpify tronbox migrate --network ${network} --f ${tag} --to ${tag}`\n // NODE: promisify exec may not work here when invoked from testify\n try {\n const cmdExecutor = new CmdExecutor()\n await cmdExecutor.executeCmd(\n cmd,\n [],\n { shell: true, cwd: workspace, env: process.env },\n true,\n undefined,\n logger\n )\n } catch (e) {\n console.log(e)\n }\n }\n}\n\nexport async function signAndSendTronTransaction(\n txn: {\n data: string\n to: string\n } & TransactionOverrides,\n signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb,\n permissionId?: number // for multi-sig\n): Promise<{ txId: string; result: any; wait: () => Promise<any> }> {\n const signedTxn = await signTronTx(txn, signer, permissionId)\n const client = createTronWeb(signer)\n return sendTronTransaction(signedTxn, client)\n}\n\nexport async function sendTronTransaction(\n singedTxn: SignedTronTransaction,\n client: TronWeb\n): Promise<{ txId: string; result: any; wait: () => Promise<TransactionInfo> }> {\n // reference: https://developers.tron.network/reference/json-rpc-api-overview\n // JSON-RPC interface is not fully supported by the TRON network.\n // Furthermore, The JSON-RPC service needs to be enabled and set the port in the node configuration\n // file. If not configured, the service is disable by default.\n // broadcast signedTransaction\n const broadcastResponse = await client.trx.sendRawTransaction(singedTxn)\n if (broadcastResponse.code !== undefined) {\n const err = {\n error: broadcastResponse.code,\n message: TronWeb.toUtf8(broadcastResponse.message ?? ''),\n }\n throw new Error(JSON.stringify(err, null, 2))\n }\n\n return {\n txId: singedTxn.txID,\n result: broadcastResponse,\n wait: async (): Promise<TransactionInfo> => {\n return checkResult(client, singedTxn.txID)\n },\n }\n}\n\nexport async function signTronTx(\n txn: {\n data: string\n to: string\n } & TransactionOverrides,\n _signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb,\n permissionId?: number // for multi-sig\n): Promise<SignedTronTransaction> {\n const signer: TronWeb = createTronWeb(_signer)\n\n // privateKey = privateKey.replace(/^0x/, '') // remove the 0x prefix\n // private key to address\n // const from = TronWeb.address.fromPrivateKey(privateKey)\n if (typeof signer.defaultAddress.hex !== 'string') {\n throw new Error(`signer.defaultAddress.hex is not a valid hex string`)\n }\n\n const partialTxn: PartialTronTransaction = {\n visible: false,\n txID: '',\n raw_data_hex: '',\n raw_data: {\n contract: [\n {\n parameter: {\n value: {\n data: txn.data.replace(/^0x/, ''),\n contract_address: TronWeb.address.toHex(txn.to),\n owner_address: signer.defaultAddress.hex,\n },\n type_url: `type.googleapis.com/protocol.${TronTransactionType.TRIGGER_SMART_CONTRACT}`,\n },\n type: TronTransactionType.TRIGGER_SMART_CONTRACT,\n Permission_id: permissionId,\n },\n ],\n },\n }\n\n const fullTxn = await fullFillTxn(signer, partialTxn, {\n gasLimit: txn.gasLimit,\n gasPrice: txn.gasPrice,\n energyFactor: txn.energyFactor,\n value: txn.value,\n })\n\n // sign transaction\n const signedTransaction = await signer.trx.sign(fullTxn)\n if (signedTransaction.signature === undefined) {\n throw new Error('Invalid private key provided')\n }\n return signedTransaction as SignedTronTransaction\n}\n\nlet gasPriceCache: { time: number; value: string } = { time: 0, value: '' }\nconst energyFactorsCache = new Map<string, { time: number; value: number }>()\n\nexport async function fullFillTxn(\n signer: TronWeb,\n txn: PartialTronTransaction,\n overrides: TransactionOverrides = {}\n): Promise<TronTransaction> {\n const apiKey = signer.fullNode.headers['TRON-PRO-API-KEY']\n const etherProvider = new ethers.providers.StaticJsonRpcProvider({\n url: StrategyFactory.get(signer.fullNode.host).asJSONRPC(signer.fullNode.host),\n headers: {\n ...(apiKey !== undefined ? { 'TRON-PRO-API-KEY': apiKey } : {}),\n },\n })\n\n // cache the gasPrice with a 15sec TTL\n async function getGasPrice(): Promise<string> {\n const { time, value } = gasPriceCache\n if (time > Time.NOW - 15 * Time.SECOND && value != '') return value\n const newGaspPrice = await etherProvider.getGasPrice().then((x) => x.toString())\n gasPriceCache = { time: Time.NOW, value: newGaspPrice }\n return newGaspPrice\n }\n\n async function getGasLimit(raw: PartialTronTransaction): Promise<number> {\n const gasLimit = await etherProvider.estimateGas({\n to: raw.raw_data.contract[0].parameter.value.contract_address.replace(/^41/, '0x'), // need to slice off the \"41\" prefix that Tron appends to addresses\n data: '0x' + raw.raw_data.contract[0].parameter.value.data,\n from: raw.raw_data.contract[0].parameter.value.owner_address.replace(/^41/, '0x'),\n value: overrides.value ?? 0,\n })\n return gasLimit.toNumber()\n }\n\n // cache the energy_factor with a 10min TTL, energy factors should be updated by Tron every 6h\n async function getEnergyFactor(raw: PartialTronTransaction): Promise<number> {\n /* eslint-disable @typescript-eslint/no-unsafe-assignment */\n const addr = raw.raw_data.contract[0].parameter.value.contract_address\n const cached = energyFactorsCache.get(addr)\n if (cached && cached.time > Time.NOW - 10 * Time.MINUTE) return cached.value\n const MAX_ENERGY_FACTOR = 1.2\n // refers: https://developers.tron.network/reference/getcontractinfo\n const response = await signer.fullNode.request(\n 'wallet/getcontractinfo',\n { value: addr, visible: false },\n 'post'\n )\n const contractInfo: ContractInfo = response as ContractInfo\n const energy_factor = contractInfo.contract_state.energy_factor ?? MAX_ENERGY_FACTOR\n energyFactorsCache.set(addr, { time: Time.NOW, value: energy_factor })\n return energy_factor\n /* eslint-enable @typescript-eslint/no-unsafe-assignment */\n }\n\n async function getFeeLimit(raw: PartialTronTransaction, overrides: TransactionOverrides = {}): Promise<number> {\n // https://developers.tron.network/docs/set-feelimit#how-to-determine-the-feelimit-parameter\n // https://developers.tron.network/reference/getcontractinfo, get energy_factor\n // https://developers.tron.network/docs/resource-model#dynamic-energy-model, max factor\n // Tight FeeLimit of contract transaction = estimated basic energy consumption * (1 + energy_factor) * EnergyPrice\n // Loose FeeLimit of contract transaction = estimated basic energy consumption * (1 + max_energy_factor) * EnergyPrice\n const MAX_FEE_LIMIT = 15000000000\n const energy_factor = overrides.energyFactor ?? (await getEnergyFactor(raw))\n const gasLimit = overrides.gasLimit ?? (await getGasLimit(raw))\n const energyPrice = overrides.gasPrice ?? Number(await getGasPrice())\n const factor = 1 + energy_factor\n const feeLimit = gasLimit * factor * energyPrice\n const feeLimit_adjusted = Math.ceil(feeLimit) * 1.2 // based on reading other parts of the code, we add a 20% cushion on fee limits\n return Math.floor(Math.min(feeLimit_adjusted, MAX_FEE_LIMIT))\n }\n\n const metadata = (await signer.fullNode.request('wallet/getblock', { detail: false }, 'post')) as TronBlockData\n const ref_block_bytes = metadata.block_header.raw_data.number.toString(16).slice(-4).padStart(4, '0')\n const ref_block_hash = metadata.blockID.slice(16, 32)\n const expiration = metadata.block_header.raw_data.timestamp + 60 * 1000\n const { timestamp } = metadata.block_header.raw_data\n\n const tx: TronTransaction = {\n ...txn,\n raw_data: {\n contract: [\n {\n parameter: {\n value: {\n ...txn.raw_data.contract[0].parameter.value,\n call_value: overrides.value ?? 0,\n },\n type_url: txn.raw_data.contract[0].parameter.type_url,\n },\n type: txn.raw_data.contract[0].type,\n },\n ],\n ref_block_bytes,\n ref_block_hash,\n expiration,\n fee_limit: await getFeeLimit(txn, overrides),\n timestamp,\n },\n }\n const pb = signer.utils.transaction.txJsonToPb(tx)\n tx.txID = signer.utils.transaction.txPbToTxID(pb).replace(/^0x/, '')\n tx.raw_data_hex = signer.utils.transaction.txPbToRawDataHex(pb).toLowerCase()\n\n return tx\n}\n\nexport async function checkResult(tronWeb: TronWeb, txId: string): Promise<TransactionInfo> {\n const startTime = Date.now()\n const waitTimeout = 1000 * 60 * 5 // 5 minutes\n // TODO: get the block producer interval from the chain and sleep for that time\n const wait = async function (txId: string): Promise<TransactionInfo> {\n let tries = 0\n while (tries++ < 20) {\n const output = await tronWeb.trx.getTransactionInfo(txId)\n if (Object.keys(output).length > 0) {\n return output\n }\n\n // check if timeout\n if (Date.now() - startTime > waitTimeout) {\n throw new Error('Timeout waiting for transaction to be processed')\n }\n // wait 1 seconds for next check, mainnet block producer interval is 3 seconds,\n // but we need a small interval for the local network to speed up the test\n await sleep(1200)\n }\n throw new Error(`Failed to get transactionInfo for txId: ${txId}`)\n }\n\n const output = await wait(txId)\n\n if (process.env.CI === 'true') {\n console.trace('checkResult txId', txId)\n console.log('checkResult output', Object.keys(output), output)\n }\n\n if (output.result !== undefined && output.result === 'FAILED') {\n throw new Error(TronWeb.toUtf8(output.resMessage ?? ''))\n }\n\n if (!Object.prototype.hasOwnProperty.call(output, 'contractResult')) {\n throw new Error('Failed to execute: ' + JSON.stringify(output, null, 2))\n }\n\n return output\n}\n","// Base unit in milliseconds\nconst MILLISECOND = 1\nconst SECOND = 1000 * MILLISECOND\nconst MINUTE = 60 * SECOND\nconst HOUR = 60 * MINUTE\nconst DAY = 24 * HOUR\n\nexport const Time = {\n MILLISECOND,\n SECOND,\n MINUTE,\n HOUR,\n DAY,\n get NOW() {\n return Date.now()\n },\n} as const\n","export interface ProviderConversionStrategy {\n asREST(url: string): string\n asJSONRPC(url: string): string\n}\n\nclass DefaultProviderConversionStrategy implements ProviderConversionStrategy {\n asREST(url: string): string {\n return url.replace(/\\/jsonrpc$/, '')\n }\n\n asJSONRPC(url: string): string {\n return url.trim().replace(/\\/?$/, '/jsonrpc')\n }\n}\n\nclass AnkrProviderConversionStrategy implements ProviderConversionStrategy {\n asREST(url: string): string {\n if (/tron\\/[0-9a-fA-F]{10,}/.test(url)) {\n return url.replace(/\\/tron_jsonrpc$/, '/premium-http/tron')\n }\n\n return url.replace(/\\/tron_jsonrpc$/, '/http/tron')\n }\n\n asJSONRPC(url: string): string {\n return url.trim().replace(/\\/(premium-http|http)\\/tron/, '/tron_jsonrpc')\n }\n}\n\nclass QuiknodeProviderConversionStrategy implements ProviderConversionStrategy {\n asREST(url: string): string {\n return url.replace(/\\/jsonrpc$/, '')\n }\n\n asJSONRPC(url: string): string {\n return url.trim().replace(/\\/?$/, '/jsonrpc')\n }\n}\n\nexport class StrategyFactory {\n public static strategies: Map<RegExp, ProviderConversionStrategy> = new Map()\n\n static {\n StrategyFactory.strategies.set(/api.trongrid.io/, new DefaultProviderConversionStrategy())\n StrategyFactory.strategies.set(/ankr.com/, new AnkrProviderConversionStrategy())\n StrategyFactory.strategies.set(/quiknode.pro/, new QuiknodeProviderConversionStrategy())\n }\n\n static get(url: string): ProviderConversionStrategy {\n for (const [pattern, strategy] of this.strategies) {\n if (pattern.test(url)) {\n return strategy\n }\n }\n return new DefaultProviderConversionStrategy()\n }\n}\n"]}
package/dist/index.d.mts CHANGED
@@ -112,4 +112,13 @@ declare function signTronTx(txn: {
112
112
  declare function fullFillTxn(signer: TronWeb, txn: PartialTronTransaction, overrides?: TransactionOverrides): Promise<TronTransaction>;
113
113
  declare function checkResult(tronWeb: TronWeb, txId: string): Promise<TransactionInfo>;
114
114
 
115
- export { type PartialTronTransaction, type ProviderSetting, type SignedTronTransaction, type TransactionOverrides, type TronBlockData, type TronTransaction, TronTransactionType, type TronWebError1, type TronWebError2, type TronWebErrorResponse, checkResult, createTronWeb, fullFillTxn, sendTronTransaction, signAndSendTronTransaction, signTronTx, tronBoxDeploy };
115
+ interface ProviderConversionStrategy {
116
+ asREST(url: string): string;
117
+ asJSONRPC(url: string): string;
118
+ }
119
+ declare class StrategyFactory {
120
+ static strategies: Map<RegExp, ProviderConversionStrategy>;
121
+ static get(url: string): ProviderConversionStrategy;
122
+ }
123
+
124
+ export { type PartialTronTransaction, type ProviderConversionStrategy, type ProviderSetting, type SignedTronTransaction, StrategyFactory, type TransactionOverrides, type TronBlockData, type TronTransaction, TronTransactionType, type TronWebError1, type TronWebError2, type TronWebErrorResponse, checkResult, createTronWeb, fullFillTxn, sendTronTransaction, signAndSendTronTransaction, signTronTx, tronBoxDeploy };
package/dist/index.d.ts CHANGED
@@ -112,4 +112,13 @@ declare function signTronTx(txn: {
112
112
  declare function fullFillTxn(signer: TronWeb, txn: PartialTronTransaction, overrides?: TransactionOverrides): Promise<TronTransaction>;
113
113
  declare function checkResult(tronWeb: TronWeb, txId: string): Promise<TransactionInfo>;
114
114
 
115
- export { type PartialTronTransaction, type ProviderSetting, type SignedTronTransaction, type TransactionOverrides, type TronBlockData, type TronTransaction, TronTransactionType, type TronWebError1, type TronWebError2, type TronWebErrorResponse, checkResult, createTronWeb, fullFillTxn, sendTronTransaction, signAndSendTronTransaction, signTronTx, tronBoxDeploy };
115
+ interface ProviderConversionStrategy {
116
+ asREST(url: string): string;
117
+ asJSONRPC(url: string): string;
118
+ }
119
+ declare class StrategyFactory {
120
+ static strategies: Map<RegExp, ProviderConversionStrategy>;
121
+ static get(url: string): ProviderConversionStrategy;
122
+ }
123
+
124
+ export { type PartialTronTransaction, type ProviderConversionStrategy, type ProviderSetting, type SignedTronTransaction, StrategyFactory, type TransactionOverrides, type TronBlockData, type TronTransaction, TronTransactionType, type TronWebError1, type TronWebError2, type TronWebErrorResponse, checkResult, createTronWeb, fullFillTxn, sendTronTransaction, signAndSendTronTransaction, signTronTx, tronBoxDeploy };
package/dist/index.mjs CHANGED
@@ -22,6 +22,50 @@ var Time = {
22
22
  }
23
23
  };
24
24
 
25
+ // src/url.ts
26
+ var DefaultProviderConversionStrategy = class {
27
+ asREST(url) {
28
+ return url.replace(/\/jsonrpc$/, "");
29
+ }
30
+ asJSONRPC(url) {
31
+ return url.trim().replace(/\/?$/, "/jsonrpc");
32
+ }
33
+ };
34
+ var AnkrProviderConversionStrategy = class {
35
+ asREST(url) {
36
+ if (/tron\/[0-9a-fA-F]{10,}/.test(url)) {
37
+ return url.replace(/\/tron_jsonrpc$/, "/premium-http/tron");
38
+ }
39
+ return url.replace(/\/tron_jsonrpc$/, "/http/tron");
40
+ }
41
+ asJSONRPC(url) {
42
+ return url.trim().replace(/\/(premium-http|http)\/tron/, "/tron_jsonrpc");
43
+ }
44
+ };
45
+ var QuiknodeProviderConversionStrategy = class {
46
+ asREST(url) {
47
+ return url.replace(/\/jsonrpc$/, "");
48
+ }
49
+ asJSONRPC(url) {
50
+ return url.trim().replace(/\/?$/, "/jsonrpc");
51
+ }
52
+ };
53
+ var _StrategyFactory = class _StrategyFactory {
54
+ static get(url) {
55
+ for (const [pattern, strategy] of this.strategies) {
56
+ if (pattern.test(url)) {
57
+ return strategy;
58
+ }
59
+ }
60
+ return new DefaultProviderConversionStrategy();
61
+ }
62
+ };
63
+ _StrategyFactory.strategies = /* @__PURE__ */ new Map();
64
+ _StrategyFactory.strategies.set(/api.trongrid.io/, new DefaultProviderConversionStrategy());
65
+ _StrategyFactory.strategies.set(/ankr.com/, new AnkrProviderConversionStrategy());
66
+ _StrategyFactory.strategies.set(/quiknode.pro/, new QuiknodeProviderConversionStrategy());
67
+ var StrategyFactory = _StrategyFactory;
68
+
25
69
  // src/tron.ts
26
70
  var TronTransactionType = /* @__PURE__ */ ((TronTransactionType2) => {
27
71
  TronTransactionType2["TRIGGER_SMART_CONTRACT"] = "TriggerSmartContract";
@@ -30,8 +74,9 @@ var TronTransactionType = /* @__PURE__ */ ((TronTransactionType2) => {
30
74
  var logger = getLogger();
31
75
  function createTronWeb(signer) {
32
76
  if (!(signer instanceof TronWeb)) {
77
+ const fullHostUrl = typeof signer.rpcSetting === "string" ? signer.rpcSetting : signer.rpcSetting.url;
33
78
  const client = new TronWeb({
34
- fullHost: typeof signer.rpcSetting === "string" ? signer.rpcSetting : signer.rpcSetting.url,
79
+ fullHost: StrategyFactory.get(fullHostUrl).asREST(fullHostUrl),
35
80
  headers: {
36
81
  "TRON-PRO-API-KEY": typeof signer.rpcSetting === "string" ? "" : signer.rpcSetting.apiKey ?? ""
37
82
  },
@@ -126,7 +171,7 @@ var energyFactorsCache = /* @__PURE__ */ new Map();
126
171
  async function fullFillTxn(signer, txn, overrides = {}) {
127
172
  const apiKey = signer.fullNode.headers["TRON-PRO-API-KEY"];
128
173
  const etherProvider = new ethers.providers.StaticJsonRpcProvider({
129
- url: `${signer.fullNode.host}/jsonrpc`,
174
+ url: StrategyFactory.get(signer.fullNode.host).asJSONRPC(signer.fullNode.host),
130
175
  headers: {
131
176
  ...apiKey !== void 0 ? { "TRON-PRO-API-KEY": apiKey } : {}
132
177
  }
@@ -238,6 +283,6 @@ async function checkResult(tronWeb, txId) {
238
283
  return output;
239
284
  }
240
285
 
241
- export { TronTransactionType, checkResult, createTronWeb, fullFillTxn, sendTronTransaction, signAndSendTronTransaction, signTronTx, tronBoxDeploy };
286
+ export { StrategyFactory, TronTransactionType, checkResult, createTronWeb, fullFillTxn, sendTronTransaction, signAndSendTronTransaction, signTronTx, tronBoxDeploy };
242
287
  //# sourceMappingURL=out.js.map
243
288
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tron.ts","../src/time.ts"],"names":["TronTransactionType","overrides","txId","output"],"mappings":"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","sourcesContent":["import { ethers } from 'ethers'\nimport TronWeb from 'tronweb'\n\nimport { CmdExecutor, getLogger, getProjectPackageManager, sleep } from '@layerzerolabs/lz-utilities'\n\nimport { Time } from './time'\n\nimport type {\n BlockTransaction,\n ChainParameter,\n ContractExecutionParams,\n ContractInfo,\n Transaction,\n TransactionInfo,\n} from 'tronweb'\n\nexport enum TronTransactionType {\n TRIGGER_SMART_CONTRACT = 'TriggerSmartContract',\n}\n\nexport interface TransactionOverrides {\n gasLimit?: number\n gasPrice?: number\n energyFactor?: number\n value?: number\n}\n\nexport interface PartialTronTransaction {\n visible: boolean\n txID: string\n raw_data_hex: string\n raw_data: {\n contract: [PartialTronTransactionContract]\n }\n}\n\nexport interface TronTransaction extends PartialTronTransaction {\n raw_data: {\n contract: [FullTronTransactionContract]\n ref_block_bytes: string\n ref_block_hash: string\n expiration: number\n fee_limit: number\n timestamp: number\n }\n}\n\nexport interface SignedTronTransaction extends TronTransaction {\n signature: string[]\n}\n\ninterface PartialTronTransactionParameterValue {\n data: string\n contract_address: string\n owner_address: string\n}\n\ninterface TronTransactionParameterValue extends PartialTronTransactionParameterValue {\n token_id?: number\n call_token_value?: number\n call_value?: number\n}\n\ninterface TronTransactionParameter<T> {\n value: T\n type_url: `type.googleapis.com/protocol.${TronTransactionType}`\n}\n\ninterface TronTransactionContract<T> {\n parameter: TronTransactionParameter<T>\n type: TronTransactionType\n Permission_id?: number\n}\n\ntype PartialTronTransactionContract = TronTransactionContract<PartialTronTransactionParameterValue>\ntype FullTronTransactionContract = TronTransactionContract<TronTransactionParameterValue>\n\ninterface TronBlockHeaderRawData {\n number: number\n txTrieRoot: string\n witness_address: string\n parentHash: string\n timestamp: number\n}\n\ninterface TronBlockHeader {\n raw_data: TronBlockHeaderRawData\n witness_signature: string\n}\n\nexport interface TronBlockData {\n blockID: string\n block_header: TronBlockHeader\n}\n\ninterface TronWebError1 {\n code: string\n message: string\n txid: string\n}\n\ninterface TronWebError2 {\n Error: string\n}\ntype TronWebErrorResponse = TronWebError1 | TronWebError2\n\nexport {\n TronWeb,\n BlockTransaction,\n ContractExecutionParams,\n ChainParameter,\n Transaction,\n TronWebError1,\n TronWebError2,\n TronWebErrorResponse,\n}\n\nconst logger = getLogger()\n\nexport type ProviderSetting =\n | {\n url: string\n apiKey?: string\n }\n | string\n\nexport function createTronWeb(signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb): TronWeb {\n if (!(signer instanceof TronWeb)) {\n const client = new TronWeb({\n fullHost: typeof signer.rpcSetting === 'string' ? signer.rpcSetting : signer.rpcSetting.url,\n headers: {\n 'TRON-PRO-API-KEY': typeof signer.rpcSetting === 'string' ? '' : signer.rpcSetting.apiKey ?? '',\n },\n privateKey: signer.privateKey.replace(/^0x/, ''),\n })\n return client\n }\n return signer\n}\n\nexport async function tronBoxDeploy(\n workspace: string,\n network: string,\n tags: string[],\n executor?: 'yarn' | 'npm' | 'pnpm'\n): Promise<void> {\n // const tagsStr = tags.join(',')\n if (executor === undefined) executor = getProjectPackageManager(workspace)\n // get the package manager from the workspace\n\n for (const tag of tags) {\n const cmd = `${executor} pnpify tronbox migrate --network ${network} --f ${tag} --to ${tag}`\n // NODE: promisify exec may not work here when invoked from testify\n try {\n const cmdExecutor = new CmdExecutor()\n await cmdExecutor.executeCmd(\n cmd,\n [],\n { shell: true, cwd: workspace, env: process.env },\n true,\n undefined,\n logger\n )\n } catch (e) {\n console.log(e)\n }\n }\n}\n\nexport async function signAndSendTronTransaction(\n txn: {\n data: string\n to: string\n } & TransactionOverrides,\n signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb,\n permissionId?: number // for multi-sig\n): Promise<{ txId: string; result: any; wait: () => Promise<any> }> {\n const signedTxn = await signTronTx(txn, signer, permissionId)\n const client = createTronWeb(signer)\n return sendTronTransaction(signedTxn, client)\n}\n\nexport async function sendTronTransaction(\n singedTxn: SignedTronTransaction,\n client: TronWeb\n): Promise<{ txId: string; result: any; wait: () => Promise<TransactionInfo> }> {\n // reference: https://developers.tron.network/reference/json-rpc-api-overview\n // JSON-RPC interface is not fully supported by the TRON network.\n // Furthermore, The JSON-RPC service needs to be enabled and set the port in the node configuration\n // file. If not configured, the service is disable by default.\n // broadcast signedTransaction\n const broadcastResponse = await client.trx.sendRawTransaction(singedTxn)\n if (broadcastResponse.code !== undefined) {\n const err = {\n error: broadcastResponse.code,\n message: TronWeb.toUtf8(broadcastResponse.message ?? ''),\n }\n throw new Error(JSON.stringify(err, null, 2))\n }\n\n return {\n txId: singedTxn.txID,\n result: broadcastResponse,\n wait: async (): Promise<TransactionInfo> => {\n return checkResult(client, singedTxn.txID)\n },\n }\n}\n\nexport async function signTronTx(\n txn: {\n data: string\n to: string\n } & TransactionOverrides,\n _signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb,\n permissionId?: number // for multi-sig\n): Promise<SignedTronTransaction> {\n const signer: TronWeb = createTronWeb(_signer)\n\n // privateKey = privateKey.replace(/^0x/, '') // remove the 0x prefix\n // private key to address\n // const from = TronWeb.address.fromPrivateKey(privateKey)\n if (typeof signer.defaultAddress.hex !== 'string') {\n throw new Error(`signer.defaultAddress.hex is not a valid hex string`)\n }\n\n const partialTxn: PartialTronTransaction = {\n visible: false,\n txID: '',\n raw_data_hex: '',\n raw_data: {\n contract: [\n {\n parameter: {\n value: {\n data: txn.data.replace(/^0x/, ''),\n contract_address: TronWeb.address.toHex(txn.to),\n owner_address: signer.defaultAddress.hex,\n },\n type_url: `type.googleapis.com/protocol.${TronTransactionType.TRIGGER_SMART_CONTRACT}`,\n },\n type: TronTransactionType.TRIGGER_SMART_CONTRACT,\n Permission_id: permissionId,\n },\n ],\n },\n }\n\n const fullTxn = await fullFillTxn(signer, partialTxn, {\n gasLimit: txn.gasLimit,\n gasPrice: txn.gasPrice,\n energyFactor: txn.energyFactor,\n value: txn.value,\n })\n\n // sign transaction\n const signedTransaction = await signer.trx.sign(fullTxn)\n if (signedTransaction.signature === undefined) {\n throw new Error('Invalid private key provided')\n }\n return signedTransaction as SignedTronTransaction\n}\n\nlet gasPriceCache: { time: number; value: string } = { time: 0, value: '' }\nconst energyFactorsCache = new Map<string, { time: number; value: number }>()\n\nexport async function fullFillTxn(\n signer: TronWeb,\n txn: PartialTronTransaction,\n overrides: TransactionOverrides = {}\n): Promise<TronTransaction> {\n const apiKey = signer.fullNode.headers['TRON-PRO-API-KEY']\n const etherProvider = new ethers.providers.StaticJsonRpcProvider({\n url: `${signer.fullNode.host}/jsonrpc`,\n headers: {\n ...(apiKey !== undefined ? { 'TRON-PRO-API-KEY': apiKey } : {}),\n },\n })\n\n // cache the gasPrice with a 15sec TTL\n async function getGasPrice(): Promise<string> {\n const { time, value } = gasPriceCache\n if (time > Time.NOW - 15 * Time.SECOND && value != '') return value\n const newGaspPrice = await etherProvider.getGasPrice().then((x) => x.toString())\n gasPriceCache = { time: Time.NOW, value: newGaspPrice }\n return newGaspPrice\n }\n\n async function getGasLimit(raw: PartialTronTransaction): Promise<number> {\n const gasLimit = await etherProvider.estimateGas({\n to: raw.raw_data.contract[0].parameter.value.contract_address.replace(/^41/, '0x'), // need to slice off the \"41\" prefix that Tron appends to addresses\n data: '0x' + raw.raw_data.contract[0].parameter.value.data,\n from: raw.raw_data.contract[0].parameter.value.owner_address.replace(/^41/, '0x'),\n value: overrides.value ?? 0,\n })\n return gasLimit.toNumber()\n }\n\n // cache the energy_factor with a 10min TTL, energy factors should be updated by Tron every 6h\n async function getEnergyFactor(raw: PartialTronTransaction): Promise<number> {\n /* eslint-disable @typescript-eslint/no-unsafe-assignment */\n const addr = raw.raw_data.contract[0].parameter.value.contract_address\n const cached = energyFactorsCache.get(addr)\n if (cached && cached.time > Time.NOW - 10 * Time.MINUTE) return cached.value\n const MAX_ENERGY_FACTOR = 1.2\n // refers: https://developers.tron.network/reference/getcontractinfo\n const response = await signer.fullNode.request(\n 'wallet/getcontractinfo',\n { value: addr, visible: false },\n 'post'\n )\n const contractInfo: ContractInfo = response as ContractInfo\n const energy_factor = contractInfo.contract_state.energy_factor ?? MAX_ENERGY_FACTOR\n energyFactorsCache.set(addr, { time: Time.NOW, value: energy_factor })\n return energy_factor\n /* eslint-enable @typescript-eslint/no-unsafe-assignment */\n }\n\n async function getFeeLimit(raw: PartialTronTransaction, overrides: TransactionOverrides = {}): Promise<number> {\n // https://developers.tron.network/docs/set-feelimit#how-to-determine-the-feelimit-parameter\n // https://developers.tron.network/reference/getcontractinfo, get energy_factor\n // https://developers.tron.network/docs/resource-model#dynamic-energy-model, max factor\n // Tight FeeLimit of contract transaction = estimated basic energy consumption * (1 + energy_factor) * EnergyPrice\n // Loose FeeLimit of contract transaction = estimated basic energy consumption * (1 + max_energy_factor) * EnergyPrice\n const MAX_FEE_LIMIT = 15000000000\n const energy_factor = overrides.energyFactor ?? (await getEnergyFactor(raw))\n const gasLimit = overrides.gasLimit ?? (await getGasLimit(raw))\n const energyPrice = overrides.gasPrice ?? Number(await getGasPrice())\n const factor = 1 + energy_factor\n const feeLimit = gasLimit * factor * energyPrice\n const feeLimit_adjusted = Math.ceil(feeLimit) * 1.2 // based on reading other parts of the code, we add a 20% cushion on fee limits\n return Math.floor(Math.min(feeLimit_adjusted, MAX_FEE_LIMIT))\n }\n\n const metadata = (await signer.fullNode.request('wallet/getblock', { detail: false }, 'post')) as TronBlockData\n const ref_block_bytes = metadata.block_header.raw_data.number.toString(16).slice(-4).padStart(4, '0')\n const ref_block_hash = metadata.blockID.slice(16, 32)\n const expiration = metadata.block_header.raw_data.timestamp + 60 * 1000\n const { timestamp } = metadata.block_header.raw_data\n\n const tx: TronTransaction = {\n ...txn,\n raw_data: {\n contract: [\n {\n parameter: {\n value: {\n ...txn.raw_data.contract[0].parameter.value,\n call_value: overrides.value ?? 0,\n },\n type_url: txn.raw_data.contract[0].parameter.type_url,\n },\n type: txn.raw_data.contract[0].type,\n },\n ],\n ref_block_bytes,\n ref_block_hash,\n expiration,\n fee_limit: await getFeeLimit(txn, overrides),\n timestamp,\n },\n }\n const pb = signer.utils.transaction.txJsonToPb(tx)\n tx.txID = signer.utils.transaction.txPbToTxID(pb).replace(/^0x/, '')\n tx.raw_data_hex = signer.utils.transaction.txPbToRawDataHex(pb).toLowerCase()\n\n return tx\n}\n\nexport async function checkResult(tronWeb: TronWeb, txId: string): Promise<TransactionInfo> {\n const startTime = Date.now()\n const waitTimeout = 1000 * 60 * 5 // 5 minutes\n // TODO: get the block producer interval from the chain and sleep for that time\n const wait = async function (txId: string): Promise<TransactionInfo> {\n let tries = 0\n while (tries++ < 20) {\n const output = await tronWeb.trx.getTransactionInfo(txId)\n if (Object.keys(output).length > 0) {\n return output\n }\n\n // check if timeout\n if (Date.now() - startTime > waitTimeout) {\n throw new Error('Timeout waiting for transaction to be processed')\n }\n // wait 1 seconds for next check, mainnet block producer interval is 3 seconds,\n // but we need a small interval for the local network to speed up the test\n await sleep(1200)\n }\n throw new Error(`Failed to get transactionInfo for txId: ${txId}`)\n }\n\n const output = await wait(txId)\n\n if (process.env.CI === 'true') {\n console.trace('checkResult txId', txId)\n console.log('checkResult output', Object.keys(output), output)\n }\n\n if (output.result !== undefined && output.result === 'FAILED') {\n throw new Error(TronWeb.toUtf8(output.resMessage ?? ''))\n }\n\n if (!Object.prototype.hasOwnProperty.call(output, 'contractResult')) {\n throw new Error('Failed to execute: ' + JSON.stringify(output, null, 2))\n }\n\n return output\n}\n","// Base unit in milliseconds\nconst MILLISECOND = 1\nconst SECOND = 1000 * MILLISECOND\nconst MINUTE = 60 * SECOND\nconst HOUR = 60 * MINUTE\nconst DAY = 24 * HOUR\n\nexport const Time = {\n MILLISECOND,\n SECOND,\n MINUTE,\n HOUR,\n DAY,\n get NOW() {\n return Date.now()\n },\n} as const\n"]}
1
+ {"version":3,"sources":["../src/tron.ts","../src/time.ts","../src/url.ts"],"names":["TronTransactionType","overrides","txId","output"],"mappings":"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","sourcesContent":["import { ethers } from 'ethers'\nimport TronWeb from 'tronweb'\n\nimport { CmdExecutor, getLogger, getProjectPackageManager, sleep } from '@layerzerolabs/lz-utilities'\n\nimport { Time } from './time'\nimport { StrategyFactory } from './url'\n\nimport type {\n BlockTransaction,\n ChainParameter,\n ContractExecutionParams,\n ContractInfo,\n Transaction,\n TransactionInfo,\n} from 'tronweb'\n\nexport enum TronTransactionType {\n TRIGGER_SMART_CONTRACT = 'TriggerSmartContract',\n}\n\nexport interface TransactionOverrides {\n gasLimit?: number\n gasPrice?: number\n energyFactor?: number\n value?: number\n}\n\nexport interface PartialTronTransaction {\n visible: boolean\n txID: string\n raw_data_hex: string\n raw_data: {\n contract: [PartialTronTransactionContract]\n }\n}\n\nexport interface TronTransaction extends PartialTronTransaction {\n raw_data: {\n contract: [FullTronTransactionContract]\n ref_block_bytes: string\n ref_block_hash: string\n expiration: number\n fee_limit: number\n timestamp: number\n }\n}\n\nexport interface SignedTronTransaction extends TronTransaction {\n signature: string[]\n}\n\ninterface PartialTronTransactionParameterValue {\n data: string\n contract_address: string\n owner_address: string\n}\n\ninterface TronTransactionParameterValue extends PartialTronTransactionParameterValue {\n token_id?: number\n call_token_value?: number\n call_value?: number\n}\n\ninterface TronTransactionParameter<T> {\n value: T\n type_url: `type.googleapis.com/protocol.${TronTransactionType}`\n}\n\ninterface TronTransactionContract<T> {\n parameter: TronTransactionParameter<T>\n type: TronTransactionType\n Permission_id?: number\n}\n\ntype PartialTronTransactionContract = TronTransactionContract<PartialTronTransactionParameterValue>\ntype FullTronTransactionContract = TronTransactionContract<TronTransactionParameterValue>\n\ninterface TronBlockHeaderRawData {\n number: number\n txTrieRoot: string\n witness_address: string\n parentHash: string\n timestamp: number\n}\n\ninterface TronBlockHeader {\n raw_data: TronBlockHeaderRawData\n witness_signature: string\n}\n\nexport interface TronBlockData {\n blockID: string\n block_header: TronBlockHeader\n}\n\ninterface TronWebError1 {\n code: string\n message: string\n txid: string\n}\n\ninterface TronWebError2 {\n Error: string\n}\ntype TronWebErrorResponse = TronWebError1 | TronWebError2\n\nexport {\n TronWeb,\n BlockTransaction,\n ContractExecutionParams,\n ChainParameter,\n Transaction,\n TronWebError1,\n TronWebError2,\n TronWebErrorResponse,\n}\n\nconst logger = getLogger()\n\nexport type ProviderSetting =\n | {\n url: string\n apiKey?: string\n }\n | string\n\nexport function createTronWeb(signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb): TronWeb {\n if (!(signer instanceof TronWeb)) {\n const fullHostUrl = typeof signer.rpcSetting === 'string' ? signer.rpcSetting : signer.rpcSetting.url\n const client = new TronWeb({\n fullHost: StrategyFactory.get(fullHostUrl).asREST(fullHostUrl),\n headers: {\n 'TRON-PRO-API-KEY': typeof signer.rpcSetting === 'string' ? '' : signer.rpcSetting.apiKey ?? '',\n },\n privateKey: signer.privateKey.replace(/^0x/, ''),\n })\n return client\n }\n return signer\n}\n\nexport async function tronBoxDeploy(\n workspace: string,\n network: string,\n tags: string[],\n executor?: 'yarn' | 'npm' | 'pnpm'\n): Promise<void> {\n // const tagsStr = tags.join(',')\n if (executor === undefined) executor = getProjectPackageManager(workspace)\n // get the package manager from the workspace\n\n for (const tag of tags) {\n const cmd = `${executor} pnpify tronbox migrate --network ${network} --f ${tag} --to ${tag}`\n // NODE: promisify exec may not work here when invoked from testify\n try {\n const cmdExecutor = new CmdExecutor()\n await cmdExecutor.executeCmd(\n cmd,\n [],\n { shell: true, cwd: workspace, env: process.env },\n true,\n undefined,\n logger\n )\n } catch (e) {\n console.log(e)\n }\n }\n}\n\nexport async function signAndSendTronTransaction(\n txn: {\n data: string\n to: string\n } & TransactionOverrides,\n signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb,\n permissionId?: number // for multi-sig\n): Promise<{ txId: string; result: any; wait: () => Promise<any> }> {\n const signedTxn = await signTronTx(txn, signer, permissionId)\n const client = createTronWeb(signer)\n return sendTronTransaction(signedTxn, client)\n}\n\nexport async function sendTronTransaction(\n singedTxn: SignedTronTransaction,\n client: TronWeb\n): Promise<{ txId: string; result: any; wait: () => Promise<TransactionInfo> }> {\n // reference: https://developers.tron.network/reference/json-rpc-api-overview\n // JSON-RPC interface is not fully supported by the TRON network.\n // Furthermore, The JSON-RPC service needs to be enabled and set the port in the node configuration\n // file. If not configured, the service is disable by default.\n // broadcast signedTransaction\n const broadcastResponse = await client.trx.sendRawTransaction(singedTxn)\n if (broadcastResponse.code !== undefined) {\n const err = {\n error: broadcastResponse.code,\n message: TronWeb.toUtf8(broadcastResponse.message ?? ''),\n }\n throw new Error(JSON.stringify(err, null, 2))\n }\n\n return {\n txId: singedTxn.txID,\n result: broadcastResponse,\n wait: async (): Promise<TransactionInfo> => {\n return checkResult(client, singedTxn.txID)\n },\n }\n}\n\nexport async function signTronTx(\n txn: {\n data: string\n to: string\n } & TransactionOverrides,\n _signer: { rpcSetting: ProviderSetting; privateKey: string } | TronWeb,\n permissionId?: number // for multi-sig\n): Promise<SignedTronTransaction> {\n const signer: TronWeb = createTronWeb(_signer)\n\n // privateKey = privateKey.replace(/^0x/, '') // remove the 0x prefix\n // private key to address\n // const from = TronWeb.address.fromPrivateKey(privateKey)\n if (typeof signer.defaultAddress.hex !== 'string') {\n throw new Error(`signer.defaultAddress.hex is not a valid hex string`)\n }\n\n const partialTxn: PartialTronTransaction = {\n visible: false,\n txID: '',\n raw_data_hex: '',\n raw_data: {\n contract: [\n {\n parameter: {\n value: {\n data: txn.data.replace(/^0x/, ''),\n contract_address: TronWeb.address.toHex(txn.to),\n owner_address: signer.defaultAddress.hex,\n },\n type_url: `type.googleapis.com/protocol.${TronTransactionType.TRIGGER_SMART_CONTRACT}`,\n },\n type: TronTransactionType.TRIGGER_SMART_CONTRACT,\n Permission_id: permissionId,\n },\n ],\n },\n }\n\n const fullTxn = await fullFillTxn(signer, partialTxn, {\n gasLimit: txn.gasLimit,\n gasPrice: txn.gasPrice,\n energyFactor: txn.energyFactor,\n value: txn.value,\n })\n\n // sign transaction\n const signedTransaction = await signer.trx.sign(fullTxn)\n if (signedTransaction.signature === undefined) {\n throw new Error('Invalid private key provided')\n }\n return signedTransaction as SignedTronTransaction\n}\n\nlet gasPriceCache: { time: number; value: string } = { time: 0, value: '' }\nconst energyFactorsCache = new Map<string, { time: number; value: number }>()\n\nexport async function fullFillTxn(\n signer: TronWeb,\n txn: PartialTronTransaction,\n overrides: TransactionOverrides = {}\n): Promise<TronTransaction> {\n const apiKey = signer.fullNode.headers['TRON-PRO-API-KEY']\n const etherProvider = new ethers.providers.StaticJsonRpcProvider({\n url: StrategyFactory.get(signer.fullNode.host).asJSONRPC(signer.fullNode.host),\n headers: {\n ...(apiKey !== undefined ? { 'TRON-PRO-API-KEY': apiKey } : {}),\n },\n })\n\n // cache the gasPrice with a 15sec TTL\n async function getGasPrice(): Promise<string> {\n const { time, value } = gasPriceCache\n if (time > Time.NOW - 15 * Time.SECOND && value != '') return value\n const newGaspPrice = await etherProvider.getGasPrice().then((x) => x.toString())\n gasPriceCache = { time: Time.NOW, value: newGaspPrice }\n return newGaspPrice\n }\n\n async function getGasLimit(raw: PartialTronTransaction): Promise<number> {\n const gasLimit = await etherProvider.estimateGas({\n to: raw.raw_data.contract[0].parameter.value.contract_address.replace(/^41/, '0x'), // need to slice off the \"41\" prefix that Tron appends to addresses\n data: '0x' + raw.raw_data.contract[0].parameter.value.data,\n from: raw.raw_data.contract[0].parameter.value.owner_address.replace(/^41/, '0x'),\n value: overrides.value ?? 0,\n })\n return gasLimit.toNumber()\n }\n\n // cache the energy_factor with a 10min TTL, energy factors should be updated by Tron every 6h\n async function getEnergyFactor(raw: PartialTronTransaction): Promise<number> {\n /* eslint-disable @typescript-eslint/no-unsafe-assignment */\n const addr = raw.raw_data.contract[0].parameter.value.contract_address\n const cached = energyFactorsCache.get(addr)\n if (cached && cached.time > Time.NOW - 10 * Time.MINUTE) return cached.value\n const MAX_ENERGY_FACTOR = 1.2\n // refers: https://developers.tron.network/reference/getcontractinfo\n const response = await signer.fullNode.request(\n 'wallet/getcontractinfo',\n { value: addr, visible: false },\n 'post'\n )\n const contractInfo: ContractInfo = response as ContractInfo\n const energy_factor = contractInfo.contract_state.energy_factor ?? MAX_ENERGY_FACTOR\n energyFactorsCache.set(addr, { time: Time.NOW, value: energy_factor })\n return energy_factor\n /* eslint-enable @typescript-eslint/no-unsafe-assignment */\n }\n\n async function getFeeLimit(raw: PartialTronTransaction, overrides: TransactionOverrides = {}): Promise<number> {\n // https://developers.tron.network/docs/set-feelimit#how-to-determine-the-feelimit-parameter\n // https://developers.tron.network/reference/getcontractinfo, get energy_factor\n // https://developers.tron.network/docs/resource-model#dynamic-energy-model, max factor\n // Tight FeeLimit of contract transaction = estimated basic energy consumption * (1 + energy_factor) * EnergyPrice\n // Loose FeeLimit of contract transaction = estimated basic energy consumption * (1 + max_energy_factor) * EnergyPrice\n const MAX_FEE_LIMIT = 15000000000\n const energy_factor = overrides.energyFactor ?? (await getEnergyFactor(raw))\n const gasLimit = overrides.gasLimit ?? (await getGasLimit(raw))\n const energyPrice = overrides.gasPrice ?? Number(await getGasPrice())\n const factor = 1 + energy_factor\n const feeLimit = gasLimit * factor * energyPrice\n const feeLimit_adjusted = Math.ceil(feeLimit) * 1.2 // based on reading other parts of the code, we add a 20% cushion on fee limits\n return Math.floor(Math.min(feeLimit_adjusted, MAX_FEE_LIMIT))\n }\n\n const metadata = (await signer.fullNode.request('wallet/getblock', { detail: false }, 'post')) as TronBlockData\n const ref_block_bytes = metadata.block_header.raw_data.number.toString(16).slice(-4).padStart(4, '0')\n const ref_block_hash = metadata.blockID.slice(16, 32)\n const expiration = metadata.block_header.raw_data.timestamp + 60 * 1000\n const { timestamp } = metadata.block_header.raw_data\n\n const tx: TronTransaction = {\n ...txn,\n raw_data: {\n contract: [\n {\n parameter: {\n value: {\n ...txn.raw_data.contract[0].parameter.value,\n call_value: overrides.value ?? 0,\n },\n type_url: txn.raw_data.contract[0].parameter.type_url,\n },\n type: txn.raw_data.contract[0].type,\n },\n ],\n ref_block_bytes,\n ref_block_hash,\n expiration,\n fee_limit: await getFeeLimit(txn, overrides),\n timestamp,\n },\n }\n const pb = signer.utils.transaction.txJsonToPb(tx)\n tx.txID = signer.utils.transaction.txPbToTxID(pb).replace(/^0x/, '')\n tx.raw_data_hex = signer.utils.transaction.txPbToRawDataHex(pb).toLowerCase()\n\n return tx\n}\n\nexport async function checkResult(tronWeb: TronWeb, txId: string): Promise<TransactionInfo> {\n const startTime = Date.now()\n const waitTimeout = 1000 * 60 * 5 // 5 minutes\n // TODO: get the block producer interval from the chain and sleep for that time\n const wait = async function (txId: string): Promise<TransactionInfo> {\n let tries = 0\n while (tries++ < 20) {\n const output = await tronWeb.trx.getTransactionInfo(txId)\n if (Object.keys(output).length > 0) {\n return output\n }\n\n // check if timeout\n if (Date.now() - startTime > waitTimeout) {\n throw new Error('Timeout waiting for transaction to be processed')\n }\n // wait 1 seconds for next check, mainnet block producer interval is 3 seconds,\n // but we need a small interval for the local network to speed up the test\n await sleep(1200)\n }\n throw new Error(`Failed to get transactionInfo for txId: ${txId}`)\n }\n\n const output = await wait(txId)\n\n if (process.env.CI === 'true') {\n console.trace('checkResult txId', txId)\n console.log('checkResult output', Object.keys(output), output)\n }\n\n if (output.result !== undefined && output.result === 'FAILED') {\n throw new Error(TronWeb.toUtf8(output.resMessage ?? ''))\n }\n\n if (!Object.prototype.hasOwnProperty.call(output, 'contractResult')) {\n throw new Error('Failed to execute: ' + JSON.stringify(output, null, 2))\n }\n\n return output\n}\n","// Base unit in milliseconds\nconst MILLISECOND = 1\nconst SECOND = 1000 * MILLISECOND\nconst MINUTE = 60 * SECOND\nconst HOUR = 60 * MINUTE\nconst DAY = 24 * HOUR\n\nexport const Time = {\n MILLISECOND,\n SECOND,\n MINUTE,\n HOUR,\n DAY,\n get NOW() {\n return Date.now()\n },\n} as const\n","export interface ProviderConversionStrategy {\n asREST(url: string): string\n asJSONRPC(url: string): string\n}\n\nclass DefaultProviderConversionStrategy implements ProviderConversionStrategy {\n asREST(url: string): string {\n return url.replace(/\\/jsonrpc$/, '')\n }\n\n asJSONRPC(url: string): string {\n return url.trim().replace(/\\/?$/, '/jsonrpc')\n }\n}\n\nclass AnkrProviderConversionStrategy implements ProviderConversionStrategy {\n asREST(url: string): string {\n if (/tron\\/[0-9a-fA-F]{10,}/.test(url)) {\n return url.replace(/\\/tron_jsonrpc$/, '/premium-http/tron')\n }\n\n return url.replace(/\\/tron_jsonrpc$/, '/http/tron')\n }\n\n asJSONRPC(url: string): string {\n return url.trim().replace(/\\/(premium-http|http)\\/tron/, '/tron_jsonrpc')\n }\n}\n\nclass QuiknodeProviderConversionStrategy implements ProviderConversionStrategy {\n asREST(url: string): string {\n return url.replace(/\\/jsonrpc$/, '')\n }\n\n asJSONRPC(url: string): string {\n return url.trim().replace(/\\/?$/, '/jsonrpc')\n }\n}\n\nexport class StrategyFactory {\n public static strategies: Map<RegExp, ProviderConversionStrategy> = new Map()\n\n static {\n StrategyFactory.strategies.set(/api.trongrid.io/, new DefaultProviderConversionStrategy())\n StrategyFactory.strategies.set(/ankr.com/, new AnkrProviderConversionStrategy())\n StrategyFactory.strategies.set(/quiknode.pro/, new QuiknodeProviderConversionStrategy())\n }\n\n static get(url: string): ProviderConversionStrategy {\n for (const [pattern, strategy] of this.strategies) {\n if (pattern.test(url)) {\n return strategy\n }\n }\n return new DefaultProviderConversionStrategy()\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layerzerolabs/tron-utilities",
3
- "version": "2.3.4",
3
+ "version": "2.3.6",
4
4
  "license": "BUSL-1.1",
5
5
  "exports": {
6
6
  "types": "./dist/index.d.ts",
@@ -18,14 +18,14 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@ethersproject/providers": "^5.7.0",
21
- "@layerzerolabs/lz-utilities": "^2.3.4",
21
+ "@layerzerolabs/lz-utilities": "^2.3.6",
22
22
  "ethers": "^5.7.2",
23
23
  "tronweb": "^5.3.1"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@layerzerolabs/tronweb-typescript": "^0.0.0",
27
- "@layerzerolabs/tsup-config-next": "^2.3.4",
28
- "@layerzerolabs/typescript-config-next": "^2.3.4",
27
+ "@layerzerolabs/tsup-config-next": "^2.3.6",
28
+ "@layerzerolabs/typescript-config-next": "^2.3.6",
29
29
  "@types/tronweb": "npm:@layerzerolabs/tronweb-typescript@workspace:^",
30
30
  "rimraf": "^5.0.5",
31
31
  "tsup": "^8.0.1",