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.
- package/CHANGELOG.md +95 -0
- package/README.md +346 -164
- 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 -216
- package/dist/client.js.map +1 -1
- package/dist/http-server.d.ts +18 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +89 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.js +77 -32
- package/dist/index.js.map +1 -1
- package/dist/kv-storage.d.ts +23 -0
- package/dist/kv-storage.d.ts.map +1 -0
- package/dist/kv-storage.js +69 -0
- package/dist/kv-storage.js.map +1 -0
- 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 +14 -4
- 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 +48 -4
- package/dist/tools/transactions.d.ts.map +1 -1
- package/dist/tools/transactions.js +228 -44
- package/dist/tools/transactions.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +3 -8
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +36 -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 +52 -0
- package/dist/walletconnect.d.ts.map +1 -0
- package/dist/walletconnect.js +221 -0
- package/dist/walletconnect.js.map +1 -0
- package/package.json +21 -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 -252
- package/src/http-server.ts +117 -0
- package/src/index.ts +98 -49
- package/src/kv-storage.ts +83 -0
- package/src/oauth.ts +270 -0
- package/src/preview.ts +15 -14
- 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 +283 -50
- package/src/types.ts +2 -15
- package/src/utils.ts +56 -127
- package/src/wallet-client.ts +31 -9
- package/src/walletconnect.ts +269 -0
package/dist/tools/ens.js
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import { isAddress, namehash } from
|
|
2
|
-
import { normalize } from
|
|
3
|
-
import { z } from
|
|
4
|
-
import { getClientManager, SUPPORTED_CHAINS } from
|
|
5
|
-
import { createTool, formatResponse } from
|
|
1
|
+
import { isAddress, namehash } from 'viem';
|
|
2
|
+
import { normalize } from 'viem/ens';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { getClientManager, SUPPORTED_CHAINS } from '../client.js';
|
|
5
|
+
import { createTool, formatResponse } from '../utils.js';
|
|
6
6
|
// Base ENS Contract Addresses
|
|
7
7
|
const BASE_ENS_CONTRACTS = {
|
|
8
|
-
registry:
|
|
9
|
-
reverseRegistrar:
|
|
10
|
-
l2Resolver:
|
|
8
|
+
registry: '0xb94704422c2a1e396835a571837aa5ae53285a95',
|
|
9
|
+
reverseRegistrar: '0x79ea96012eea67a83431f1701b3dff7e37f9e282',
|
|
10
|
+
l2Resolver: '0xC6d566A56A1aFf6508b41f6c90ff131615583BCD'
|
|
11
11
|
};
|
|
12
12
|
// Helper function for Base ENS reverse resolution
|
|
13
13
|
async function reverseResolveBase(address) {
|
|
14
14
|
const clientManager = getClientManager();
|
|
15
|
-
const client = clientManager.getClient(
|
|
15
|
+
const client = clientManager.getClient('base');
|
|
16
16
|
try {
|
|
17
17
|
// Get the reverse node from ReverseRegistrar
|
|
18
18
|
const reverseNode = await client.readContract({
|
|
19
19
|
address: BASE_ENS_CONTRACTS.reverseRegistrar,
|
|
20
20
|
abi: [
|
|
21
21
|
{
|
|
22
|
-
name:
|
|
23
|
-
type:
|
|
24
|
-
stateMutability:
|
|
25
|
-
inputs: [{ name:
|
|
26
|
-
outputs: [{ name:
|
|
27
|
-
}
|
|
22
|
+
name: 'node',
|
|
23
|
+
type: 'function',
|
|
24
|
+
stateMutability: 'pure',
|
|
25
|
+
inputs: [{ name: 'addr', type: 'address' }],
|
|
26
|
+
outputs: [{ name: '', type: 'bytes32' }]
|
|
27
|
+
}
|
|
28
28
|
],
|
|
29
|
-
functionName:
|
|
30
|
-
args: [address]
|
|
29
|
+
functionName: 'node',
|
|
30
|
+
args: [address]
|
|
31
31
|
});
|
|
32
32
|
// Query the L2Resolver for the name
|
|
33
33
|
const name = await client.readContract({
|
|
34
34
|
address: BASE_ENS_CONTRACTS.l2Resolver,
|
|
35
35
|
abi: [
|
|
36
36
|
{
|
|
37
|
-
name:
|
|
38
|
-
type:
|
|
39
|
-
stateMutability:
|
|
40
|
-
inputs: [{ name:
|
|
41
|
-
outputs: [{ name:
|
|
42
|
-
}
|
|
37
|
+
name: 'name',
|
|
38
|
+
type: 'function',
|
|
39
|
+
stateMutability: 'view',
|
|
40
|
+
inputs: [{ name: 'node', type: 'bytes32' }],
|
|
41
|
+
outputs: [{ name: '', type: 'string' }]
|
|
42
|
+
}
|
|
43
43
|
],
|
|
44
|
-
functionName:
|
|
45
|
-
args: [reverseNode]
|
|
44
|
+
functionName: 'name',
|
|
45
|
+
args: [reverseNode]
|
|
46
46
|
});
|
|
47
47
|
return name || null;
|
|
48
48
|
}
|
|
49
|
-
catch (
|
|
49
|
+
catch (_error) {
|
|
50
50
|
return null;
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
// Helper function for Base ENS forward resolution
|
|
54
54
|
async function resolveNameBase(name) {
|
|
55
55
|
const clientManager = getClientManager();
|
|
56
|
-
const client = clientManager.getClient(
|
|
56
|
+
const client = clientManager.getClient('base');
|
|
57
57
|
try {
|
|
58
58
|
const node = namehash(name);
|
|
59
59
|
// Get resolver from registry
|
|
@@ -61,17 +61,17 @@ async function resolveNameBase(name) {
|
|
|
61
61
|
address: BASE_ENS_CONTRACTS.registry,
|
|
62
62
|
abi: [
|
|
63
63
|
{
|
|
64
|
-
name:
|
|
65
|
-
type:
|
|
66
|
-
stateMutability:
|
|
67
|
-
inputs: [{ name:
|
|
68
|
-
outputs: [{ name:
|
|
69
|
-
}
|
|
64
|
+
name: 'resolver',
|
|
65
|
+
type: 'function',
|
|
66
|
+
stateMutability: 'view',
|
|
67
|
+
inputs: [{ name: 'node', type: 'bytes32' }],
|
|
68
|
+
outputs: [{ name: '', type: 'address' }]
|
|
69
|
+
}
|
|
70
70
|
],
|
|
71
|
-
functionName:
|
|
72
|
-
args: [node]
|
|
71
|
+
functionName: 'resolver',
|
|
72
|
+
args: [node]
|
|
73
73
|
});
|
|
74
|
-
if (!resolver || resolver ===
|
|
74
|
+
if (!resolver || resolver === '0x0000000000000000000000000000000000000000') {
|
|
75
75
|
return null;
|
|
76
76
|
}
|
|
77
77
|
// Get address from resolver
|
|
@@ -79,26 +79,26 @@ async function resolveNameBase(name) {
|
|
|
79
79
|
address: resolver,
|
|
80
80
|
abi: [
|
|
81
81
|
{
|
|
82
|
-
name:
|
|
83
|
-
type:
|
|
84
|
-
stateMutability:
|
|
85
|
-
inputs: [{ name:
|
|
86
|
-
outputs: [{ name:
|
|
87
|
-
}
|
|
82
|
+
name: 'addr',
|
|
83
|
+
type: 'function',
|
|
84
|
+
stateMutability: 'view',
|
|
85
|
+
inputs: [{ name: 'node', type: 'bytes32' }],
|
|
86
|
+
outputs: [{ name: '', type: 'address' }]
|
|
87
|
+
}
|
|
88
88
|
],
|
|
89
|
-
functionName:
|
|
90
|
-
args: [node]
|
|
89
|
+
functionName: 'addr',
|
|
90
|
+
args: [node]
|
|
91
91
|
});
|
|
92
92
|
return address;
|
|
93
93
|
}
|
|
94
|
-
catch (
|
|
94
|
+
catch (_error) {
|
|
95
95
|
return null;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
// Helper function for Base ENS text records
|
|
99
99
|
async function getTextRecordBase(name, key) {
|
|
100
100
|
const clientManager = getClientManager();
|
|
101
|
-
const client = clientManager.getClient(
|
|
101
|
+
const client = clientManager.getClient('base');
|
|
102
102
|
try {
|
|
103
103
|
const node = namehash(name);
|
|
104
104
|
// Get resolver from registry
|
|
@@ -106,17 +106,17 @@ async function getTextRecordBase(name, key) {
|
|
|
106
106
|
address: BASE_ENS_CONTRACTS.registry,
|
|
107
107
|
abi: [
|
|
108
108
|
{
|
|
109
|
-
name:
|
|
110
|
-
type:
|
|
111
|
-
stateMutability:
|
|
112
|
-
inputs: [{ name:
|
|
113
|
-
outputs: [{ name:
|
|
114
|
-
}
|
|
109
|
+
name: 'resolver',
|
|
110
|
+
type: 'function',
|
|
111
|
+
stateMutability: 'view',
|
|
112
|
+
inputs: [{ name: 'node', type: 'bytes32' }],
|
|
113
|
+
outputs: [{ name: '', type: 'address' }]
|
|
114
|
+
}
|
|
115
115
|
],
|
|
116
|
-
functionName:
|
|
117
|
-
args: [node]
|
|
116
|
+
functionName: 'resolver',
|
|
117
|
+
args: [node]
|
|
118
118
|
});
|
|
119
|
-
if (!resolver || resolver ===
|
|
119
|
+
if (!resolver || resolver === '0x0000000000000000000000000000000000000000') {
|
|
120
120
|
return null;
|
|
121
121
|
}
|
|
122
122
|
// Get text record from resolver
|
|
@@ -124,302 +124,244 @@ async function getTextRecordBase(name, key) {
|
|
|
124
124
|
address: resolver,
|
|
125
125
|
abi: [
|
|
126
126
|
{
|
|
127
|
-
name:
|
|
128
|
-
type:
|
|
129
|
-
stateMutability:
|
|
127
|
+
name: 'text',
|
|
128
|
+
type: 'function',
|
|
129
|
+
stateMutability: 'view',
|
|
130
130
|
inputs: [
|
|
131
|
-
{ name:
|
|
132
|
-
{ name:
|
|
131
|
+
{ name: 'node', type: 'bytes32' },
|
|
132
|
+
{ name: 'key', type: 'string' }
|
|
133
133
|
],
|
|
134
|
-
outputs: [{ name:
|
|
135
|
-
}
|
|
134
|
+
outputs: [{ name: '', type: 'string' }]
|
|
135
|
+
}
|
|
136
136
|
],
|
|
137
|
-
functionName:
|
|
138
|
-
args: [node, key]
|
|
137
|
+
functionName: 'text',
|
|
138
|
+
args: [node, key]
|
|
139
139
|
});
|
|
140
140
|
return textRecord || null;
|
|
141
141
|
}
|
|
142
|
-
catch (
|
|
142
|
+
catch (_error) {
|
|
143
143
|
return null;
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
const EnsResolveSchema = z.object({
|
|
147
147
|
chain: z
|
|
148
148
|
.enum(SUPPORTED_CHAINS)
|
|
149
|
-
.default(
|
|
150
|
-
.describe(
|
|
151
|
-
name: z
|
|
152
|
-
|
|
153
|
-
.describe("ENS name to resolve to an address (e.g., 'vitalik.eth', 'example.eth')"),
|
|
154
|
-
universalResolver: z
|
|
155
|
-
.boolean()
|
|
156
|
-
.optional()
|
|
157
|
-
.describe("Use universal resolver for cross-chain resolution (defaults to true)"),
|
|
149
|
+
.default('mainnet')
|
|
150
|
+
.describe('Blockchain network (defaults to mainnet, as ENS is primarily on Ethereum)'),
|
|
151
|
+
name: z.string().describe("ENS name to resolve to an address (e.g., 'vitalik.eth', 'example.eth')"),
|
|
152
|
+
universalResolver: z.boolean().optional().describe('Use universal resolver for cross-chain resolution (defaults to true)')
|
|
158
153
|
});
|
|
159
154
|
const EnsReverseResolveSchema = z.object({
|
|
160
|
-
chain: z
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
.describe("Blockchain network (defaults to mainnet)"),
|
|
164
|
-
address: z.string().describe("Ethereum address to resolve to an ENS name"),
|
|
165
|
-
universalResolver: z
|
|
166
|
-
.boolean()
|
|
167
|
-
.optional()
|
|
168
|
-
.describe("Use universal resolver for cross-chain resolution (defaults to true)"),
|
|
155
|
+
chain: z.enum(SUPPORTED_CHAINS).default('mainnet').describe('Blockchain network (defaults to mainnet)'),
|
|
156
|
+
address: z.string().describe('Ethereum address to resolve to an ENS name'),
|
|
157
|
+
universalResolver: z.boolean().optional().describe('Use universal resolver for cross-chain resolution (defaults to true)')
|
|
169
158
|
});
|
|
170
159
|
const EnsTextRecordSchema = z.object({
|
|
171
|
-
chain: z
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
name: z.string().describe("ENS name to query text records from"),
|
|
176
|
-
key: z
|
|
177
|
-
.string()
|
|
178
|
-
.describe("Text record key (e.g., 'avatar', 'description', 'email', 'url', 'com.twitter', 'com.github')"),
|
|
179
|
-
universalResolver: z
|
|
180
|
-
.boolean()
|
|
181
|
-
.optional()
|
|
182
|
-
.describe("Use universal resolver for cross-chain resolution (defaults to true)"),
|
|
160
|
+
chain: z.enum(SUPPORTED_CHAINS).default('mainnet').describe('Blockchain network (defaults to mainnet)'),
|
|
161
|
+
name: z.string().describe('ENS name to query text records from'),
|
|
162
|
+
key: z.string().describe("Text record key (e.g., 'avatar', 'description', 'email', 'url', 'com.twitter', 'com.github')"),
|
|
163
|
+
universalResolver: z.boolean().optional().describe('Use universal resolver for cross-chain resolution (defaults to true)')
|
|
183
164
|
});
|
|
184
165
|
const EnsBatchResolveSchema = z.object({
|
|
185
|
-
chain: z
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
.describe("Blockchain network (defaults to mainnet)"),
|
|
189
|
-
names: z
|
|
190
|
-
.array(z.string())
|
|
191
|
-
.describe("Array of ENS names to resolve to addresses in a single batch"),
|
|
192
|
-
universalResolver: z
|
|
193
|
-
.boolean()
|
|
194
|
-
.optional()
|
|
195
|
-
.describe("Use universal resolver for cross-chain resolution (defaults to true)"),
|
|
166
|
+
chain: z.enum(SUPPORTED_CHAINS).default('mainnet').describe('Blockchain network (defaults to mainnet)'),
|
|
167
|
+
names: z.array(z.string()).describe('Array of ENS names to resolve to addresses in a single batch'),
|
|
168
|
+
universalResolver: z.boolean().optional().describe('Use universal resolver for cross-chain resolution (defaults to true)')
|
|
196
169
|
});
|
|
197
170
|
export default {
|
|
198
|
-
resolve_ens_name: createTool(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
if (!address) {
|
|
217
|
-
return formatResponse({
|
|
218
|
-
success: false,
|
|
219
|
-
name: args.name,
|
|
220
|
-
normalizedName,
|
|
221
|
-
address: null,
|
|
222
|
-
chain: args.chain,
|
|
223
|
-
message: "ENS name does not resolve to an address",
|
|
224
|
-
});
|
|
225
|
-
}
|
|
171
|
+
resolve_ens_name: createTool('Resolve ENS Name to Address', 'Resolve an ENS name to its Ethereum address. ENS names are human-readable identifiers (like vitalik.eth) that resolve to Ethereum addresses.', EnsResolveSchema, async (args) => {
|
|
172
|
+
// Normalize the ENS name
|
|
173
|
+
const normalizedName = normalize(args.name);
|
|
174
|
+
let address = null;
|
|
175
|
+
// Use Base-specific logic for Base chain
|
|
176
|
+
if (args.chain === 'base') {
|
|
177
|
+
address = await resolveNameBase(normalizedName);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
// Use viem's built-in ENS resolution for other chains
|
|
181
|
+
const clientManager = getClientManager();
|
|
182
|
+
const client = clientManager.getClient(args.chain);
|
|
183
|
+
address = await client.getEnsAddress({
|
|
184
|
+
name: normalizedName,
|
|
185
|
+
universalResolverAddress: args.universalResolver !== false ? undefined : undefined
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
if (!address) {
|
|
226
189
|
return formatResponse({
|
|
227
|
-
success:
|
|
190
|
+
success: false,
|
|
228
191
|
name: args.name,
|
|
229
192
|
normalizedName,
|
|
230
|
-
address,
|
|
193
|
+
address: null,
|
|
231
194
|
chain: args.chain,
|
|
195
|
+
message: 'ENS name does not resolve to an address'
|
|
232
196
|
});
|
|
233
197
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
198
|
+
return formatResponse({
|
|
199
|
+
success: true,
|
|
200
|
+
name: args.name,
|
|
201
|
+
normalizedName,
|
|
202
|
+
address,
|
|
203
|
+
chain: args.chain
|
|
204
|
+
});
|
|
237
205
|
}),
|
|
238
|
-
reverse_resolve_ens: createTool(
|
|
206
|
+
reverse_resolve_ens: createTool('Reverse Resolve Address to ENS Name', 'Reverse resolve an Ethereum address to its primary ENS name. Returns the ENS name if the address has set a reverse record.', EnsReverseResolveSchema, async (args) => {
|
|
239
207
|
if (!isAddress(args.address)) {
|
|
240
208
|
throw new Error(`Invalid Ethereum address: ${args.address}`);
|
|
241
209
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (!ensName) {
|
|
258
|
-
return formatResponse({
|
|
259
|
-
success: false,
|
|
260
|
-
address: args.address,
|
|
261
|
-
name: null,
|
|
262
|
-
chain: args.chain,
|
|
263
|
-
message: "Address does not have a primary ENS name set",
|
|
264
|
-
});
|
|
265
|
-
}
|
|
210
|
+
let ensName = null;
|
|
211
|
+
// Use Base-specific logic for Base chain
|
|
212
|
+
if (args.chain === 'base') {
|
|
213
|
+
ensName = await reverseResolveBase(args.address);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// Use viem's built-in ENS resolution for other chains
|
|
217
|
+
const clientManager = getClientManager();
|
|
218
|
+
const client = clientManager.getClient(args.chain);
|
|
219
|
+
ensName = await client.getEnsName({
|
|
220
|
+
address: args.address,
|
|
221
|
+
universalResolverAddress: args.universalResolver !== false ? undefined : undefined
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
if (!ensName) {
|
|
266
225
|
return formatResponse({
|
|
267
|
-
success:
|
|
226
|
+
success: false,
|
|
268
227
|
address: args.address,
|
|
269
|
-
name:
|
|
228
|
+
name: null,
|
|
270
229
|
chain: args.chain,
|
|
230
|
+
message: 'Address does not have a primary ENS name set'
|
|
271
231
|
});
|
|
272
232
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
233
|
+
return formatResponse({
|
|
234
|
+
success: true,
|
|
235
|
+
address: args.address,
|
|
236
|
+
name: ensName,
|
|
237
|
+
chain: args.chain
|
|
238
|
+
});
|
|
276
239
|
}),
|
|
277
|
-
get_ens_text_record: createTool(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (!textRecord) {
|
|
297
|
-
return formatResponse({
|
|
298
|
-
success: false,
|
|
299
|
-
name: args.name,
|
|
300
|
-
normalizedName,
|
|
301
|
-
key: args.key,
|
|
302
|
-
value: null,
|
|
303
|
-
chain: args.chain,
|
|
304
|
-
message: `Text record '${args.key}' not found for ${args.name}`,
|
|
305
|
-
});
|
|
306
|
-
}
|
|
240
|
+
get_ens_text_record: createTool('Get ENS Text Record', "Retrieve a text record from an ENS name. Common keys include 'avatar', 'description', 'email', 'url', 'com.twitter', 'com.github'.", EnsTextRecordSchema, async (args) => {
|
|
241
|
+
// Normalize the ENS name
|
|
242
|
+
const normalizedName = normalize(args.name);
|
|
243
|
+
let textRecord = null;
|
|
244
|
+
// Use Base-specific logic for Base chain
|
|
245
|
+
if (args.chain === 'base') {
|
|
246
|
+
textRecord = await getTextRecordBase(normalizedName, args.key);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
// Use viem's built-in ENS resolution for other chains
|
|
250
|
+
const clientManager = getClientManager();
|
|
251
|
+
const client = clientManager.getClient(args.chain);
|
|
252
|
+
textRecord = await client.getEnsText({
|
|
253
|
+
name: normalizedName,
|
|
254
|
+
key: args.key,
|
|
255
|
+
universalResolverAddress: args.universalResolver !== false ? undefined : undefined
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (!textRecord) {
|
|
307
259
|
return formatResponse({
|
|
308
|
-
success:
|
|
260
|
+
success: false,
|
|
309
261
|
name: args.name,
|
|
310
262
|
normalizedName,
|
|
311
263
|
key: args.key,
|
|
312
|
-
value:
|
|
264
|
+
value: null,
|
|
313
265
|
chain: args.chain,
|
|
266
|
+
message: `Text record '${args.key}' not found for ${args.name}`
|
|
314
267
|
});
|
|
315
268
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
269
|
+
return formatResponse({
|
|
270
|
+
success: true,
|
|
271
|
+
name: args.name,
|
|
272
|
+
normalizedName,
|
|
273
|
+
key: args.key,
|
|
274
|
+
value: textRecord,
|
|
275
|
+
chain: args.chain
|
|
276
|
+
});
|
|
319
277
|
}),
|
|
320
|
-
get_ens_avatar: createTool(
|
|
321
|
-
chain: z
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
.describe("Blockchain network (defaults to mainnet)"),
|
|
325
|
-
name: z.string().describe("ENS name to get avatar from"),
|
|
326
|
-
universalResolver: z
|
|
327
|
-
.boolean()
|
|
328
|
-
.optional()
|
|
329
|
-
.describe("Use universal resolver for cross-chain resolution (defaults to true)"),
|
|
278
|
+
get_ens_avatar: createTool('Get ENS Avatar', 'Get the avatar URI for an ENS name. Returns the avatar URL if set.', z.object({
|
|
279
|
+
chain: z.enum(SUPPORTED_CHAINS).default('mainnet').describe('Blockchain network (defaults to mainnet)'),
|
|
280
|
+
name: z.string().describe('ENS name to get avatar from'),
|
|
281
|
+
universalResolver: z.boolean().optional().describe('Use universal resolver for cross-chain resolution (defaults to true)')
|
|
330
282
|
}), async (args) => {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
283
|
+
// Normalize the ENS name
|
|
284
|
+
const normalizedName = normalize(args.name);
|
|
285
|
+
let avatar = null;
|
|
286
|
+
// Use Base-specific logic for Base chain
|
|
287
|
+
if (args.chain === 'base') {
|
|
288
|
+
avatar = await getTextRecordBase(normalizedName, 'avatar');
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
// Use viem's built-in ENS resolution for other chains
|
|
292
|
+
const clientManager = getClientManager();
|
|
293
|
+
const client = clientManager.getClient(args.chain);
|
|
294
|
+
avatar = await client.getEnsAvatar({
|
|
295
|
+
name: normalizedName,
|
|
296
|
+
universalResolverAddress: args.universalResolver !== false ? undefined : undefined
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
if (!avatar) {
|
|
300
|
+
return formatResponse({
|
|
301
|
+
success: false,
|
|
302
|
+
name: args.name,
|
|
303
|
+
normalizedName,
|
|
304
|
+
avatar: null,
|
|
305
|
+
chain: args.chain,
|
|
306
|
+
message: `No avatar set for ${args.name}`
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
return formatResponse({
|
|
310
|
+
success: true,
|
|
311
|
+
name: args.name,
|
|
312
|
+
normalizedName,
|
|
313
|
+
avatar,
|
|
314
|
+
chain: args.chain
|
|
315
|
+
});
|
|
316
|
+
}),
|
|
317
|
+
batch_resolve_ens_names: createTool('Batch Resolve ENS Names', 'Resolve multiple ENS names to addresses in a single batch for efficiency.', EnsBatchResolveSchema, async (args) => {
|
|
318
|
+
// Resolve all ENS names in parallel
|
|
319
|
+
const results = await Promise.allSettled(args.names.map(async (name) => {
|
|
320
|
+
const normalizedName = normalize(name);
|
|
321
|
+
let address = null;
|
|
335
322
|
// Use Base-specific logic for Base chain
|
|
336
|
-
if (args.chain ===
|
|
337
|
-
|
|
323
|
+
if (args.chain === 'base') {
|
|
324
|
+
address = await resolveNameBase(normalizedName);
|
|
338
325
|
}
|
|
339
326
|
else {
|
|
340
327
|
// Use viem's built-in ENS resolution for other chains
|
|
341
328
|
const clientManager = getClientManager();
|
|
342
329
|
const client = clientManager.getClient(args.chain);
|
|
343
|
-
|
|
330
|
+
address = await client.getEnsAddress({
|
|
344
331
|
name: normalizedName,
|
|
345
|
-
universalResolverAddress: args.universalResolver !== false ? undefined : undefined
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
if (!avatar) {
|
|
349
|
-
return formatResponse({
|
|
350
|
-
success: false,
|
|
351
|
-
name: args.name,
|
|
352
|
-
normalizedName,
|
|
353
|
-
avatar: null,
|
|
354
|
-
chain: args.chain,
|
|
355
|
-
message: `No avatar set for ${args.name}`,
|
|
332
|
+
universalResolverAddress: args.universalResolver !== false ? undefined : undefined
|
|
356
333
|
});
|
|
357
334
|
}
|
|
358
|
-
return
|
|
359
|
-
|
|
360
|
-
name: args.name,
|
|
335
|
+
return {
|
|
336
|
+
name,
|
|
361
337
|
normalizedName,
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
name,
|
|
391
|
-
normalizedName,
|
|
392
|
-
address,
|
|
393
|
-
success: !!address,
|
|
394
|
-
};
|
|
395
|
-
}));
|
|
396
|
-
// Process results
|
|
397
|
-
const resolved = results.map((result, index) => {
|
|
398
|
-
if (result.status === "fulfilled") {
|
|
399
|
-
return result.value;
|
|
400
|
-
}
|
|
401
|
-
return {
|
|
402
|
-
name: args.names[index],
|
|
403
|
-
normalizedName: args.names[index],
|
|
404
|
-
address: null,
|
|
405
|
-
success: false,
|
|
406
|
-
error: result.reason instanceof Error ? result.reason.message : String(result.reason),
|
|
407
|
-
};
|
|
408
|
-
});
|
|
409
|
-
const successCount = resolved.filter((r) => r.success).length;
|
|
410
|
-
const failCount = resolved.filter((r) => !r.success).length;
|
|
411
|
-
return formatResponse({
|
|
412
|
-
success: true,
|
|
413
|
-
chain: args.chain,
|
|
414
|
-
totalNames: args.names.length,
|
|
415
|
-
successfulResolves: successCount,
|
|
416
|
-
failedResolves: failCount,
|
|
417
|
-
results: resolved,
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
catch (error) {
|
|
421
|
-
throw new Error(`Failed to batch resolve ENS names: ${error}`);
|
|
422
|
-
}
|
|
423
|
-
}),
|
|
338
|
+
address,
|
|
339
|
+
success: !!address
|
|
340
|
+
};
|
|
341
|
+
}));
|
|
342
|
+
// Process results
|
|
343
|
+
const resolved = results.map((result, index) => {
|
|
344
|
+
if (result.status === 'fulfilled') {
|
|
345
|
+
return result.value;
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
name: args.names[index],
|
|
349
|
+
normalizedName: args.names[index],
|
|
350
|
+
address: null,
|
|
351
|
+
success: false,
|
|
352
|
+
error: result.reason instanceof Error ? result.reason.message : String(result.reason)
|
|
353
|
+
};
|
|
354
|
+
});
|
|
355
|
+
const successCount = resolved.filter((r) => r.success).length;
|
|
356
|
+
const failCount = resolved.filter((r) => !r.success).length;
|
|
357
|
+
return formatResponse({
|
|
358
|
+
success: true,
|
|
359
|
+
chain: args.chain,
|
|
360
|
+
totalNames: args.names.length,
|
|
361
|
+
successfulResolves: successCount,
|
|
362
|
+
failedResolves: failCount,
|
|
363
|
+
results: resolved
|
|
364
|
+
});
|
|
365
|
+
})
|
|
424
366
|
};
|
|
425
367
|
//# sourceMappingURL=ens.js.map
|