@lifi/sdk-provider-tron 4.0.0-alpha.21

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.
Files changed (95) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +79 -0
  3. package/dist/cjs/TronProvider.d.ts +2 -0
  4. package/dist/cjs/TronProvider.js +37 -0
  5. package/dist/cjs/TronProvider.js.map +1 -0
  6. package/dist/cjs/actions/getTronBalance.d.ts +2 -0
  7. package/dist/cjs/actions/getTronBalance.js +75 -0
  8. package/dist/cjs/actions/getTronBalance.js.map +1 -0
  9. package/dist/cjs/actions/resolveTronAddress.d.ts +1 -0
  10. package/dist/cjs/actions/resolveTronAddress.js +7 -0
  11. package/dist/cjs/actions/resolveTronAddress.js.map +1 -0
  12. package/dist/cjs/core/TronStepExecutor.d.ts +10 -0
  13. package/dist/cjs/core/TronStepExecutor.js +47 -0
  14. package/dist/cjs/core/TronStepExecutor.js.map +1 -0
  15. package/dist/cjs/core/tasks/TronSignAndExecuteTask.d.ts +5 -0
  16. package/dist/cjs/core/tasks/TronSignAndExecuteTask.js +26 -0
  17. package/dist/cjs/core/tasks/TronSignAndExecuteTask.js.map +1 -0
  18. package/dist/cjs/core/tasks/TronWaitForTransactionTask.d.ts +5 -0
  19. package/dist/cjs/core/tasks/TronWaitForTransactionTask.js +56 -0
  20. package/dist/cjs/core/tasks/TronWaitForTransactionTask.js.map +1 -0
  21. package/dist/cjs/errors/parseTronErrors.d.ts +2 -0
  22. package/dist/cjs/errors/parseTronErrors.js +43 -0
  23. package/dist/cjs/errors/parseTronErrors.js.map +1 -0
  24. package/dist/cjs/index.d.ts +3 -0
  25. package/dist/cjs/index.js +8 -0
  26. package/dist/cjs/index.js.map +1 -0
  27. package/dist/cjs/package.json +1 -0
  28. package/dist/cjs/types.d.ts +20 -0
  29. package/dist/cjs/types.js +8 -0
  30. package/dist/cjs/types.js.map +1 -0
  31. package/dist/cjs/version.d.ts +2 -0
  32. package/dist/cjs/version.js +6 -0
  33. package/dist/cjs/version.js.map +1 -0
  34. package/dist/esm/TronProvider.d.ts +2 -0
  35. package/dist/esm/TronProvider.js +34 -0
  36. package/dist/esm/TronProvider.js.map +1 -0
  37. package/dist/esm/actions/getTronBalance.d.ts +2 -0
  38. package/dist/esm/actions/getTronBalance.js +72 -0
  39. package/dist/esm/actions/getTronBalance.js.map +1 -0
  40. package/dist/esm/actions/resolveTronAddress.d.ts +1 -0
  41. package/dist/esm/actions/resolveTronAddress.js +5 -0
  42. package/dist/esm/actions/resolveTronAddress.js.map +1 -0
  43. package/dist/esm/core/TronStepExecutor.d.ts +10 -0
  44. package/dist/esm/core/TronStepExecutor.js +43 -0
  45. package/dist/esm/core/TronStepExecutor.js.map +1 -0
  46. package/dist/esm/core/tasks/TronSignAndExecuteTask.d.ts +5 -0
  47. package/dist/esm/core/tasks/TronSignAndExecuteTask.js +22 -0
  48. package/dist/esm/core/tasks/TronSignAndExecuteTask.js.map +1 -0
  49. package/dist/esm/core/tasks/TronWaitForTransactionTask.d.ts +5 -0
  50. package/dist/esm/core/tasks/TronWaitForTransactionTask.js +53 -0
  51. package/dist/esm/core/tasks/TronWaitForTransactionTask.js.map +1 -0
  52. package/dist/esm/errors/parseTronErrors.d.ts +2 -0
  53. package/dist/esm/errors/parseTronErrors.js +40 -0
  54. package/dist/esm/errors/parseTronErrors.js.map +1 -0
  55. package/dist/esm/index.d.ts +3 -0
  56. package/dist/esm/index.js +4 -0
  57. package/dist/esm/index.js.map +1 -0
  58. package/dist/esm/package.json +1 -0
  59. package/dist/esm/types.d.ts +20 -0
  60. package/dist/esm/types.js +5 -0
  61. package/dist/esm/types.js.map +1 -0
  62. package/dist/esm/version.d.ts +2 -0
  63. package/dist/esm/version.js +3 -0
  64. package/dist/esm/version.js.map +1 -0
  65. package/dist/types/TronProvider.d.ts +3 -0
  66. package/dist/types/TronProvider.d.ts.map +1 -0
  67. package/dist/types/actions/getTronBalance.d.ts +3 -0
  68. package/dist/types/actions/getTronBalance.d.ts.map +1 -0
  69. package/dist/types/actions/resolveTronAddress.d.ts +2 -0
  70. package/dist/types/actions/resolveTronAddress.d.ts.map +1 -0
  71. package/dist/types/core/TronStepExecutor.d.ts +11 -0
  72. package/dist/types/core/TronStepExecutor.d.ts.map +1 -0
  73. package/dist/types/core/tasks/TronSignAndExecuteTask.d.ts +6 -0
  74. package/dist/types/core/tasks/TronSignAndExecuteTask.d.ts.map +1 -0
  75. package/dist/types/core/tasks/TronWaitForTransactionTask.d.ts +6 -0
  76. package/dist/types/core/tasks/TronWaitForTransactionTask.d.ts.map +1 -0
  77. package/dist/types/errors/parseTronErrors.d.ts +3 -0
  78. package/dist/types/errors/parseTronErrors.d.ts.map +1 -0
  79. package/dist/types/index.d.ts +4 -0
  80. package/dist/types/index.d.ts.map +1 -0
  81. package/dist/types/types.d.ts +21 -0
  82. package/dist/types/types.d.ts.map +1 -0
  83. package/dist/types/version.d.ts +3 -0
  84. package/dist/types/version.d.ts.map +1 -0
  85. package/package.json +76 -0
  86. package/src/TronProvider.ts +48 -0
  87. package/src/actions/getTronBalance.ts +108 -0
  88. package/src/actions/resolveTronAddress.ts +6 -0
  89. package/src/core/TronStepExecutor.ts +88 -0
  90. package/src/core/tasks/TronSignAndExecuteTask.ts +53 -0
  91. package/src/core/tasks/TronWaitForTransactionTask.ts +102 -0
  92. package/src/errors/parseTronErrors.ts +83 -0
  93. package/src/index.ts +4 -0
  94. package/src/types.ts +38 -0
  95. package/src/version.ts +2 -0
