@sun-protocol/tron-mcp-server 1.0.0-beta.1

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 (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +282 -0
  3. package/bin/cli.js +51 -0
  4. package/build/core/chains.d.ts +17 -0
  5. package/build/core/chains.js +55 -0
  6. package/build/core/chains.js.map +1 -0
  7. package/build/core/prompts.d.ts +16 -0
  8. package/build/core/prompts.js +268 -0
  9. package/build/core/prompts.js.map +1 -0
  10. package/build/core/resources.d.ts +14 -0
  11. package/build/core/resources.js +42 -0
  12. package/build/core/resources.js.map +1 -0
  13. package/build/core/services/address.d.ts +8 -0
  14. package/build/core/services/address.js +52 -0
  15. package/build/core/services/address.js.map +1 -0
  16. package/build/core/services/balance.d.ts +26 -0
  17. package/build/core/services/balance.js +60 -0
  18. package/build/core/services/balance.js.map +1 -0
  19. package/build/core/services/blocks.d.ts +16 -0
  20. package/build/core/services/blocks.js +46 -0
  21. package/build/core/services/blocks.js.map +1 -0
  22. package/build/core/services/clients.d.ts +9 -0
  23. package/build/core/services/clients.js +46 -0
  24. package/build/core/services/clients.js.map +1 -0
  25. package/build/core/services/contracts.d.ts +50 -0
  26. package/build/core/services/contracts.js +225 -0
  27. package/build/core/services/contracts.js.map +1 -0
  28. package/build/core/services/index.d.ts +119 -0
  29. package/build/core/services/index.js +39 -0
  30. package/build/core/services/index.js.map +1 -0
  31. package/build/core/services/multicall-abi.d.ts +55 -0
  32. package/build/core/services/multicall-abi.js +61 -0
  33. package/build/core/services/multicall-abi.js.map +1 -0
  34. package/build/core/services/tokens.d.ts +22 -0
  35. package/build/core/services/tokens.js +68 -0
  36. package/build/core/services/tokens.js.map +1 -0
  37. package/build/core/services/transactions.d.ts +16 -0
  38. package/build/core/services/transactions.js +42 -0
  39. package/build/core/services/transactions.js.map +1 -0
  40. package/build/core/services/transfer.d.ts +24 -0
  41. package/build/core/services/transfer.js +70 -0
  42. package/build/core/services/transfer.js.map +1 -0
  43. package/build/core/services/utils.d.ts +13 -0
  44. package/build/core/services/utils.js +39 -0
  45. package/build/core/services/utils.js.map +1 -0
  46. package/build/core/services/wallet.d.ts +33 -0
  47. package/build/core/services/wallet.js +113 -0
  48. package/build/core/services/wallet.js.map +1 -0
  49. package/build/core/tools.d.ts +16 -0
  50. package/build/core/tools.js +792 -0
  51. package/build/core/tools.js.map +1 -0
  52. package/build/index.d.ts +1 -0
  53. package/build/index.js +20 -0
  54. package/build/index.js.map +1 -0
  55. package/build/server/http-server.d.ts +1 -0
  56. package/build/server/http-server.js +197 -0
  57. package/build/server/http-server.js.map +1 -0
  58. package/build/server/server.d.ts +3 -0
  59. package/build/server/server.js +46 -0
  60. package/build/server/server.js.map +1 -0
  61. package/package.json +90 -0
@@ -0,0 +1,268 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Register task-oriented prompts with the MCP server
4
+ *
5
+ * All prompts follow a consistent structure:
6
+ * - Clear objective statement
7
+ * - Step-by-step instructions
8
+ * - Expected outputs
9
+ * - Safety/security considerations
10
+ *
11
+ * Prompts guide the model through complex workflows that would otherwise
12
+ * require multiple tool calls in the correct sequence.
13
+ *
14
+ * @param server The MCP server instance
15
+ */
16
+ export function registerTRONPrompts(server) {
17
+ // ============================================================================
18
+ // TRANSACTION PROMPTS
19
+ // ============================================================================
20
+ server.registerPrompt("prepare_transfer", {
21
+ description: "Safely prepare and execute a token transfer with validation checks",
22
+ argsSchema: {
23
+ tokenType: z
24
+ .enum(["trx", "trc20"])
25
+ .describe("Token type: 'trx' for native or 'trc20' for contract tokens"),
26
+ recipient: z.string().describe("Recipient address"),
27
+ amount: z.string().describe("Amount to transfer (in TRX or token units)"),
28
+ network: z.string().optional().describe("Network name (default: mainnet)"),
29
+ tokenAddress: z.string().optional().describe("Token contract address (required for TRC20)"),
30
+ },
31
+ }, ({ tokenType, recipient, amount, network = "mainnet", tokenAddress }) => ({
32
+ messages: [
33
+ {
34
+ role: "user",
35
+ content: {
36
+ type: "text",
37
+ text: `# Token Transfer Task
38
+
39
+ **Objective**: Safely transfer ${amount} ${tokenType === "trx" ? "TRX" : "TRC20 tokens"} to ${recipient} on ${network}
40
+
41
+ ## Validation & Checks
42
+ Before executing any transfer:
43
+ 1. **Wallet Verification**: Call \`get_wallet_address\` to confirm the sending wallet
44
+ 2. **Balance Check**:
45
+ ${tokenType === "trx"
46
+ ? "- Call `get_balance` to verify TRX balance"
47
+ : `- Call \`get_token_balance\` with tokenAddress=${tokenAddress} to verify balance`}
48
+ 3. **Resource Analysis**: Call \`get_chain_parameters\` to assess current network costs (Energy/Bandwidth)
49
+
50
+ ## Execution Steps
51
+ ${tokenType === "trx"
52
+ ? `
53
+ 1. Summarize: sender address, recipient, amount, and estimated cost
54
+ 2. Request confirmation from user
55
+ 3. Call \`transfer_trx\` with to="${recipient}", amount="${amount}", network="${network}"
56
+ 4. Return transaction hash to user
57
+ 5. Call \`get_transaction_info\` to confirm completion
58
+ `
59
+ : `
60
+ 1. Summarize: sender, recipient, token, amount
61
+ 2. Request confirmation
62
+ 3. Call \`transfer_trc20\` with tokenAddress, recipient, amount
63
+ 4. Wait for confirmation with \`get_transaction_info\`
64
+ `}
65
+
66
+ ## Output Format
67
+ - **Transaction Hash**: Clear hex value
68
+ - **Status**: Pending or Confirmed
69
+ - **User Confirmation**: Always ask before sending
70
+
71
+ ## Safety Considerations
72
+ - Never send more than available balance
73
+ - Double-check recipient address
74
+ - Explain any approval requirements
75
+ `,
76
+ },
77
+ },
78
+ ],
79
+ }));
80
+ server.registerPrompt("diagnose_transaction", {
81
+ description: "Analyze transaction status, failures, and provide debugging insights",
82
+ argsSchema: {
83
+ txHash: z.string().describe("Transaction hash to diagnose"),
84
+ network: z.string().optional().describe("Network name (default: mainnet)"),
85
+ },
86
+ }, ({ txHash, network = "mainnet" }) => ({
87
+ messages: [
88
+ {
89
+ role: "user",
90
+ content: {
91
+ type: "text",
92
+ text: `# Transaction Diagnosis
93
+
94
+ **Objective**: Analyze transaction ${txHash} on ${network} and identify any issues
95
+
96
+ ## Investigation Process
97
+
98
+ ### 1. Gather Transaction Data
99
+ - Call \`get_transaction\` to fetch transaction details
100
+ - Call \`get_transaction_info\` to get status and energy/bandwidth used
101
+ - Note: both calls are read-only and free
102
+
103
+ ### 2. Status Assessment
104
+ Determine transaction state:
105
+ - **Pending**: Not yet mined
106
+ - **Confirmed**: Successfully executed (contractRet='SUCCESS')
107
+ - **Failed**: Execution failed (contractRet='REVERT' or other error)
108
+
109
+ ### 3. Failure Analysis
110
+ If transaction failed, investigate:
111
+
112
+ **Out of Energy**:
113
+ - Check energy_usage vs energy_limit
114
+ - If usage >= limit, suggest increasing fee limit
115
+
116
+ **Contract Revert**:
117
+ - Check function called and parameters
118
+ - Verify sufficient balance/approvals
119
+ - Look for require/revert statements in contract
120
+
121
+ ### 4. Resource Analysis
122
+ - Calculate energy/bandwidth cost
123
+ - Compare to current chain parameters
124
+
125
+ ## Output Format
126
+
127
+ Provide structured diagnosis:
128
+ - **Status**: Pending/Confirmed/Failed with reason
129
+ - **Transaction Hash**: The hash analyzed
130
+ - **From/To**: Addresses involved
131
+ - **Resource Usage**: Energy / Bandwidth used
132
+ - **Issue (if failed)**: Root cause and explanation
133
+ - **Recommended Actions**: Next steps to resolve
134
+ `,
135
+ },
136
+ },
137
+ ],
138
+ }));
139
+ // ============================================================================
140
+ // WALLET ANALYSIS PROMPTS
141
+ // ============================================================================
142
+ server.registerPrompt("analyze_wallet", {
143
+ description: "Get comprehensive overview of wallet assets, balances, and activity",
144
+ argsSchema: {
145
+ address: z.string().describe("Wallet address to analyze"),
146
+ network: z.string().optional().describe("Network name (default: mainnet)"),
147
+ tokens: z.string().optional().describe("Comma-separated token addresses to check"),
148
+ },
149
+ }, ({ address, network = "mainnet", tokens }) => {
150
+ const tokenList = tokens ? tokens.split(",").map((t) => t.trim()) : [];
151
+ return {
152
+ messages: [
153
+ {
154
+ role: "user",
155
+ content: {
156
+ type: "text",
157
+ text: `# Wallet Analysis
158
+
159
+ **Objective**: Provide complete asset overview for ${address} on ${network}
160
+
161
+ ## Information Gathering
162
+
163
+ ### 1. Address Resolution
164
+ - Call \`convert_address\` to get both Hex and Base58 formats
165
+
166
+ ### 2. Native Token Balance
167
+ - Call \`get_balance\` to fetch TRX balance
168
+ - Report both sun and TRX formats
169
+
170
+ ### 3. Token Balances
171
+ ${tokenList.length > 0
172
+ ? `- Call \`get_token_balance\` for each token:\n${tokenList.map((t) => ` * ${t}`).join("\n")}`
173
+ : `- If specific tokens provided: call \`get_token_balance\` for each`}
174
+
175
+ ## Output Format
176
+
177
+ Provide analysis with clear sections:
178
+
179
+ **Wallet Overview**
180
+ - Address (Base58): [address]
181
+ - Address (Hex): [hex]
182
+ - Network: [network]
183
+
184
+ **TRX Balance**
185
+ - TRX: [formatted amount]
186
+ - Sun: [raw amount]
187
+
188
+ **Token Holdings** (if requested)
189
+ - Token: [address]
190
+ - Symbol: [symbol]
191
+ - Balance: [formatted]
192
+ - Decimals: [decimals]
193
+
194
+ **Summary**
195
+ - Primary holdings
196
+ - Notable observations
197
+ `,
198
+ },
199
+ },
200
+ ],
201
+ };
202
+ });
203
+ // ============================================================================
204
+ // NETWORK & EDUCATION PROMPTS
205
+ // ============================================================================
206
+ server.registerPrompt("check_network_status", {
207
+ description: "Check current network health and conditions",
208
+ argsSchema: {
209
+ network: z.string().optional().describe("Network name (default: mainnet)"),
210
+ },
211
+ }, ({ network = "mainnet" }) => ({
212
+ messages: [
213
+ {
214
+ role: "user",
215
+ content: {
216
+ type: "text",
217
+ text: `# Network Status Check
218
+
219
+ **Objective**: Assess health and current conditions of ${network}
220
+
221
+ ## Status Assessment
222
+
223
+ ### 1. Gather Current Data
224
+ Call these read-only tools:
225
+ - \`get_chain_info\` for chain ID and current block number
226
+ - \`get_latest_block\` for block details and timing
227
+ - \`get_chain_parameters\` for current resource costs
228
+
229
+ ### 2. Network Health Analysis
230
+
231
+ **Block Production**:
232
+ - Current block number
233
+ - Block timing (normal ~3 sec for Tron)
234
+ - Consistent vs irregular blocks
235
+
236
+ **Resource Market**:
237
+ - Energy Fee
238
+ - Bandwidth Fee
239
+
240
+ **Overall Status**:
241
+ - Operational: Yes/No
242
+ - Issues detected: Yes/No
243
+
244
+ ## Output Format
245
+
246
+ **Network Status Report: ${network}**
247
+
248
+ **Overall Status**
249
+ - Operational Status: [Online/Degraded/Offline]
250
+ - Current Block: [number]
251
+ - Network Time: [timestamp]
252
+
253
+ **Performance Metrics**
254
+ - Block Time: [seconds] (normal: 3s)
255
+ - Energy Fee: [amount]
256
+ - Bandwidth Fee: [amount]
257
+
258
+ **Recommendations**
259
+
260
+ For **sending transactions now**:
261
+ - Status is Green/Yellow/Red
262
+ `,
263
+ },
264
+ },
265
+ ],
266
+ }));
267
+ }
268
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/core/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /**
3
+ * Register TRON-related resources with the MCP server
4
+ *
5
+ * Resources are application-driven, read-only data that clients can explicitly load.
6
+ * For an AI agent use case, most data should be exposed through tools instead,
7
+ * which allow the model to discover and autonomously fetch information.
8
+ *
9
+ * The supported_networks resource provides a static reference list that clients
10
+ * may want to browse when configuring which networks to use.
11
+ *
12
+ * @param server The MCP server instance
13
+ */
14
+ export declare function registerTRONResources(server: McpServer): void;
@@ -0,0 +1,42 @@
1
+ import { getSupportedNetworks } from "./chains.js";
2
+ /**
3
+ * Register TRON-related resources with the MCP server
4
+ *
5
+ * Resources are application-driven, read-only data that clients can explicitly load.
6
+ * For an AI agent use case, most data should be exposed through tools instead,
7
+ * which allow the model to discover and autonomously fetch information.
8
+ *
9
+ * The supported_networks resource provides a static reference list that clients
10
+ * may want to browse when configuring which networks to use.
11
+ *
12
+ * @param server The MCP server instance
13
+ */
14
+ export function registerTRONResources(server) {
15
+ server.registerResource("supported_networks", "tron://networks", {
16
+ description: "Get list of all supported TRON networks and their configuration",
17
+ mimeType: "application/json",
18
+ }, async (uri) => {
19
+ try {
20
+ const networks = getSupportedNetworks();
21
+ return {
22
+ contents: [
23
+ {
24
+ uri: uri.href,
25
+ text: JSON.stringify({ supportedNetworks: networks }, null, 2),
26
+ },
27
+ ],
28
+ };
29
+ }
30
+ catch (error) {
31
+ return {
32
+ contents: [
33
+ {
34
+ uri: uri.href,
35
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`,
36
+ },
37
+ ],
38
+ };
39
+ }
40
+ });
41
+ }
42
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/core/resources.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,gBAAgB,CACrB,oBAAoB,EACpB,iBAAiB,EACjB;QACE,WAAW,EAAE,iEAAiE;QAC9E,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,oBAAoB,EAAE,CAAC;YACxC,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG,EAAE,GAAG,CAAC,IAAI;wBACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,iBAAiB,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;qBAC/D;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG,EAAE,GAAG,CAAC,IAAI;wBACb,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACzE;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Service for handling address conversions (Hex <-> Base58)
3
+ */
4
+ export declare function toHexAddress(address: string): string;
5
+ export declare function toBase58Address(address: string): string;
6
+ export declare function isBase58(address: string): boolean;
7
+ export declare function isHex(address: string): boolean;
8
+ export declare const resolveAddress: (nameOrAddress: string, _network?: string) => Promise<string>;
@@ -0,0 +1,52 @@
1
+ import { TronWeb } from "tronweb";
2
+ /**
3
+ * Service for handling address conversions (Hex <-> Base58)
4
+ */
5
+ export function toHexAddress(address) {
6
+ if (address.startsWith("T")) {
7
+ return TronWeb.address.toHex(address);
8
+ }
9
+ return address;
10
+ }
11
+ export function toBase58Address(address) {
12
+ if (address.startsWith("41")) {
13
+ return TronWeb.address.fromHex(address);
14
+ }
15
+ if (address.startsWith("0x")) {
16
+ // TronWeb expects 41 prefix for hex addresses usually, but 0x might be passed from EVM habits
17
+ // 0x prefix usually needs to be replaced with 41 if it's a valid Tron address in hex
18
+ // However, TronWeb.address.fromHex handles 0x prefix by assuming it's an ETH address and converting?
19
+ // Let's rely on TronWeb's robust handling
20
+ return TronWeb.address.fromHex(address);
21
+ }
22
+ return address;
23
+ }
24
+ export function isBase58(address) {
25
+ return address.startsWith("T") && TronWeb.isAddress(address);
26
+ }
27
+ export function isHex(address) {
28
+ // Base58 addresses start with T, Hex addresses don't (0-9, a-f)
29
+ if (address.startsWith("T"))
30
+ return false;
31
+ let cleanAddress = address;
32
+ if (address.startsWith("0x")) {
33
+ cleanAddress = address.substring(2);
34
+ }
35
+ // If it's a 20-byte hex (40 chars), prefix with 41 to verify as a Tron address
36
+ // TronWeb.address.fromHex handles this auto-prefixing, so isHex should validate it too
37
+ if (cleanAddress.length === 40) {
38
+ cleanAddress = "41" + cleanAddress;
39
+ }
40
+ return TronWeb.isAddress(cleanAddress);
41
+ }
42
+ // Re-export utility for convenience
43
+ export const resolveAddress = async (nameOrAddress, _network) => {
44
+ // Tron doesn't have ENS exactly like ETH.
45
+ // If it's a valid address, return it.
46
+ if (TronWeb.isAddress(nameOrAddress)) {
47
+ return nameOrAddress;
48
+ }
49
+ // Future: Implement Tron NS resolution if needed
50
+ throw new Error(`Invalid address or unsupported name service: ${nameOrAddress}`);
51
+ };
52
+ //# sourceMappingURL=address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../../../src/core/services/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;GAEG;AAEH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,8FAA8F;QAC9F,qFAAqF;QACrF,qGAAqG;QACrG,0CAA0C;QAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,gEAAgE;IAChE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAE1C,IAAI,YAAY,GAAG,OAAO,CAAC;IAC3B,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,+EAA+E;IAC/E,uFAAuF;IACvF,IAAI,YAAY,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC/B,YAAY,GAAG,IAAI,GAAG,YAAY,CAAC;IACrC,CAAC;IAED,OAAO,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;AACzC,CAAC;AAED,oCAAoC;AACpC,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,aAAqB,EAAE,QAAiB,EAAmB,EAAE;IAChG,0CAA0C;IAC1C,sCAAsC;IACtC,IAAI,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC;QACrC,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,iDAAiD;IACjD,MAAM,IAAI,KAAK,CAAC,gDAAgD,aAAa,EAAE,CAAC,CAAC;AACnF,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Get TRX balance for an address
3
+ */
4
+ export declare function getTRXBalance(address: string, network?: string): Promise<{
5
+ wei: bigint;
6
+ ether: string;
7
+ formatted: string;
8
+ symbol: string;
9
+ decimals: number;
10
+ }>;
11
+ /**
12
+ * Get TRC20 token balance
13
+ */
14
+ export declare function getTRC20Balance(tokenAddress: string, walletAddress: string, network?: string): Promise<{
15
+ raw: bigint;
16
+ formatted: string;
17
+ token: {
18
+ symbol: any;
19
+ decimals: number;
20
+ address: string;
21
+ };
22
+ }>;
23
+ /**
24
+ * Get TRC1155 balance
25
+ */
26
+ export declare function getTRC1155Balance(contractAddress: string, ownerAddress: string, tokenId: bigint, network?: string): Promise<bigint>;
@@ -0,0 +1,60 @@
1
+ import { getTronWeb } from "./clients.js";
2
+ import { utils } from "./utils.js";
3
+ /**
4
+ * Get TRX balance for an address
5
+ */
6
+ export async function getTRXBalance(address, network = "mainnet") {
7
+ const tronWeb = getTronWeb(network);
8
+ const balanceSun = await tronWeb.trx.getBalance(address);
9
+ return {
10
+ wei: BigInt(balanceSun), // Keeping 'wei' property name for compatibility if tools rely on it, but strictly it's Sun
11
+ ether: utils.fromSun(balanceSun), // 'ether' -> TRX
12
+ formatted: utils.fromSun(balanceSun),
13
+ symbol: "TRX",
14
+ decimals: 6,
15
+ };
16
+ }
17
+ /**
18
+ * Get TRC20 token balance
19
+ */
20
+ export async function getTRC20Balance(tokenAddress, walletAddress, network = "mainnet") {
21
+ const tronWeb = getTronWeb(network);
22
+ try {
23
+ const contract = await tronWeb.contract().at(tokenAddress);
24
+ // TRC20 standard functions
25
+ const balance = await contract.methods.balanceOf(walletAddress).call();
26
+ const decimals = await contract.methods.decimals().call();
27
+ const symbol = await contract.methods.symbol().call();
28
+ const balanceBigInt = BigInt(balance.toString());
29
+ const divisor = BigInt(10) ** BigInt(decimals.toString());
30
+ // Basic formatting
31
+ const formatted = (Number(balanceBigInt) / Number(divisor)).toString();
32
+ return {
33
+ raw: balanceBigInt,
34
+ formatted: formatted,
35
+ token: {
36
+ symbol: symbol,
37
+ decimals: Number(decimals),
38
+ address: tokenAddress,
39
+ },
40
+ };
41
+ }
42
+ catch (error) {
43
+ throw new Error(`Failed to get TRC20 balance: ${error.message}`);
44
+ }
45
+ }
46
+ /**
47
+ * Get TRC1155 balance
48
+ */
49
+ export async function getTRC1155Balance(contractAddress, ownerAddress, tokenId, network = "mainnet") {
50
+ const tronWeb = getTronWeb(network);
51
+ try {
52
+ const contract = await tronWeb.contract().at(contractAddress);
53
+ const balance = await contract.methods.balanceOf(ownerAddress, tokenId.toString()).call();
54
+ return BigInt(balance.toString());
55
+ }
56
+ catch (error) {
57
+ throw new Error(`Failed to get TRC1155 balance: ${error.message}`);
58
+ }
59
+ }
60
+ //# sourceMappingURL=balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../../src/core/services/balance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ type Block = any;
2
+ /**
3
+ * Get block details by block number or hash
4
+ */
5
+ export declare function getBlockByNumber(blockNumber: number, network?: string): Promise<Block>;
6
+ export declare function getBlockByHash(blockHash: string, network?: string): Promise<Block>;
7
+ /**
8
+ * Get the latest block from the network
9
+ */
10
+ export declare function getLatestBlock(network?: string): Promise<Block>;
11
+ /**
12
+ * Get current block number
13
+ */
14
+ export declare function getBlockNumber(network?: string): Promise<number>;
15
+ export declare function getChainId(network?: string): Promise<number>;
16
+ export {};
@@ -0,0 +1,46 @@
1
+ import { getTronWeb } from "./clients.js";
2
+ /**
3
+ * Get block details by block number or hash
4
+ */
5
+ export async function getBlockByNumber(blockNumber, network = "mainnet") {
6
+ const tronWeb = getTronWeb(network);
7
+ const block = await tronWeb.trx.getBlock(blockNumber);
8
+ return block;
9
+ }
10
+ export async function getBlockByHash(blockHash, network = "mainnet") {
11
+ const tronWeb = getTronWeb(network);
12
+ const block = await tronWeb.trx.getBlock(blockHash);
13
+ return block;
14
+ }
15
+ /**
16
+ * Get the latest block from the network
17
+ */
18
+ export async function getLatestBlock(network = "mainnet") {
19
+ const tronWeb = getTronWeb(network);
20
+ const block = await tronWeb.trx.getCurrentBlock();
21
+ return block;
22
+ }
23
+ /**
24
+ * Get current block number
25
+ */
26
+ export async function getBlockNumber(network = "mainnet") {
27
+ const block = await getLatestBlock(network);
28
+ // Type assertion or checking structure; TronWeb block structure varies slightly by version/response
29
+ return block.block_header.raw_data.number;
30
+ }
31
+ // Chain ID is not standard in TronWeb like EVM, but we can return network ID or similar
32
+ // For compatibility with tool interface
33
+ export async function getChainId(network = "mainnet") {
34
+ // Tron Mainnet ID is often considered 0x2b6653dc (hex) or similar in some contexts,
35
+ // but typically we just return a placeholder or specific known ID if needed.
36
+ // FullNode info might have it.
37
+ // For now, mapping known networks to some integer IDs if needed, or just return 0
38
+ if (network === "mainnet")
39
+ return 728126428; // Tron Mainnet ID (often used)
40
+ if (network === "nile")
41
+ return 20191029; // Nile ID
42
+ if (network === "shasta")
43
+ return 1;
44
+ return 0;
45
+ }
46
+ //# sourceMappingURL=blocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../../src/core/services/blocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK1C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,WAAmB,EAAE,OAAO,GAAG,SAAS;IAC7E,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAiB,EAAE,OAAO,GAAG,SAAS;IACzE,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAO,GAAG,SAAS;IACtD,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;IAClD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAO,GAAG,SAAS;IACtD,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAC5C,oGAAoG;IACpG,OAAQ,KAAa,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC;AACrD,CAAC;AAED,wFAAwF;AACxF,wCAAwC;AACxC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAO,GAAG,SAAS;IAClD,oFAAoF;IACpF,6EAA6E;IAC7E,+BAA+B;IAE/B,kFAAkF;IAClF,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC,CAAC,+BAA+B;IAC5E,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,QAAQ,CAAC,CAAC,UAAU;IACnD,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { TronWeb } from "tronweb";
2
+ /**
3
+ * Get a TronWeb instance for a specific network
4
+ */
5
+ export declare function getTronWeb(network?: string): TronWeb;
6
+ /**
7
+ * Create a TronWeb instance with a private key for signing
8
+ */
9
+ export declare function getWallet(privateKey: string, network?: string): TronWeb;
@@ -0,0 +1,46 @@
1
+ import { TronWeb } from "tronweb";
2
+ import { getNetworkConfig } from "../chains.js";
3
+ // Cache for clients to avoid recreating them for each request
4
+ const clientCache = new Map();
5
+ /**
6
+ * Get a TronWeb instance for a specific network
7
+ */
8
+ export function getTronWeb(network = "mainnet") {
9
+ const cacheKey = String(network);
10
+ // Return cached client if available
11
+ if (clientCache.has(cacheKey)) {
12
+ return clientCache.get(cacheKey);
13
+ }
14
+ // Create a new client
15
+ const config = getNetworkConfig(network);
16
+ const apiKey = process.env.TRONGRID_API_KEY;
17
+ const client = new TronWeb({
18
+ fullHost: config.fullNode,
19
+ solidityNode: config.solidityNode,
20
+ eventServer: config.eventServer,
21
+ headers: apiKey ? { "TRON-PRO-API-KEY": apiKey } : undefined,
22
+ });
23
+ // Set a default address for read-only calls that might require it
24
+ client.setAddress("T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb");
25
+ // Cache the client
26
+ clientCache.set(cacheKey, client);
27
+ return client;
28
+ }
29
+ /**
30
+ * Create a TronWeb instance with a private key for signing
31
+ */
32
+ export function getWallet(privateKey, network = "mainnet") {
33
+ const config = getNetworkConfig(network);
34
+ const apiKey = process.env.TRONGRID_API_KEY;
35
+ // TronWeb expects private key without 0x prefix usually, but handles it if present?
36
+ // Let's strip 0x to be safe as TronWeb often prefers clean hex
37
+ const cleanKey = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
38
+ return new TronWeb({
39
+ fullHost: config.fullNode,
40
+ solidityNode: config.solidityNode,
41
+ eventServer: config.eventServer,
42
+ privateKey: cleanKey,
43
+ headers: apiKey ? { "TRON-PRO-API-KEY": apiKey } : undefined,
44
+ });
45
+ }
46
+ //# sourceMappingURL=clients.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.js","sourceRoot":"","sources":["../../../src/core/services/clients.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,8DAA8D;AAC9D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAmB,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAAO,GAAG,SAAS;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjC,oCAAoC;IACpC,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,OAAO,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;IACpC,CAAC;IAED,sBAAsB;IACtB,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAE5C,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS;KAC7D,CAAC,CAAC;IAEH,kEAAkE;IAClE,MAAM,CAAC,UAAU,CAAC,oCAAoC,CAAC,CAAC;IAExD,mBAAmB;IACnB,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,UAAkB,EAAE,OAAO,GAAG,SAAS;IAC/D,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAE5C,oFAAoF;IACpF,+DAA+D;IAC/D,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAEhF,OAAO,IAAI,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,QAAQ;QACpB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS;KAC7D,CAAC,CAAC;AACL,CAAC"}