web3-tools-mcp 1.0.0 → 1.1.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 (135) hide show
  1. package/README.md +92 -259
  2. package/dist/client.d.ts +1653 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +142 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +78 -28274
  9. package/dist/index.js.map +1 -0
  10. package/dist/package.json +60 -0
  11. package/dist/src/client.d.ts +1653 -0
  12. package/dist/src/client.d.ts.map +1 -0
  13. package/dist/src/client.js +142 -0
  14. package/dist/src/client.js.map +1 -0
  15. package/dist/src/index.d.ts +3 -0
  16. package/dist/src/index.d.ts.map +1 -0
  17. package/dist/src/index.js +88 -0
  18. package/dist/src/index.js.map +1 -0
  19. package/dist/src/tools/advanced.d.ts +75 -0
  20. package/dist/src/tools/advanced.d.ts.map +1 -0
  21. package/dist/src/tools/advanced.js +234 -0
  22. package/dist/src/tools/advanced.js.map +1 -0
  23. package/dist/src/tools/balance.d.ts +55 -0
  24. package/dist/src/tools/balance.d.ts.map +1 -0
  25. package/dist/src/tools/balance.js +146 -0
  26. package/dist/src/tools/balance.js.map +1 -0
  27. package/dist/src/tools/contract-info.d.ts +79 -0
  28. package/dist/src/tools/contract-info.d.ts.map +1 -0
  29. package/dist/src/tools/contract-info.js +450 -0
  30. package/dist/src/tools/contract-info.js.map +1 -0
  31. package/dist/src/tools/contract.d.ts +79 -0
  32. package/dist/src/tools/contract.d.ts.map +1 -0
  33. package/dist/src/tools/contract.js +140 -0
  34. package/dist/src/tools/contract.js.map +1 -0
  35. package/dist/src/tools/index.d.ts +3 -0
  36. package/dist/src/tools/index.d.ts.map +1 -0
  37. package/dist/src/tools/index.js +27 -0
  38. package/dist/src/tools/index.js.map +1 -0
  39. package/dist/src/tools/logs.d.ts +39 -0
  40. package/dist/src/tools/logs.d.ts.map +1 -0
  41. package/dist/src/tools/logs.js +231 -0
  42. package/dist/src/tools/logs.js.map +1 -0
  43. package/dist/src/tools/signatures.d.ts +83 -0
  44. package/dist/src/tools/signatures.d.ts.map +1 -0
  45. package/dist/src/tools/signatures.js +93 -0
  46. package/dist/src/tools/signatures.js.map +1 -0
  47. package/dist/src/types.d.ts +22 -0
  48. package/dist/src/types.d.ts.map +1 -0
  49. package/dist/src/types.js +2 -0
  50. package/dist/src/types.js.map +1 -0
  51. package/dist/src/utils.d.ts +22 -0
  52. package/dist/src/utils.d.ts.map +1 -0
  53. package/dist/src/utils.js +183 -0
  54. package/dist/src/utils.js.map +1 -0
  55. package/dist/test/mcp-client.test.d.ts +2 -0
  56. package/dist/test/mcp-client.test.d.ts.map +1 -0
  57. package/dist/test/mcp-client.test.js +376 -0
  58. package/dist/test/mcp-client.test.js.map +1 -0
  59. package/dist/test/tools/advanced.test.d.ts +2 -0
  60. package/dist/test/tools/advanced.test.d.ts.map +1 -0
  61. package/dist/test/tools/advanced.test.js +235 -0
  62. package/dist/test/tools/advanced.test.js.map +1 -0
  63. package/dist/test/tools/balance.test.d.ts +2 -0
  64. package/dist/test/tools/balance.test.d.ts.map +1 -0
  65. package/dist/test/tools/balance.test.js +167 -0
  66. package/dist/test/tools/balance.test.js.map +1 -0
  67. package/dist/test/tools/contract-info.test.d.ts +2 -0
  68. package/dist/test/tools/contract-info.test.d.ts.map +1 -0
  69. package/dist/test/tools/contract-info.test.js +286 -0
  70. package/dist/test/tools/contract-info.test.js.map +1 -0
  71. package/dist/test/tools/contract.test.d.ts +2 -0
  72. package/dist/test/tools/contract.test.d.ts.map +1 -0
  73. package/dist/test/tools/contract.test.js +234 -0
  74. package/dist/test/tools/contract.test.js.map +1 -0
  75. package/dist/test/tools/logs.test.d.ts +2 -0
  76. package/dist/test/tools/logs.test.d.ts.map +1 -0
  77. package/dist/test/tools/logs.test.js +196 -0
  78. package/dist/test/tools/logs.test.js.map +1 -0
  79. package/dist/test/tools/signatures.test.d.ts +2 -0
  80. package/dist/test/tools/signatures.test.d.ts.map +1 -0
  81. package/dist/test/tools/signatures.test.js +112 -0
  82. package/dist/test/tools/signatures.test.js.map +1 -0
  83. package/dist/tools/advanced.d.ts +75 -0
  84. package/dist/tools/advanced.d.ts.map +1 -0
  85. package/dist/tools/advanced.js +234 -0
  86. package/dist/tools/advanced.js.map +1 -0
  87. package/dist/tools/balance.d.ts +55 -0
  88. package/dist/tools/balance.d.ts.map +1 -0
  89. package/dist/tools/balance.js +146 -0
  90. package/dist/tools/balance.js.map +1 -0
  91. package/dist/tools/batch.d.ts +122 -0
  92. package/dist/tools/batch.d.ts.map +1 -0
  93. package/dist/tools/batch.js +243 -0
  94. package/dist/tools/batch.js.map +1 -0
  95. package/dist/tools/contract-info.d.ts +79 -0
  96. package/dist/tools/contract-info.d.ts.map +1 -0
  97. package/dist/tools/contract-info.js +450 -0
  98. package/dist/tools/contract-info.js.map +1 -0
  99. package/dist/tools/contract.d.ts +79 -0
  100. package/dist/tools/contract.d.ts.map +1 -0
  101. package/dist/tools/contract.js +140 -0
  102. package/dist/tools/contract.js.map +1 -0
  103. package/dist/tools/index.d.ts +3 -0
  104. package/dist/tools/index.d.ts.map +1 -0
  105. package/dist/tools/index.js +27 -0
  106. package/dist/tools/index.js.map +1 -0
  107. package/dist/tools/logs.d.ts +39 -0
  108. package/dist/tools/logs.d.ts.map +1 -0
  109. package/dist/tools/logs.js +231 -0
  110. package/dist/tools/logs.js.map +1 -0
  111. package/dist/tools/signatures.d.ts +83 -0
  112. package/dist/tools/signatures.d.ts.map +1 -0
  113. package/dist/tools/signatures.js +93 -0
  114. package/dist/tools/signatures.js.map +1 -0
  115. package/dist/types.d.ts +22 -0
  116. package/dist/types.d.ts.map +1 -0
  117. package/dist/types.js +2 -0
  118. package/dist/types.js.map +1 -0
  119. package/dist/utils.d.ts +22 -0
  120. package/dist/utils.d.ts.map +1 -0
  121. package/dist/utils.js +183 -0
  122. package/dist/utils.js.map +1 -0
  123. package/package.json +35 -23
  124. package/src/client.ts +160 -0
  125. package/src/index.ts +96 -0
  126. package/src/tools/advanced.ts +262 -0
  127. package/src/tools/balance.ts +176 -0
  128. package/src/tools/contract-info.ts +582 -0
  129. package/src/tools/contract.ts +180 -0
  130. package/src/tools/index.ts +35 -0
  131. package/src/tools/logs.ts +291 -0
  132. package/src/tools/signatures.ts +126 -0
  133. package/src/types.ts +29 -0
  134. package/src/utils.ts +222 -0
  135. package/dist/hypersync-client.darwin-arm64-7fegfwn5.node +0 -0
