web3-tools-mcp 1.6.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.
- package/CHANGELOG.md +95 -0
- package/README.md +328 -234
- package/dist/anvil.d.ts +1 -1
- package/dist/anvil.d.ts.map +1 -1
- package/dist/anvil.js +11 -9
- package/dist/anvil.js.map +1 -1
- package/dist/chain-meta.d.ts.map +1 -1
- package/dist/chain-meta.js +7 -3
- package/dist/chain-meta.js.map +1 -1
- package/dist/chains.d.ts +960 -0
- package/dist/chains.d.ts.map +1 -0
- package/dist/chains.js +108 -0
- package/dist/chains.js.map +1 -0
- package/dist/client.d.ts +10 -1717
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +33 -218
- package/dist/client.js.map +1 -1
- package/dist/http-server.d.ts +6 -0
- package/dist/http-server.d.ts.map +1 -1
- package/dist/http-server.js +55 -40
- package/dist/http-server.js.map +1 -1
- package/dist/index.js +50 -29
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts +31 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +227 -0
- package/dist/oauth.js.map +1 -0
- package/dist/preview.d.ts.map +1 -1
- package/dist/preview.js +2 -2
- package/dist/preview.js.map +1 -1
- package/dist/tools/advanced.d.ts +4 -4
- package/dist/tools/advanced.d.ts.map +1 -1
- package/dist/tools/advanced.js +228 -247
- package/dist/tools/advanced.js.map +1 -1
- package/dist/tools/balance.d.ts +1 -1
- package/dist/tools/balance.d.ts.map +1 -1
- package/dist/tools/balance.js +97 -103
- package/dist/tools/balance.js.map +1 -1
- package/dist/tools/contract-info.d.ts +3 -3
- package/dist/tools/contract-info.d.ts.map +1 -1
- package/dist/tools/contract-info.js +150 -161
- package/dist/tools/contract-info.js.map +1 -1
- package/dist/tools/contract.d.ts +4 -4
- package/dist/tools/contract.d.ts.map +1 -1
- package/dist/tools/contract.js +91 -110
- package/dist/tools/contract.js.map +1 -1
- package/dist/tools/ens.d.ts +6 -6
- package/dist/tools/ens.d.ts.map +1 -1
- package/dist/tools/ens.js +239 -297
- package/dist/tools/ens.js.map +1 -1
- package/dist/tools/gas.d.ts +4 -4
- package/dist/tools/gas.d.ts.map +1 -1
- package/dist/tools/gas.js +90 -138
- package/dist/tools/gas.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/logs.d.ts +1 -1
- package/dist/tools/logs.d.ts.map +1 -1
- package/dist/tools/logs.js +36 -37
- package/dist/tools/logs.js.map +1 -1
- package/dist/tools/signatures.d.ts.map +1 -1
- package/dist/tools/signatures.js +67 -89
- package/dist/tools/signatures.js.map +1 -1
- package/dist/tools/transactions.d.ts +35 -5
- package/dist/tools/transactions.d.ts.map +1 -1
- package/dist/tools/transactions.js +148 -74
- package/dist/tools/transactions.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +35 -98
- package/dist/utils.js.map +1 -1
- package/dist/wallet-client.d.ts +11 -1
- package/dist/wallet-client.d.ts.map +1 -1
- package/dist/wallet-client.js +27 -9
- package/dist/wallet-client.js.map +1 -1
- package/dist/walletconnect.d.ts +22 -1
- package/dist/walletconnect.d.ts.map +1 -1
- package/dist/walletconnect.js +101 -8
- package/dist/walletconnect.js.map +1 -1
- package/package.json +17 -9
- package/src/anvil.ts +15 -18
- package/src/chain-meta.ts +8 -4
- package/src/chains.ts +145 -0
- package/src/client.ts +39 -254
- package/src/http-server.ts +67 -44
- package/src/index.ts +77 -53
- package/src/oauth.ts +270 -0
- package/src/preview.ts +3 -12
- package/src/tools/advanced.ts +195 -213
- package/src/tools/balance.ts +103 -108
- package/src/tools/contract-info.ts +163 -184
- package/src/tools/contract.ts +123 -144
- package/src/tools/ens.ts +290 -345
- package/src/tools/gas.ts +122 -170
- package/src/tools/index.ts +2 -2
- package/src/tools/logs.ts +45 -43
- package/src/tools/signatures.ts +68 -86
- package/src/tools/transactions.ts +194 -87
- package/src/types.ts +1 -15
- package/src/utils.ts +52 -110
- package/src/wallet-client.ts +31 -9
- package/src/walletconnect.ts +119 -7
package/src/tools/balance.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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:
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
}
|