@@ -0,0 +1,3 @@
1
+ import { type ExecutionAction, type LiFiStep, SDKError } from '@lifi/sdk';
2
+ export declare const parseTronErrors: (e: Error, step?: LiFiStep, action?: ExecutionAction) => Promise<SDKError>;
3
+ //# sourceMappingURL=parseTronErrors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseTronErrors.d.ts","sourceRoot":"","sources":["../../../src/errors/parseTronErrors.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EAEpB,KAAK,QAAQ,EACb,QAAQ,EAGT,MAAM,WAAW,CAAA;AASlB,eAAO,MAAM,eAAe,GAC1B,GAAG,KAAK,EACR,OAAO,QAAQ,EACf,SAAS,eAAe,KACvB,OAAO,CAAC,QAAQ,CAUlB,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { TronProvider } from './TronProvider.js';
2
+ export type { TronProviderOptions, TronSDKProvider } from './types.js';
3
+ export { isTronProvider } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,21 @@
1
+ import { type LiFiStepExtended, type SDKProvider, type StepExecutorContext, type StepExecutorOptions } from '@lifi/sdk';
2
+ import type { Adapter } from '@tronweb3/tronwallet-abstract-adapter';
3
+ import type { SignedTransaction } from 'tronweb/lib/esm/types/Transaction';
4
+ export interface TronProviderOptions {
5
+ getWallet?: () => Promise<Adapter>;
6
+ }
7
+ export interface TronTaskContext {
8
+ signedTransaction?: SignedTransaction;
9
+ }
10
+ export interface TronStepExecutorContext extends StepExecutorContext, TronTaskContext {
11
+ wallet: Adapter;
12
+ checkWallet: (step: LiFiStepExtended) => void;
13
+ }
14
+ export interface TronSDKProvider extends SDKProvider {
15
+ setOptions(options: TronProviderOptions): void;
16
+ }
17
+ export declare function isTronProvider(provider: SDKProvider): provider is TronSDKProvider;
18
+ export interface TronStepExecutorOptions extends StepExecutorOptions {
19
+ wallet: Adapter;
20
+ }
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACzB,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uCAAuC,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAA;AAE1E,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;CACtC;AAED,MAAM,WAAW,uBACf,SAAQ,mBAAmB,EACzB,eAAe;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAC9C;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,UAAU,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAA;CAC/C;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,WAAW,GACpB,QAAQ,IAAI,eAAe,CAE7B;AAED,MAAM,WAAW,uBAAwB,SAAQ,mBAAmB;IAClE,MAAM,EAAE,OAAO,CAAA;CAChB"}
@@ -0,0 +1,3 @@
1
+ export declare const name = "@lifi/sdk-provider-tron";
2
+ export declare const version = "4.0.0-alpha.21";
3
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,4BAA4B,CAAA;AAC7C,eAAO,MAAM,OAAO,mBAAmB,CAAA"}
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@lifi/sdk-provider-tron",
3
+ "version": "4.0.0-alpha.21",
4
+ "description": "LI.FI Tron SDK Provider for Any-to-Any Cross-Chain-Swap",
5
+ "homepage": "https://github.com/lifinance/sdk",
6
+ "bugs": {
7
+ "url": "https://github.com/lifinance/sdk/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/lifinance/sdk.git",
12
+ "directory": "packages/sdk-provider-tron"
13
+ },
14
+ "license": "Apache-2.0",
15
+ "author": "Eugene Chybisov <eugene@li.finance>",
16
+ "type": "module",
17
+ "sideEffects": false,
18
+ "main": "./dist/cjs/index.js",
19
+ "module": "./dist/esm/index.js",
20
+ "types": "./dist/types/index.d.ts",
21
+ "typings": "./dist/types/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/types/index.d.ts",
25
+ "import": "./dist/esm/index.js",
26
+ "default": "./dist/cjs/index.js"
27
+ },
28
+ "./package.json": "./package.json"
29
+ },
30
+ "dependencies": {
31
+ "@tronweb3/tronwallet-abstract-adapter": "^1.1.10",
32
+ "tronweb": "^6.0.4",
33
+ "@lifi/sdk": "4.0.0-alpha.21"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "files": [
39
+ "dist/**",
40
+ "!dist/**/*.tsbuildinfo",
41
+ "src/**/*.ts",
42
+ "!src/**/*.spec.ts",
43
+ "!src/**/*.test.ts",
44
+ "!src/**/*.mock.ts",
45
+ "!src/**/*.spec.ts",
46
+ "!src/**/*.handlers.ts",
47
+ "!src/**/*.tsbuildinfo",
48
+ "!**/__mocks__/**",
49
+ "!*.tmp",
50
+ "!*.env",
51
+ "!tsconfig.json"
52
+ ],
53
+ "keywords": [
54
+ "swap",
55
+ "bridge",
56
+ "bridge-aggregation",
57
+ "cross-chain",
58
+ "cross-chain-applications",
59
+ "cross-chain-bridge",
60
+ "dapp",
61
+ "defi",
62
+ "ethereum",
63
+ "bitcoin",
64
+ "solana",
65
+ "sui",
66
+ "tron",
67
+ "lifi",
68
+ "multi-chain",
69
+ "sdk",
70
+ "ethers",
71
+ "viem",
72
+ "wagmi",
73
+ "web3",
74
+ "web3-react"
75
+ ]
76
+ }
@@ -0,0 +1,48 @@
1
+ import {
2
+ ChainType,
3
+ LiFiErrorCode,
4
+ ProviderError,
5
+ type StepExecutorOptions,
6
+ } from '@lifi/sdk'
7
+ import { TronWeb } from 'tronweb'
8
+ import { getTronBalance } from './actions/getTronBalance.js'
9
+ import { resolveTronAddress } from './actions/resolveTronAddress.js'
10
+ import { TronStepExecutor } from './core/TronStepExecutor.js'
11
+ import type { TronProviderOptions, TronSDKProvider } from './types.js'
12
+
13
+ export function TronProvider(options?: TronProviderOptions): TronSDKProvider {
14
+ const _options: TronProviderOptions = options ?? {}
15
+ return {
16
+ get type() {
17
+ return ChainType.TVM
18
+ },
19
+ isAddress: (address: string) => TronWeb.isAddress(address),
20
+ resolveAddress: resolveTronAddress,
21
+ getBalance: getTronBalance,
22
+ async getStepExecutor(
23
+ options: StepExecutorOptions
24
+ ): Promise<TronStepExecutor> {
25
+ if (!_options.getWallet) {
26
+ throw new ProviderError(
27
+ LiFiErrorCode.ProviderUnavailable,
28
+ 'TronProvider requires a getWallet function.'
29
+ )
30
+ }
31
+
32
+ const wallet = await _options.getWallet()
33
+
34
+ const executor = new TronStepExecutor({
35
+ wallet,
36
+ routeId: options.routeId,
37
+ executionOptions: {
38
+ ...options.executionOptions,
39
+ },
40
+ })
41
+
42
+ return executor
43
+ },
44
+ setOptions(options: TronProviderOptions) {
45
+ Object.assign(_options, options)
46
+ },
47
+ }
48
+ }
@@ -0,0 +1,108 @@
1
+ import type { SDKClient, Token, TokenAmount } from '@lifi/sdk'
2
+ import { withDedupe } from '@lifi/sdk'
3
+ import { TronWeb } from 'tronweb'
4
+
5
+ export const getTronBalance = async (
6
+ client: SDKClient,
7
+ walletAddress: string,
8
+ tokens: Token[]
9
+ ): Promise<TokenAmount[]> => {
10
+ if (tokens.length === 0) {
11
+ return []
12
+ }
13
+ const { chainId } = tokens[0]
14
+ for (const token of tokens) {
15
+ if (token.chainId !== chainId) {
16
+ console.warn('Requested tokens have to be on the same chain.')
17
+ }
18
+ }
19
+
20
+ return getTronBalanceDefault(client, tokens, walletAddress)
21
+ }
22
+
23
+ const getTronBalanceDefault = async (
24
+ client: SDKClient,
25
+ tokens: Token[],
26
+ walletAddress: string
27
+ ): Promise<TokenAmount[]> => {
28
+ const rpcUrls = await client.getRpcUrlsByChainId(tokens[0].chainId)
29
+ const fullHost = rpcUrls[0] || 'https://api.trongrid.io'
30
+
31
+ const tronWeb = new TronWeb({ fullHost })
32
+
33
+ const [trxBalance, currentBlock] = await Promise.allSettled([
34
+ withDedupe(() => tronWeb.trx.getBalance(walletAddress), {
35
+ id: `${getTronBalanceDefault.name}.getBalance`,
36
+ }),
37
+ withDedupe(() => tronWeb.trx.getCurrentBlock(), {
38
+ id: `${getTronBalanceDefault.name}.getCurrentBlock`,
39
+ }),
40
+ ])
41
+
42
+ const nativeBalance =
43
+ trxBalance.status === 'fulfilled' ? BigInt(trxBalance.value) : 0n
44
+ const blockNumber =
45
+ currentBlock.status === 'fulfilled'
46
+ ? BigInt(currentBlock.value.block_header?.raw_data?.number ?? 0)
47
+ : 0n
48
+
49
+ const walletTokenAmounts: Record<string, bigint> = {}
50
+
51
+ // Identify native TRX tokens by checking for the zero address pattern
52
+ const nativeTokens = tokens.filter(
53
+ (token) =>
54
+ token.address === 'T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb' ||
55
+ token.address === '0x0000000000000000000000000000000000000000'
56
+ )
57
+ const trc20Tokens = tokens.filter(
58
+ (token) =>
59
+ token.address !== 'T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb' &&
60
+ token.address !== '0x0000000000000000000000000000000000000000'
61
+ )
62
+
63
+ for (const token of nativeTokens) {
64
+ walletTokenAmounts[token.address] = nativeBalance
65
+ }
66
+
67
+ if (trc20Tokens.length > 0) {
68
+ const trc20Balances = await Promise.allSettled(
69
+ trc20Tokens.map((token) =>
70
+ withDedupe(
71
+ async () => {
72
+ const contract = await tronWeb.contract().at(token.address)
73
+ const balance = await contract.balanceOf(walletAddress).call()
74
+ return {
75
+ address: token.address,
76
+ balance: BigInt(balance.toString()),
77
+ }
78
+ },
79
+ {
80
+ id: `${getTronBalanceDefault.name}.balanceOf.${token.address}`,
81
+ }
82
+ )
83
+ )
84
+ )
85
+
86
+ for (const result of trc20Balances) {
87
+ if (result.status === 'fulfilled' && result.value.balance > 0n) {
88
+ walletTokenAmounts[result.value.address] = result.value.balance
89
+ }
90
+ }
91
+ }
92
+
93
+ const tokenAmounts: TokenAmount[] = tokens.map((token) => {
94
+ if (walletTokenAmounts[token.address]) {
95
+ return {
96
+ ...token,
97
+ amount: walletTokenAmounts[token.address],
98
+ blockNumber,
99
+ }
100
+ }
101
+ return {
102
+ ...token,
103
+ blockNumber,
104
+ }
105
+ })
106
+
107
+ return tokenAmounts
108
+ }
@@ -0,0 +1,6 @@
1
+ export async function resolveTronAddress(
2
+ _name: string
3
+ ): Promise<string | undefined> {
4
+ // Tron does not have a widely-adopted name service
5
+ return undefined
6
+ }
@@ -0,0 +1,88 @@
1
+ import {
2
+ BaseStepExecutor,
3
+ CheckBalanceTask,
4
+ type ExecutionAction,
5
+ LiFiErrorCode,
6
+ type LiFiStepExtended,
7
+ PrepareTransactionTask,
8
+ type SDKError,
9
+ type StepExecutorBaseContext,
10
+ TaskPipeline,
11
+ TransactionError,
12
+ WaitForTransactionStatusTask,
13
+ } from '@lifi/sdk'
14
+ import type { Adapter } from '@tronweb3/tronwallet-abstract-adapter'
15
+ import { parseTronErrors } from '../errors/parseTronErrors.js'
16
+ import type {
17
+ TronStepExecutorContext,
18
+ TronStepExecutorOptions,
19
+ } from '../types.js'
20
+ import { TronSignAndExecuteTask } from './tasks/TronSignAndExecuteTask.js'
21
+ import { TronWaitForTransactionTask } from './tasks/TronWaitForTransactionTask.js'
22
+
23
+ export class TronStepExecutor extends BaseStepExecutor {
24
+ private wallet: Adapter
25
+
26
+ constructor(options: TronStepExecutorOptions) {
27
+ super(options)
28
+ this.wallet = options.wallet
29
+ }
30
+
31
+ checkWallet = (step: LiFiStepExtended) => {
32
+ const address = this.wallet.address
33
+ if (address && address !== step.action.fromAddress) {
34
+ throw new TransactionError(
35
+ LiFiErrorCode.WalletChangedDuringExecution,
36
+ 'The wallet address that requested the quote does not match the wallet address attempting to sign the transaction.'
37
+ )
38
+ }
39
+ }
40
+
41
+ override parseErrors = (
42
+ error: Error,
43
+ step?: LiFiStepExtended,
44
+ action?: ExecutionAction
45
+ ): Promise<SDKError> => parseTronErrors(error, step, action)
46
+
47
+ override createContext = async (
48
+ baseContext: StepExecutorBaseContext
49
+ ): Promise<TronStepExecutorContext> => {
50
+ return {
51
+ ...baseContext,
52
+ wallet: this.wallet,
53
+ checkWallet: this.checkWallet,
54
+ }
55
+ }
56
+
57
+ override createPipeline = (context: TronStepExecutorContext) => {
58
+ const { step, isBridgeExecution } = context
59
+
60
+ const tasks = [
61
+ new CheckBalanceTask(),
62
+ new PrepareTransactionTask(),
63
+ new TronSignAndExecuteTask(),
64
+ new TronWaitForTransactionTask(),
65
+ new WaitForTransactionStatusTask(
66
+ isBridgeExecution ? 'RECEIVING_CHAIN' : 'SWAP'
67
+ ),
68
+ ]
69
+
70
+ const swapOrBridgeAction = this.statusManager.findAction(
71
+ step,
72
+ isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'
73
+ )
74
+
75
+ const taskName =
76
+ swapOrBridgeAction?.txHash && swapOrBridgeAction?.status === 'DONE'
77
+ ? WaitForTransactionStatusTask.name
78
+ : CheckBalanceTask.name
79
+
80
+ const firstTaskIndex = tasks.findIndex(
81
+ (task) => task.constructor.name === taskName
82
+ )
83
+
84
+ const tasksToRun = tasks.slice(firstTaskIndex)
85
+
86
+ return new TaskPipeline(tasksToRun)
87
+ }
88
+ }
@@ -0,0 +1,53 @@
1
+ import {
2
+ BaseStepExecutionTask,
3
+ getTransactionRequestData,
4
+ LiFiErrorCode,
5
+ type TaskResult,
6
+ TransactionError,
7
+ } from '@lifi/sdk'
8
+ import type { TronStepExecutorContext } from '../../types.js'
9
+
10
+ export class TronSignAndExecuteTask extends BaseStepExecutionTask {
11
+ async run(context: TronStepExecutorContext): Promise<TaskResult> {
12
+ const {
13
+ step,
14
+ wallet,
15
+ statusManager,
16
+ executionOptions,
17
+ isBridgeExecution,
18
+ checkWallet,
19
+ } = context
20
+
21
+ const action = statusManager.findAction(
22
+ step,
23
+ isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'
24
+ )
25
+
26
+ if (!action) {
27
+ throw new TransactionError(
28
+ LiFiErrorCode.TransactionUnprepared,
29
+ 'Unable to prepare transaction. Action not found.'
30
+ )
31
+ }
32
+
33
+ const transactionRequestData = await getTransactionRequestData(
34
+ step,
35
+ executionOptions
36
+ )
37
+
38
+ checkWallet(step)
39
+
40
+ const unsignedTransaction = JSON.parse(transactionRequestData)
41
+
42
+ const signedTransaction = await wallet.signTransaction(unsignedTransaction)
43
+
44
+ statusManager.updateAction(step, action.type, 'PENDING', {
45
+ signedAt: Date.now(),
46
+ })
47
+
48
+ return {
49
+ status: 'COMPLETED',
50
+ context: { signedTransaction },
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,102 @@
1
+ import {
2
+ BaseStepExecutionTask,
3
+ LiFiErrorCode,
4
+ type TaskResult,
5
+ TransactionError,
6
+ } from '@lifi/sdk'
7
+ import { TronWeb } from 'tronweb'
8
+ import type { TronStepExecutorContext } from '../../types.js'
9
+
10
+ export class TronWaitForTransactionTask extends BaseStepExecutionTask {
11
+ async run(context: TronStepExecutorContext): Promise<TaskResult> {
12
+ const {
13
+ client,
14
+ step,
15
+ statusManager,
16
+ fromChain,
17
+ isBridgeExecution,
18
+ signedTransaction,
19
+ } = context
20
+
21
+ if (!signedTransaction) {
22
+ throw new TransactionError(
23
+ LiFiErrorCode.TransactionUnprepared,
24
+ 'Unable to prepare transaction. Signed transaction is not found.'
25
+ )
26
+ }
27
+
28
+ const action = statusManager.findAction(
29
+ step,
30
+ isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'
31
+ )
32
+ if (!action) {
33
+ throw new TransactionError(
34
+ LiFiErrorCode.TransactionUnprepared,
35
+ 'Unable to prepare transaction. Action not found.'
36
+ )
37
+ }
38
+
39
+ const rpcUrls = await client.getRpcUrlsByChainId(fromChain.id)
40
+ const fullHost = rpcUrls[0] || 'https://api.trongrid.io'
41
+ const tronWeb = new TronWeb({ fullHost })
42
+
43
+ const broadcastResult =
44
+ await tronWeb.trx.sendRawTransaction(signedTransaction)
45
+
46
+ if (!broadcastResult.result) {
47
+ throw new TransactionError(
48
+ LiFiErrorCode.TransactionFailed,
49
+ `Transaction broadcast failed: ${(broadcastResult as any).code || 'Unknown error'}`
50
+ )
51
+ }
52
+
53
+ const txHash = broadcastResult.transaction.txID
54
+
55
+ statusManager.updateAction(step, action.type, 'PENDING', {
56
+ txHash,
57
+ txLink: `${fromChain.metamask.blockExplorerUrls[0]}#/transaction/${txHash}`,
58
+ })
59
+
60
+ await waitForTronConfirmation(tronWeb, txHash)
61
+
62
+ if (isBridgeExecution) {
63
+ statusManager.updateAction(step, action.type, 'DONE')
64
+ }
65
+
66
+ return { status: 'COMPLETED' }
67
+ }
68
+ }
69
+
70
+ async function waitForTronConfirmation(
71
+ tronWeb: TronWeb,
72
+ txHash: string,
73
+ maxRetries = 20,
74
+ intervalMs = 3000
75
+ ): Promise<void> {
76
+ for (let i = 0; i < maxRetries; i++) {
77
+ try {
78
+ const txInfo = await tronWeb.trx.getTransactionInfo(txHash)
79
+
80
+ if (txInfo?.id) {
81
+ if (txInfo.receipt?.result === 'FAILED') {
82
+ throw new TransactionError(
83
+ LiFiErrorCode.TransactionFailed,
84
+ `Transaction failed on-chain: ${txInfo.receipt.result}`
85
+ )
86
+ }
87
+ return
88
+ }
89
+ } catch (error) {
90
+ if (error instanceof TransactionError) {
91
+ throw error
92
+ }
93
+ // Transaction info not yet available, continue polling
94
+ }
95
+ await new Promise((resolve) => setTimeout(resolve, intervalMs))
96
+ }
97
+
98
+ throw new TransactionError(
99
+ LiFiErrorCode.TransactionFailed,
100
+ 'Transaction confirmation timeout.'
101
+ )
102
+ }
@@ -0,0 +1,83 @@
1
+ import {
2
+ BaseError,
3
+ ErrorMessage,
4
+ type ExecutionAction,
5
+ LiFiErrorCode,
6
+ type LiFiStep,
7
+ SDKError,
8
+ TransactionError,
9
+ UnknownError,
10
+ } from '@lifi/sdk'
11
+ import {
12
+ WalletDisconnectedError,
13
+ WalletNotFoundError,
14
+ WalletNotSelectedError,
15
+ WalletSignTransactionError,
16
+ WalletWindowClosedError,
17
+ } from '@tronweb3/tronwallet-abstract-adapter'
18
+
19
+ export const parseTronErrors = async (
20
+ e: Error,
21
+ step?: LiFiStep,
22
+ action?: ExecutionAction
23
+ ): Promise<SDKError> => {
24
+ if (e instanceof SDKError) {
25
+ e.step = e.step ?? step
26
+ e.action = e.action ?? action
27
+ return e
28
+ }
29
+
30
+ const baseError = handleSpecificErrors(e)
31
+
32
+ return new SDKError(baseError, step, action)
33
+ }
34
+
35
+ const handleSpecificErrors = (e: any) => {
36
+ const message: string = typeof e === 'string' ? e : e.message || ''
37
+
38
+ if (
39
+ e instanceof WalletSignTransactionError ||
40
+ e instanceof WalletWindowClosedError
41
+ ) {
42
+ return new TransactionError(LiFiErrorCode.SignatureRejected, message, e)
43
+ }
44
+
45
+ if (
46
+ e instanceof WalletNotFoundError ||
47
+ e instanceof WalletNotSelectedError ||
48
+ e instanceof WalletDisconnectedError
49
+ ) {
50
+ return new TransactionError(
51
+ LiFiErrorCode.WalletChangedDuringExecution,
52
+ message,
53
+ e
54
+ )
55
+ }
56
+
57
+ // TronWeb trx.sign() validation errors
58
+ if (
59
+ message === 'Invalid transaction provided' ||
60
+ message === 'Invalid transaction' ||
61
+ message === 'Transaction is not signed'
62
+ ) {
63
+ return new TransactionError(LiFiErrorCode.TransactionUnprepared, message, e)
64
+ }
65
+
66
+ if (message === 'Transaction is already signed') {
67
+ return new TransactionError(LiFiErrorCode.TransactionFailed, message, e)
68
+ }
69
+
70
+ if (message === 'Private key does not match address in transaction') {
71
+ return new TransactionError(
72
+ LiFiErrorCode.WalletChangedDuringExecution,
73
+ message,
74
+ e
75
+ )
76
+ }
77
+
78
+ if (e instanceof BaseError) {
79
+ return e
80
+ }
81
+
82
+ return new UnknownError(message || ErrorMessage.UnknownError, e)
83
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ // biome-ignore lint/performance/noBarrelFile: module entrypoint
2
+ export { TronProvider } from './TronProvider.js'
3
+ export type { TronProviderOptions, TronSDKProvider } from './types.js'
4
+ export { isTronProvider } from './types.js'
package/src/types.ts ADDED
@@ -0,0 +1,38 @@
1
+ import {
2
+ ChainType,
3
+ type LiFiStepExtended,
4
+ type SDKProvider,
5
+ type StepExecutorContext,
6
+ type StepExecutorOptions,
7
+ } from '@lifi/sdk'
8
+ import type { Adapter } from '@tronweb3/tronwallet-abstract-adapter'
9
+ import type { SignedTransaction } from 'tronweb/lib/esm/types/Transaction'
10
+
11
+ export interface TronProviderOptions {
12
+ getWallet?: () => Promise<Adapter>
13
+ }
14
+
15
+ export interface TronTaskContext {
16
+ signedTransaction?: SignedTransaction
17
+ }
18
+
19
+ export interface TronStepExecutorContext
20
+ extends StepExecutorContext,
21
+ TronTaskContext {
22
+ wallet: Adapter
23
+ checkWallet: (step: LiFiStepExtended) => void
24
+ }
25
+
26
+ export interface TronSDKProvider extends SDKProvider {
27
+ setOptions(options: TronProviderOptions): void
28
+ }
29
+
30
+ export function isTronProvider(
31
+ provider: SDKProvider
32
+ ): provider is TronSDKProvider {
33
+ return provider.type === ChainType.TVM
34
+ }
35
+
36
+ export interface TronStepExecutorOptions extends StepExecutorOptions {
37
+ wallet: Adapter
38
+ }
package/src/version.ts ADDED
@@ -0,0 +1,2 @@
1
+ export const name = '@lifi/sdk-provider-tron'
2
+ export const version = '4.0.0-alpha.21'