package/src/utils.ts ADDED
@@ -0,0 +1,222 @@
1
+ import type { AbiParameter } from 'viem'
2
+ import type { ToolResult } from './types.js'
3
+ import { z } from 'zod'
4
+
5
+ // Create tool helper
6
+ export function createTool<T extends z.ZodType>(
7
+ title: string,
8
+ description: string,
9
+ schema: T,
10
+ handler: (args: z.infer<T>) => Promise<ToolResult>
11
+ ) {
12
+ return {
13
+ title,
14
+ description,
15
+ schema,
16
+ handler
17
+ }
18
+ }
19
+
20
+ // Convert BigInt values to strings for JSON serialization
21
+ export function convertBigIntToString(obj: unknown): unknown {
22
+ if (typeof obj === 'bigint') {
23
+ return obj.toString()
24
+ }
25
+ if (Array.isArray(obj)) {
26
+ return obj.map(item => convertBigIntToString(item))
27
+ }
28
+ if (obj && typeof obj === 'object') {
29
+ const converted: Record<string, unknown> = {}
30
+ for (const [key, value] of Object.entries(obj)) {
31
+ converted[key] = convertBigIntToString(value)
32
+ }
33
+ return converted
34
+ }
35
+ return obj
36
+ }
37
+
38
+ // Convert arguments to appropriate types based on ABI
39
+ export function convertArgumentsToTypes(
40
+ args: (string | number | boolean | null)[],
41
+ abiInputs: readonly AbiParameter[]
42
+ ): unknown[] {
43
+ return args.map((arg, index) => {
44
+ if (index >= abiInputs.length) {
45
+ throw new Error(`Too many arguments provided. Expected ${abiInputs.length}, got ${args.length}`)
46
+ }
47
+
48
+ const param = abiInputs[index]
49
+ if (!param?.type) {
50
+ throw new Error(`Missing type information for parameter at index ${index}`)
51
+ }
52
+
53
+ const paramType = param.type
54
+
55
+ // Handle null values
56
+ if (arg === null) {
57
+ return null
58
+ }
59
+
60
+ // Handle different parameter types
61
+ if (paramType === 'address') {
62
+ return String(arg)
63
+ }
64
+
65
+ if (paramType === 'bool') {
66
+ if (typeof arg === 'boolean') return arg
67
+ if (typeof arg === 'string') return arg.toLowerCase() === 'true'
68
+ return Boolean(arg)
69
+ }
70
+
71
+ if (paramType.startsWith('uint') || paramType.startsWith('int')) {
72
+ if (typeof arg === 'number') return BigInt(arg)
73
+ if (typeof arg === 'string') return BigInt(arg)
74
+ throw new Error(`Invalid type for ${paramType}: ${typeof arg}`)
75
+ }
76
+
77
+ if (paramType === 'string') {
78
+ return String(arg)
79
+ }
80
+
81
+ if (paramType === 'bytes' || paramType.startsWith('bytes')) {
82
+ return String(arg)
83
+ }
84
+
85
+ // For other types, try to convert appropriately
86
+ if (typeof arg === 'string' && arg.startsWith('0x')) {
87
+ return arg // Assume it's already properly formatted
88
+ }
89
+ return arg
90
+ })
91
+ }
92
+
93
+ // Convert event arguments to appropriate types
94
+ export function convertEventArgsToTypes(
95
+ eventArgs: Record<string, unknown>,
96
+ abiInputs: readonly AbiParameter[]
97
+ ): Record<string, unknown> {
98
+ const converted: Record<string, unknown> = {}
99
+
100
+ for (const [argName, argValue] of Object.entries(eventArgs)) {
101
+ // Find the parameter definition for this argument name
102
+ const param = abiInputs.find(input => input.name === argName)
103
+
104
+ if (!param) {
105
+ throw new Error(`Parameter '${argName}' not found in event ABI`)
106
+ }
107
+
108
+ if (!param.type) {
109
+ throw new Error(`Missing type information for parameter '${argName}'`)
110
+ }
111
+
112
+ const paramType = param.type
113
+
114
+ // Handle null/undefined values
115
+ if (argValue === null || argValue === undefined) {
116
+ converted[argName] = null
117
+ continue
118
+ }
119
+
120
+ // Handle different parameter types
121
+ if (paramType === 'address') {
122
+ converted[argName] = String(argValue)
123
+ } else if (paramType === 'bool') {
124
+ if (typeof argValue === 'boolean') {
125
+ converted[argName] = argValue
126
+ } else if (typeof argValue === 'string') {
127
+ converted[argName] = argValue.toLowerCase() === 'true'
128
+ } else {
129
+ converted[argName] = Boolean(argValue)
130
+ }
131
+ } else if (paramType.startsWith('uint') || paramType.startsWith('int')) {
132
+ if (typeof argValue === 'number') {
133
+ converted[argName] = BigInt(argValue)
134
+ } else if (typeof argValue === 'string') {
135
+ converted[argName] = BigInt(argValue)
136
+ } else {
137
+ throw new Error(`Invalid type for ${paramType}: ${typeof argValue}`)
138
+ }
139
+ } else if (paramType === 'string') {
140
+ converted[argName] = String(argValue)
141
+ } else if (paramType === 'bytes' || paramType.startsWith('bytes')) {
142
+ converted[argName] = String(argValue)
143
+ } else {
144
+ // For other types, handle arrays and try to convert appropriately
145
+ if (Array.isArray(argValue)) {
146
+ converted[argName] = argValue
147
+ } else if (typeof argValue === 'string' && argValue.startsWith('0x')) {
148
+ converted[argName] = argValue // Assume it's already properly formatted
149
+ } else {
150
+ converted[argName] = argValue
151
+ }
152
+ }
153
+ }
154
+
155
+ return converted
156
+ }
157
+
158
+ // Format response as tool result
159
+ export function formatResponse(data: unknown): ToolResult {
160
+ const serializable = convertBigIntToString(data)
161
+ return {
162
+ content: [
163
+ {
164
+ type: 'text',
165
+ text: JSON.stringify(serializable, null, 2)
166
+ }
167
+ ]
168
+ }
169
+ }
170
+
171
+ // Parse command line arguments
172
+ export function parseCommandLineArgs(): {
173
+ etherscanApiKey?: string
174
+ alchemyApiKey?: string
175
+ infuraApiKey?: string
176
+ customRpcUrls?: Record<string, string>
177
+ hypersyncApiKey?: string
178
+ showHelp?: boolean
179
+ } {
180
+ const config: {
181
+ etherscanApiKey?: string
182
+ alchemyApiKey?: string
183
+ infuraApiKey?: string
184
+ customRpcUrls?: Record<string, string>
185
+ hypersyncApiKey?: string
186
+ showHelp?: boolean
187
+ } = {}
188
+
189
+ function getArgValue(argName: string): string | undefined {
190
+ const args = process.argv
191
+ const index = args.findIndex(arg => arg === argName)
192
+ return index !== -1 && index + 1 < args.length ? args[index + 1] : undefined
193
+ }
194
+
195
+ function hasArg(argName: string): boolean {
196
+ return process.argv.includes(argName)
197
+ }
198
+
199
+ // Check for help flag
200
+ if (hasArg('--help') || hasArg('-h')) {
201
+ config.showHelp = true
202
+ return config
203
+ }
204
+
205
+ // Parse environment variables and command line arguments
206
+ config.etherscanApiKey = process.env.ETHERSCAN_API_KEY || getArgValue('--etherscan-api-key')
207
+ config.alchemyApiKey = process.env.ALCHEMY_API_KEY || getArgValue('--alchemy-api-key')
208
+ config.infuraApiKey = process.env.INFURA_API_KEY || getArgValue('--infura-api-key')
209
+ config.hypersyncApiKey = process.env.HYPERSYNC_API_KEY || getArgValue('--hypersync-api-key')
210
+
211
+ // Parse custom RPC URLs
212
+ const customRpcs = getArgValue('--custom-rpc')
213
+ if (customRpcs) {
214
+ try {
215
+ config.customRpcUrls = JSON.parse(customRpcs)
216
+ } catch {
217
+ console.error('Invalid JSON for --custom-rpc:', customRpcs)
218
+ }
219
+ }
220
+
221
+ return config
222
+ }