web3-tools-mcp 1.5.0 → 2.0.0

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 (109) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/README.md +346 -164
  3. package/dist/anvil.d.ts +1 -1
  4. package/dist/anvil.d.ts.map +1 -1
  5. package/dist/anvil.js +11 -9
  6. package/dist/anvil.js.map +1 -1
  7. package/dist/chain-meta.d.ts.map +1 -1
  8. package/dist/chain-meta.js +7 -3
  9. package/dist/chain-meta.js.map +1 -1
  10. package/dist/chains.d.ts +960 -0
  11. package/dist/chains.d.ts.map +1 -0
  12. package/dist/chains.js +108 -0
  13. package/dist/chains.js.map +1 -0
  14. package/dist/client.d.ts +10 -1717
  15. package/dist/client.d.ts.map +1 -1
  16. package/dist/client.js +33 -216
  17. package/dist/client.js.map +1 -1
  18. package/dist/http-server.d.ts +18 -0
  19. package/dist/http-server.d.ts.map +1 -0
  20. package/dist/http-server.js +89 -0
  21. package/dist/http-server.js.map +1 -0
  22. package/dist/index.js +77 -32
  23. package/dist/index.js.map +1 -1
  24. package/dist/kv-storage.d.ts +23 -0
  25. package/dist/kv-storage.d.ts.map +1 -0
  26. package/dist/kv-storage.js +69 -0
  27. package/dist/kv-storage.js.map +1 -0
  28. package/dist/oauth.d.ts +31 -0
  29. package/dist/oauth.d.ts.map +1 -0
  30. package/dist/oauth.js +227 -0
  31. package/dist/oauth.js.map +1 -0
  32. package/dist/preview.d.ts.map +1 -1
  33. package/dist/preview.js +14 -4
  34. package/dist/preview.js.map +1 -1
  35. package/dist/tools/advanced.d.ts +4 -4
  36. package/dist/tools/advanced.d.ts.map +1 -1
  37. package/dist/tools/advanced.js +228 -247
  38. package/dist/tools/advanced.js.map +1 -1
  39. package/dist/tools/balance.d.ts +1 -1
  40. package/dist/tools/balance.d.ts.map +1 -1
  41. package/dist/tools/balance.js +97 -103
  42. package/dist/tools/balance.js.map +1 -1
  43. package/dist/tools/contract-info.d.ts +3 -3
  44. package/dist/tools/contract-info.d.ts.map +1 -1
  45. package/dist/tools/contract-info.js +150 -161
  46. package/dist/tools/contract-info.js.map +1 -1
  47. package/dist/tools/contract.d.ts +4 -4
  48. package/dist/tools/contract.d.ts.map +1 -1
  49. package/dist/tools/contract.js +91 -110
  50. package/dist/tools/contract.js.map +1 -1
  51. package/dist/tools/ens.d.ts +6 -6
  52. package/dist/tools/ens.d.ts.map +1 -1
  53. package/dist/tools/ens.js +239 -297
  54. package/dist/tools/ens.js.map +1 -1
  55. package/dist/tools/gas.d.ts +4 -4
  56. package/dist/tools/gas.d.ts.map +1 -1
  57. package/dist/tools/gas.js +90 -138
  58. package/dist/tools/gas.js.map +1 -1
  59. package/dist/tools/index.d.ts +1 -1
  60. package/dist/tools/index.d.ts.map +1 -1
  61. package/dist/tools/logs.d.ts +1 -1
  62. package/dist/tools/logs.d.ts.map +1 -1
  63. package/dist/tools/logs.js +36 -37
  64. package/dist/tools/logs.js.map +1 -1
  65. package/dist/tools/signatures.d.ts.map +1 -1
  66. package/dist/tools/signatures.js +67 -89
  67. package/dist/tools/signatures.js.map +1 -1
  68. package/dist/tools/transactions.d.ts +48 -4
  69. package/dist/tools/transactions.d.ts.map +1 -1
  70. package/dist/tools/transactions.js +228 -44
  71. package/dist/tools/transactions.js.map +1 -1
  72. package/dist/types.d.ts +2 -1
  73. package/dist/types.d.ts.map +1 -1
  74. package/dist/utils.d.ts +3 -8
  75. package/dist/utils.d.ts.map +1 -1
  76. package/dist/utils.js +36 -98
  77. package/dist/utils.js.map +1 -1
  78. package/dist/wallet-client.d.ts +11 -1
  79. package/dist/wallet-client.d.ts.map +1 -1
  80. package/dist/wallet-client.js +27 -9
  81. package/dist/wallet-client.js.map +1 -1
  82. package/dist/walletconnect.d.ts +52 -0
  83. package/dist/walletconnect.d.ts.map +1 -0
  84. package/dist/walletconnect.js +221 -0
  85. package/dist/walletconnect.js.map +1 -0
  86. package/package.json +21 -9
  87. package/src/anvil.ts +15 -18
  88. package/src/chain-meta.ts +8 -4
  89. package/src/chains.ts +145 -0
  90. package/src/client.ts +39 -252
  91. package/src/http-server.ts +117 -0
  92. package/src/index.ts +98 -49
  93. package/src/kv-storage.ts +83 -0
  94. package/src/oauth.ts +270 -0
  95. package/src/preview.ts +15 -14
  96. package/src/tools/advanced.ts +195 -213
  97. package/src/tools/balance.ts +103 -108
  98. package/src/tools/contract-info.ts +163 -184
  99. package/src/tools/contract.ts +123 -144
  100. package/src/tools/ens.ts +290 -345
  101. package/src/tools/gas.ts +122 -170
  102. package/src/tools/index.ts +2 -2
  103. package/src/tools/logs.ts +45 -43
  104. package/src/tools/signatures.ts +68 -86
  105. package/src/tools/transactions.ts +283 -50
  106. package/src/types.ts +2 -15
  107. package/src/utils.ts +56 -127
  108. package/src/wallet-client.ts +31 -9
  109. package/src/walletconnect.ts +269 -0
