@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.
- package/LICENSE +201 -0
- package/README.md +79 -0
- package/dist/cjs/TronProvider.d.ts +2 -0
- package/dist/cjs/TronProvider.js +37 -0
- package/dist/cjs/TronProvider.js.map +1 -0
- package/dist/cjs/actions/getTronBalance.d.ts +2 -0
- package/dist/cjs/actions/getTronBalance.js +75 -0
- package/dist/cjs/actions/getTronBalance.js.map +1 -0
- package/dist/cjs/actions/resolveTronAddress.d.ts +1 -0
- package/dist/cjs/actions/resolveTronAddress.js +7 -0
- package/dist/cjs/actions/resolveTronAddress.js.map +1 -0
- package/dist/cjs/core/TronStepExecutor.d.ts +10 -0
- package/dist/cjs/core/TronStepExecutor.js +47 -0
- package/dist/cjs/core/TronStepExecutor.js.map +1 -0
- package/dist/cjs/core/tasks/TronSignAndExecuteTask.d.ts +5 -0
- package/dist/cjs/core/tasks/TronSignAndExecuteTask.js +26 -0
- package/dist/cjs/core/tasks/TronSignAndExecuteTask.js.map +1 -0
- package/dist/cjs/core/tasks/TronWaitForTransactionTask.d.ts +5 -0
- package/dist/cjs/core/tasks/TronWaitForTransactionTask.js +56 -0
- package/dist/cjs/core/tasks/TronWaitForTransactionTask.js.map +1 -0
- package/dist/cjs/errors/parseTronErrors.d.ts +2 -0
- package/dist/cjs/errors/parseTronErrors.js +43 -0
- package/dist/cjs/errors/parseTronErrors.js.map +1 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +8 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/types.d.ts +20 -0
- package/dist/cjs/types.js +8 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/version.d.ts +2 -0
- package/dist/cjs/version.js +6 -0
- package/dist/cjs/version.js.map +1 -0
- package/dist/esm/TronProvider.d.ts +2 -0
- package/dist/esm/TronProvider.js +34 -0
- package/dist/esm/TronProvider.js.map +1 -0
- package/dist/esm/actions/getTronBalance.d.ts +2 -0
- package/dist/esm/actions/getTronBalance.js +72 -0
- package/dist/esm/actions/getTronBalance.js.map +1 -0
- package/dist/esm/actions/resolveTronAddress.d.ts +1 -0
- package/dist/esm/actions/resolveTronAddress.js +5 -0
- package/dist/esm/actions/resolveTronAddress.js.map +1 -0
- package/dist/esm/core/TronStepExecutor.d.ts +10 -0
- package/dist/esm/core/TronStepExecutor.js +43 -0
- package/dist/esm/core/TronStepExecutor.js.map +1 -0
- package/dist/esm/core/tasks/TronSignAndExecuteTask.d.ts +5 -0
- package/dist/esm/core/tasks/TronSignAndExecuteTask.js +22 -0
- package/dist/esm/core/tasks/TronSignAndExecuteTask.js.map +1 -0
- package/dist/esm/core/tasks/TronWaitForTransactionTask.d.ts +5 -0
- package/dist/esm/core/tasks/TronWaitForTransactionTask.js +53 -0
- package/dist/esm/core/tasks/TronWaitForTransactionTask.js.map +1 -0
- package/dist/esm/errors/parseTronErrors.d.ts +2 -0
- package/dist/esm/errors/parseTronErrors.js +40 -0
- package/dist/esm/errors/parseTronErrors.js.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/types.d.ts +20 -0
- package/dist/esm/types.js +5 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/version.d.ts +2 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/types/TronProvider.d.ts +3 -0
- package/dist/types/TronProvider.d.ts.map +1 -0
- package/dist/types/actions/getTronBalance.d.ts +3 -0
- package/dist/types/actions/getTronBalance.d.ts.map +1 -0
- package/dist/types/actions/resolveTronAddress.d.ts +2 -0
- package/dist/types/actions/resolveTronAddress.d.ts.map +1 -0
- package/dist/types/core/TronStepExecutor.d.ts +11 -0
- package/dist/types/core/TronStepExecutor.d.ts.map +1 -0
- package/dist/types/core/tasks/TronSignAndExecuteTask.d.ts +6 -0
- package/dist/types/core/tasks/TronSignAndExecuteTask.d.ts.map +1 -0
- package/dist/types/core/tasks/TronWaitForTransactionTask.d.ts +6 -0
- package/dist/types/core/tasks/TronWaitForTransactionTask.d.ts.map +1 -0
- package/dist/types/errors/parseTronErrors.d.ts +3 -0
- package/dist/types/errors/parseTronErrors.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types.d.ts +21 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/version.d.ts +3 -0
- package/dist/types/version.d.ts.map +1 -0
- package/package.json +76 -0
- package/src/TronProvider.ts +48 -0
- package/src/actions/getTronBalance.ts +108 -0
- package/src/actions/resolveTronAddress.ts +6 -0
- package/src/core/TronStepExecutor.ts +88 -0
- package/src/core/tasks/TronSignAndExecuteTask.ts +53 -0
- package/src/core/tasks/TronWaitForTransactionTask.ts +102 -0
- package/src/errors/parseTronErrors.ts +83 -0
- package/src/index.ts +4 -0
- package/src/types.ts +38 -0
- package/src/version.ts +2 -0
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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,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
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