@@ -1,16 +1,13 @@
1
1
  import { type Address, formatEther, formatUnits, isAddress } from 'viem'
2
2
  import { z } from 'zod'
3
- import type { ChainName } from '../types.js'
4
3
  import { getClientManager, SUPPORTED_CHAINS } from '../client.js'
4
+ import type { ChainName } from '../types.js'
5
5
  import { createTool, formatResponse } from '../utils.js'
6
6
 
7
7
  const BalanceQuerySchema = z.object({
8
8
  chain: z.enum(SUPPORTED_CHAINS).describe('The blockchain network to use'),
9
9
  address: z.string().describe('The address to check balance for'),
10
- tokenAddress: z
11
- .string()
12
- .optional()
13
- .describe('Token contract address (optional, if not provided returns native token balance)'),
10
+ tokenAddress: z.string().optional().describe('Token contract address (optional, if not provided returns native token balance)'),
14
11
  blockNumber: z.string().optional().describe('Block number to query (optional, defaults to latest)'),
15
12
  label: z.string().optional().describe('Optional label for batch results')
16
13
  })
@@ -20,7 +17,9 @@ export default {
20
17
  'Get Token Balances',
21
18
  'Retrieve native and ERC20 token balances for multiple addresses. BATCH OPTIMIZED - use for portfolio tracking, wallet monitoring.',
22
19
  z.object({
23
- queries: z.array(BalanceQuerySchema).describe('Array of balance queries. Omit tokenAddress for native balance, include for ERC20.')
20
+ queries: z
21
+ .array(BalanceQuerySchema)
22
+ .describe('Array of balance queries. Omit tokenAddress for native balance, include for ERC20.')
24
23
  }),
25
24
  async (args) => {
26
25
  // Group by chain and blockNumber for efficient processing
@@ -47,130 +46,126 @@ export default {
47
46
  error?: string
48
47
  }> = []
49
48
 
50
- try {
51
- // Process each group
52
- for (const [key, queries] of groupedQueries) {
53
- const [chain, blockNum] = key.split(':')
54
- const clientManager = getClientManager()
55
- const client = clientManager.getClient(chain as ChainName)
56
- const blockTag = blockNum === 'latest' ? 'latest' : BigInt(blockNum)
57
-
58
- // Process all queries in this group
59
- const results = await Promise.allSettled(
60
- queries.map(async (query) => {
61
- if (!isAddress(query.address)) {
62
- throw new Error(`Invalid address format: ${query.address}`)
63
- }
64
-
65
- const originalIndex = args.queries.indexOf(query)
66
-
67
- // Native token balance
68
- if (!query.tokenAddress) {
69
- const balance = await client.getBalance({
70
- address: query.address as Address,
71
- blockNumber: blockTag === 'latest' ? undefined : blockTag
72
- })
49
+ // Process each group
50
+ for (const [key, queries] of groupedQueries) {
51
+ const [chain, blockNum] = key.split(':')
52
+ const clientManager = getClientManager()
53
+ const client = clientManager.getClient(chain as ChainName)
54
+ const blockTag = blockNum === 'latest' ? 'latest' : BigInt(blockNum)
73
55
 
74
- return {
75
- index: originalIndex,
76
- label: query.label,
77
- address: query.address,
78
- chain: query.chain,
79
- blockNumber: query.blockNumber || 'latest',
80
- success: true,
81
- balance,
82
- balanceFormatted: formatEther(balance)
83
- }
84
- }
56
+ // Process all queries in this group
57
+ const results = await Promise.allSettled(
58
+ queries.map(async (query) => {
59
+ if (!isAddress(query.address)) {
60
+ throw new Error(`Invalid address format: ${query.address}`)
61
+ }
85
62
 
86
- // ERC20 token balance
87
- if (!isAddress(query.tokenAddress)) {
88
- throw new Error(`Invalid token address format: ${query.tokenAddress}`)
89
- }
63
+ const originalIndex = args.queries.indexOf(query)
90
64
 
91
- const balance = await client.readContract({
92
- address: query.tokenAddress as Address,
93
- abi: [
94
- {
95
- name: 'balanceOf',
96
- type: 'function',
97
- stateMutability: 'view',
98
- inputs: [{ name: 'account', type: 'address' }],
99
- outputs: [{ name: '', type: 'uint256' }]
100
- }
101
- ],
102
- functionName: 'balanceOf',
103
- args: [query.address as Address],
65
+ // Native token balance
66
+ if (!query.tokenAddress) {
67
+ const balance = await client.getBalance({
68
+ address: query.address as Address,
104
69
  blockNumber: blockTag === 'latest' ? undefined : blockTag
105
70
  })
106
71
 
107
- // Try to get decimals
108
- let decimals = 18
109
- try {
110
- decimals = (await client.readContract({
111
- address: query.tokenAddress as Address,
112
- abi: [
113
- {
114
- name: 'decimals',
115
- type: 'function',
116
- stateMutability: 'view',
117
- inputs: [],
118
- outputs: [{ name: '', type: 'uint8' }]
119
- }
120
- ],
121
- functionName: 'decimals',
122
- blockNumber: blockTag === 'latest' ? undefined : blockTag
123
- })) as number
124
- } catch {
125
- // Use default decimals if call fails
126
- }
127
-
128
72
  return {
129
73
  index: originalIndex,
130
74
  label: query.label,
131
75
  address: query.address,
132
- tokenAddress: query.tokenAddress,
133
76
  chain: query.chain,
134
77
  blockNumber: query.blockNumber || 'latest',
135
78
  success: true,
136
79
  balance,
137
- balanceFormatted: formatUnits(balance as bigint, decimals),
138
- decimals
80
+ balanceFormatted: formatEther(balance)
139
81
  }
82
+ }
83
+
84
+ // ERC20 token balance
85
+ if (!isAddress(query.tokenAddress)) {
86
+ throw new Error(`Invalid token address format: ${query.tokenAddress}`)
87
+ }
88
+
89
+ const balance = await client.readContract({
90
+ address: query.tokenAddress as Address,
91
+ abi: [
92
+ {
93
+ name: 'balanceOf',
94
+ type: 'function',
95
+ stateMutability: 'view',
96
+ inputs: [{ name: 'account', type: 'address' }],
97
+ outputs: [{ name: '', type: 'uint256' }]
98
+ }
99
+ ],
100
+ functionName: 'balanceOf',
101
+ args: [query.address as Address],
102
+ blockNumber: blockTag === 'latest' ? undefined : blockTag
140
103
  })
141
- )
142
104
 
143
- // Process results
144
- results.forEach((result, idx) => {
145
- if (result.status === 'fulfilled') {
146
- allResults[result.value.index] = result.value
147
- } else {
148
- const query = queries[idx]!
149
- const originalIndex = args.queries.indexOf(query)
150
- allResults[originalIndex] = {
151
- index: originalIndex,
152
- label: query.label,
153
- address: query.address,
154
- tokenAddress: query.tokenAddress,
155
- chain: query.chain,
156
- blockNumber: query.blockNumber || 'latest',
157
- success: false,
158
- error: result.reason instanceof Error ? result.reason.message : String(result.reason)
159
- }
105
+ // Try to get decimals
106
+ let decimals = 18
107
+ try {
108
+ decimals = (await client.readContract({
109
+ address: query.tokenAddress as Address,
110
+ abi: [
111
+ {
112
+ name: 'decimals',
113
+ type: 'function',
114
+ stateMutability: 'view',
115
+ inputs: [],
116
+ outputs: [{ name: '', type: 'uint8' }]
117
+ }
118
+ ],
119
+ functionName: 'decimals',
120
+ blockNumber: blockTag === 'latest' ? undefined : blockTag
121
+ })) as number
122
+ } catch {
123
+ // Use default decimals if call fails
124
+ }
125
+
126
+ return {
127
+ index: originalIndex,
128
+ label: query.label,
129
+ address: query.address,
130
+ tokenAddress: query.tokenAddress,
131
+ chain: query.chain,
132
+ blockNumber: query.blockNumber || 'latest',
133
+ success: true,
134
+ balance,
135
+ balanceFormatted: formatUnits(balance as bigint, decimals),
136
+ decimals
160
137
  }
161
138
  })
162
- }
139
+ )
163
140
 
164
- return formatResponse({
165
- success: true,
166
- totalQueries: args.queries.length,
167
- successfulQueries: allResults.filter((r) => r.success).length,
168
- failedQueries: allResults.filter((r) => !r.success).length,
169
- results: allResults
141
+ // Process results
142
+ results.forEach((result, idx) => {
143
+ if (result.status === 'fulfilled') {
144
+ allResults[result.value.index] = result.value
145
+ } else {
146
+ const query = queries[idx]!
147
+ const originalIndex = args.queries.indexOf(query)
148
+ allResults[originalIndex] = {
149
+ index: originalIndex,
150
+ label: query.label,
151
+ address: query.address,
152
+ tokenAddress: query.tokenAddress,
153
+ chain: query.chain,
154
+ blockNumber: query.blockNumber || 'latest',
155
+ success: false,
156
+ error: result.reason instanceof Error ? result.reason.message : String(result.reason)
157
+ }
158
+ }
170
159
  })
171
- } catch (error) {
172
- throw new Error(`Balance query failed: ${error}`)
173
160
  }
161
+
162
+ return formatResponse({
163
+ success: true,
164
+ totalQueries: args.queries.length,
165
+ successfulQueries: allResults.filter((r) => r.success).length,
166
+ failedQueries: allResults.filter((r) => !r.success).length,
167
+ results: allResults
168
+ })
174
169
  }
175
170
  )
176
171
  }