eigen-skills 2.0.3 → 2.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.
package/README.md CHANGED
@@ -1,22 +1,73 @@
1
1
  # eigen-skills
2
2
 
3
- **EigenCompute Agent Skill — Deploy and manage apps in Trusted Execution Environments (TEE) with one command**
3
+ **EigenCompute MCP Server & Agent Skill — Deploy and manage apps in Trusted Execution Environments (TEE)**
4
4
 
5
5
  ---
6
6
 
7
7
  ## What is this?
8
8
 
9
- **eigen-skills** gives AI agents (Claude Code, OpenClaw, etc.) the ability to deploy and manage apps on [EigenCompute](https://eigencloud.xyz) — hardware-isolated TEEs powered by Intel TDX with encrypted secrets and cryptographic attestation.
9
+ **eigen-skills** gives AI agents the ability to deploy and manage apps on [EigenCompute](https://eigencloud.xyz) — hardware-isolated TEEs powered by Intel TDX with encrypted secrets and cryptographic attestation.
10
+
11
+ Works with:
12
+ - **MCP Clients** — Cursor, Claude Desktop, Antigravity, Cline, etc.
13
+ - **Claude Code** — via SKILL.md standard
10
14
 
11
15
  ```bash
12
16
  npm install -g eigen-skills@latest
13
17
  ```
14
18
 
15
- > Install once, then any compatible AI agent can deploy to EigenCompute automatically via the `SKILL.md` standard.
19
+ ---
20
+
21
+ ## MCP Server Setup (Cursor, Claude Desktop, etc.)
22
+
23
+ ### 1. Install
24
+
25
+ ```bash
26
+ npm install -g eigen-skills
27
+ ```
28
+
29
+ ### 2. Configure your MCP client
30
+
31
+ **Cursor** (`~/.cursor/mcp.json`):
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "eigencompute": {
36
+ "command": "eigen-mcp"
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ **Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
43
+ ```json
44
+ {
45
+ "mcpServers": {
46
+ "eigencompute": {
47
+ "command": "eigen-mcp"
48
+ }
49
+ }
50
+ }
51
+ ```
52
+
53
+ ### 3. Available MCP Tools
54
+
55
+ | Tool | Description |
56
+ |------|-------------|
57
+ | `eigencompute_deploy` | Deploy Docker image to TEE |
58
+ | `eigencompute_list` | List all deployed apps |
59
+ | `eigencompute_info` | Get app status, IP, details |
60
+ | `eigencompute_logs` | View app logs |
61
+ | `eigencompute_start` | Start stopped app |
62
+ | `eigencompute_stop` | Stop running app |
63
+ | `eigencompute_terminate` | Destroy app permanently |
64
+ | `eigencompute_whoami` | Check CLI auth status |
65
+ | `eigencompute_env_set` | Set sealed secrets |
66
+ | `eigencompute_upgrade` | Upgrade running app |
16
67
 
17
68
  ---
18
69
 
19
- ## Setup
70
+ ## Prerequisites
20
71
 
21
72
  ```bash
22
73
  npm install -g @layr-labs/ecloud-cli@latest # minimum v0.4.3
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require('../src/mcp-server.js');
package/index.js CHANGED
@@ -1,23 +1,14 @@
1
1
  /**
2
- * eigen-skills — EigenLayer data & infra skills for AI agents
2
+ * eigen-skills — EigenCompute TEE deployment for AI agents
3
3
  *
4
- * Install: npx skills add zeeshan8281/eigen-skills
5
- * Usage: Agents discover SKILL.md files in skills/ automatically.
6
- * For programmatic use, require this module.
4
+ * MCP Server: eigen-mcp (for Cursor, Claude Desktop, etc.)
5
+ * Claude Code: Discovers SKILL.md automatically
6
+ * Programmatic: require('eigen-skills')
7
7
  */
8
8
 
9
- const EigenAPI = require('./skills/eigen-restaking/scripts/eigen-api');
10
- const AVSAPI = require('./skills/eigen-avs/scripts/avs-api');
11
- const RewardsAPI = require('./skills/eigen-rewards/scripts/rewards-api');
12
- const DelegationAPI = require('./skills/eigen-delegation/scripts/delegation-api');
13
9
  const EigenCompute = require('./skills/eigen-compute/scripts/compute-api');
14
- const EigenDA = require('./skills/eigen-da/scripts/da-api');
15
10
 
16
11
  module.exports = {
17
- EigenAPI,
18
- AVSAPI,
19
- RewardsAPI,
20
- DelegationAPI,
21
12
  EigenCompute,
22
- EigenDA,
13
+ default: EigenCompute,
23
14
  };
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "eigen-skills",
3
- "version": "2.0.3",
4
- "description": "Deploy and manage apps on EigenCompute TEE — trusted execution environments with hardware-level isolation, encrypted secrets, and attestation",
3
+ "version": "2.1.0",
4
+ "description": "Deploy and manage apps on EigenCompute TEE — trusted execution environments with hardware-level isolation, encrypted secrets, and attestation. Works as MCP server for Cursor/Claude Desktop or as Claude Code skill.",
5
5
  "main": "index.js",
6
+ "bin": {
7
+ "eigen-mcp": "./bin/eigen-mcp.js",
8
+ "eigencompute": "./bin/eigen-mcp.js"
9
+ },
6
10
  "agents": {
7
11
  "skills": "skills/"
8
12
  },
@@ -10,22 +14,26 @@
10
14
  "postinstall": "node scripts/postinstall.js",
11
15
  "test": "node scripts/test-all.js",
12
16
  "demo": "node scripts/demo.js",
13
- "ui": "node server.js"
17
+ "ui": "node server.js",
18
+ "mcp": "node src/mcp-server.js"
14
19
  },
15
20
  "keywords": [
21
+ "mcp",
22
+ "mcp-server",
23
+ "model-context-protocol",
16
24
  "eigenlayer",
17
- "eigen",
18
- "restaking",
19
- "avs",
25
+ "eigencompute",
26
+ "tee",
20
27
  "agent-skills",
21
28
  "ai-agent",
22
29
  "claude",
23
- "openclaw",
24
- "eigenexplorer"
30
+ "cursor",
31
+ "antigravity"
25
32
  ],
26
33
  "author": "zeeshan8281",
27
34
  "license": "MIT",
28
35
  "dependencies": {
36
+ "@modelcontextprotocol/sdk": "^1.29.0",
29
37
  "axios": "^1.7.0",
30
38
  "dotenv": "^17.3.1",
31
39
  "express": "^5.2.1",
@@ -0,0 +1,321 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
4
+ const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
5
+ const { CallToolRequestSchema, ListToolsRequestSchema } = require('@modelcontextprotocol/sdk/types.js');
6
+ const { execSync, exec } = require('child_process');
7
+
8
+ const INSTANCE_TYPES = [
9
+ 'g1-micro-1v',
10
+ 'g1-medium-1v',
11
+ 'g1-custom-2-4096s',
12
+ 'g1-standard-2s',
13
+ 'g1-standard-4t',
14
+ 'g1-standard-8t'
15
+ ];
16
+
17
+ function checkCLI() {
18
+ try {
19
+ execSync('ecloud --version', { stdio: 'pipe' });
20
+ return true;
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+
26
+ function runCommand(cmd, timeout = 60000) {
27
+ return new Promise((resolve, reject) => {
28
+ exec(`ecloud ${cmd}`, { encoding: 'utf-8', timeout }, (error, stdout, stderr) => {
29
+ if (error) {
30
+ reject(new Error(stderr || error.message));
31
+ } else {
32
+ resolve(stdout.trim());
33
+ }
34
+ });
35
+ });
36
+ }
37
+
38
+ async function runDeploy(args) {
39
+ const { name, image, instanceType = 'g1-standard-4t', envFile } = args;
40
+
41
+ let cmd = `compute app deploy --name "${name}" --image-ref "${image}" --skip-profile --instance-type ${instanceType} --log-visibility public --resource-usage-monitoring enable --verbose`;
42
+
43
+ if (envFile) {
44
+ cmd += ` --env-file "${envFile}"`;
45
+ }
46
+
47
+ return new Promise((resolve, reject) => {
48
+ exec(`echo "n" | ecloud ${cmd}`, { encoding: 'utf-8', timeout: 300000 }, (error, stdout, stderr) => {
49
+ if (error) {
50
+ reject(new Error(stderr || error.message));
51
+ } else {
52
+ resolve(stdout.trim());
53
+ }
54
+ });
55
+ });
56
+ }
57
+
58
+ const TOOLS = [
59
+ {
60
+ name: 'eigencompute_whoami',
61
+ description: 'Check which address the ecloud CLI is authenticated as',
62
+ inputSchema: {
63
+ type: 'object',
64
+ properties: {},
65
+ required: []
66
+ }
67
+ },
68
+ {
69
+ name: 'eigencompute_list',
70
+ description: 'List all deployed EigenCompute apps',
71
+ inputSchema: {
72
+ type: 'object',
73
+ properties: {},
74
+ required: []
75
+ }
76
+ },
77
+ {
78
+ name: 'eigencompute_info',
79
+ description: 'Get detailed info for a specific app including status and IP',
80
+ inputSchema: {
81
+ type: 'object',
82
+ properties: {
83
+ appId: {
84
+ type: 'string',
85
+ description: 'The app ID to get info for'
86
+ }
87
+ },
88
+ required: ['appId']
89
+ }
90
+ },
91
+ {
92
+ name: 'eigencompute_logs',
93
+ description: 'View logs for a specific app',
94
+ inputSchema: {
95
+ type: 'object',
96
+ properties: {
97
+ appId: {
98
+ type: 'string',
99
+ description: 'The app ID to get logs for'
100
+ }
101
+ },
102
+ required: ['appId']
103
+ }
104
+ },
105
+ {
106
+ name: 'eigencompute_start',
107
+ description: 'Start a stopped app',
108
+ inputSchema: {
109
+ type: 'object',
110
+ properties: {
111
+ appId: {
112
+ type: 'string',
113
+ description: 'The app ID to start'
114
+ }
115
+ },
116
+ required: ['appId']
117
+ }
118
+ },
119
+ {
120
+ name: 'eigencompute_stop',
121
+ description: 'Stop a running app',
122
+ inputSchema: {
123
+ type: 'object',
124
+ properties: {
125
+ appId: {
126
+ type: 'string',
127
+ description: 'The app ID to stop'
128
+ }
129
+ },
130
+ required: ['appId']
131
+ }
132
+ },
133
+ {
134
+ name: 'eigencompute_terminate',
135
+ description: 'Permanently terminate and destroy an app. This cannot be undone.',
136
+ inputSchema: {
137
+ type: 'object',
138
+ properties: {
139
+ appId: {
140
+ type: 'string',
141
+ description: 'The app ID to terminate'
142
+ }
143
+ },
144
+ required: ['appId']
145
+ }
146
+ },
147
+ {
148
+ name: 'eigencompute_deploy',
149
+ description: 'Deploy a Docker image to EigenCompute TEE. Image must be linux/amd64 and pushed to a public registry.',
150
+ inputSchema: {
151
+ type: 'object',
152
+ properties: {
153
+ name: {
154
+ type: 'string',
155
+ description: 'App name for the deployment'
156
+ },
157
+ image: {
158
+ type: 'string',
159
+ description: 'Docker image reference (e.g., user/app:latest)'
160
+ },
161
+ instanceType: {
162
+ type: 'string',
163
+ description: 'Instance type. Recommended: g1-standard-4t',
164
+ enum: INSTANCE_TYPES,
165
+ default: 'g1-standard-4t'
166
+ },
167
+ envFile: {
168
+ type: 'string',
169
+ description: 'Path to .env file for sealed secrets (optional)'
170
+ }
171
+ },
172
+ required: ['name', 'image']
173
+ }
174
+ },
175
+ {
176
+ name: 'eigencompute_env_set',
177
+ description: 'Set sealed environment variables for an app. Secrets are encrypted and only decryptable inside the TEE.',
178
+ inputSchema: {
179
+ type: 'object',
180
+ properties: {
181
+ appId: {
182
+ type: 'string',
183
+ description: 'The app ID to set env vars for'
184
+ },
185
+ secrets: {
186
+ type: 'object',
187
+ description: 'Key-value pairs of secrets to set',
188
+ additionalProperties: { type: 'string' }
189
+ }
190
+ },
191
+ required: ['appId', 'secrets']
192
+ }
193
+ },
194
+ {
195
+ name: 'eigencompute_upgrade',
196
+ description: 'Upgrade a running app to a new image version',
197
+ inputSchema: {
198
+ type: 'object',
199
+ properties: {
200
+ appId: {
201
+ type: 'string',
202
+ description: 'The app ID to upgrade'
203
+ }
204
+ },
205
+ required: ['appId']
206
+ }
207
+ }
208
+ ];
209
+
210
+ async function handleToolCall(name, args) {
211
+ if (!checkCLI()) {
212
+ return {
213
+ content: [{
214
+ type: 'text',
215
+ text: 'Error: ecloud CLI not installed. Run: npm install -g @layr-labs/ecloud-cli@latest'
216
+ }],
217
+ isError: true
218
+ };
219
+ }
220
+
221
+ try {
222
+ let result;
223
+
224
+ switch (name) {
225
+ case 'eigencompute_whoami':
226
+ result = await runCommand('auth whoami');
227
+ break;
228
+
229
+ case 'eigencompute_list':
230
+ result = await runCommand('compute app list');
231
+ break;
232
+
233
+ case 'eigencompute_info':
234
+ result = await runCommand(`compute app info ${args.appId}`);
235
+ break;
236
+
237
+ case 'eigencompute_logs':
238
+ result = await runCommand(`compute app logs ${args.appId}`, 120000);
239
+ break;
240
+
241
+ case 'eigencompute_start':
242
+ result = await runCommand(`compute app start ${args.appId}`);
243
+ break;
244
+
245
+ case 'eigencompute_stop':
246
+ result = await runCommand(`compute app stop ${args.appId}`);
247
+ break;
248
+
249
+ case 'eigencompute_terminate':
250
+ result = await new Promise((resolve, reject) => {
251
+ exec(`echo "y" | ecloud compute app terminate ${args.appId}`,
252
+ { encoding: 'utf-8', timeout: 60000 },
253
+ (error, stdout, stderr) => {
254
+ if (error) reject(new Error(stderr || error.message));
255
+ else resolve(stdout.trim());
256
+ });
257
+ });
258
+ break;
259
+
260
+ case 'eigencompute_deploy':
261
+ result = await runDeploy(args);
262
+ break;
263
+
264
+ case 'eigencompute_env_set':
265
+ const secretPairs = Object.entries(args.secrets)
266
+ .map(([k, v]) => `${k}="${v}"`)
267
+ .join(' ');
268
+ result = await runCommand(`compute app env set ${secretPairs}`, 120000);
269
+ break;
270
+
271
+ case 'eigencompute_upgrade':
272
+ result = await runCommand(`compute app upgrade ${args.appId}`, 300000);
273
+ break;
274
+
275
+ default:
276
+ return {
277
+ content: [{ type: 'text', text: `Unknown tool: ${name}` }],
278
+ isError: true
279
+ };
280
+ }
281
+
282
+ return {
283
+ content: [{ type: 'text', text: result || 'Command completed successfully' }]
284
+ };
285
+
286
+ } catch (error) {
287
+ return {
288
+ content: [{ type: 'text', text: `Error: ${error.message}` }],
289
+ isError: true
290
+ };
291
+ }
292
+ }
293
+
294
+ async function main() {
295
+ const server = new Server(
296
+ {
297
+ name: 'eigencompute',
298
+ version: '2.1.0'
299
+ },
300
+ {
301
+ capabilities: {
302
+ tools: {}
303
+ }
304
+ }
305
+ );
306
+
307
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
308
+ return { tools: TOOLS };
309
+ });
310
+
311
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
312
+ const { name, arguments: args } = request.params;
313
+ return handleToolCall(name, args || {});
314
+ });
315
+
316
+ const transport = new StdioServerTransport();
317
+ await server.connect(transport);
318
+ console.error('EigenCompute MCP server running on stdio');
319
+ }
320
+
321
+ main().catch(console.error);
@@ -1,92 +0,0 @@
1
- ---
2
- name: eigen-avs
3
- description: "Query EigenLayer AVS (Actively Validated Services) — list services, operators per AVS, stakers per AVS, registration events, and operator-sets"
4
- version: 1.0.0
5
- metadata:
6
- emoji: "🛡️"
7
- tags: ["eigenlayer", "avs", "services", "operators", "security"]
8
- user-invocable: true
9
- ---
10
-
11
- # EigenLayer AVS Skill
12
-
13
- Query live data about Actively Validated Services (AVS) on EigenLayer: service listings, operators securing each AVS, staker delegations, registration events, and operator-sets.
14
-
15
- ## Data Source
16
-
17
- **EigenExplorer API** — `https://api.eigenexplorer.com`
18
- - Auth: `x-api-token` header (free key at https://developer.eigenexplorer.com)
19
-
20
- ## When to use this skill
21
-
22
- Use when the user asks about:
23
- - AVS (Actively Validated Services) on EigenLayer
24
- - Which operators are securing a specific AVS
25
- - Stakers delegated to a specific AVS
26
- - AVS registration/deregistration events
27
- - Operator-sets for an AVS
28
- - Comparing AVS by TVL, staker count, or APY
29
-
30
- ## How to query
31
-
32
- ### Get all AVS (sorted by TVL)
33
- ```bash
34
- curl -s "https://api.eigenexplorer.com/avs?withTvl=true&sortByTvl=desc&take=10" -H "x-api-token: $EIGEN_API_KEY"
35
- ```
36
-
37
- ### Search AVS by name
38
- ```bash
39
- curl -s "https://api.eigenexplorer.com/avs?searchByText=eigenda&withTvl=true" -H "x-api-token: $EIGEN_API_KEY"
40
- ```
41
-
42
- ### Get a specific AVS
43
- ```bash
44
- curl -s "https://api.eigenexplorer.com/avs/0xAVS_ADDRESS?withTvl=true" -H "x-api-token: $EIGEN_API_KEY"
45
- ```
46
-
47
- ### Get operators registered to an AVS
48
- ```bash
49
- curl -s "https://api.eigenexplorer.com/avs/0xAVS_ADDRESS/operators?take=20" -H "x-api-token: $EIGEN_API_KEY"
50
- ```
51
-
52
- ### Get stakers for an AVS
53
- ```bash
54
- curl -s "https://api.eigenexplorer.com/avs/0xAVS_ADDRESS/stakers?take=20" -H "x-api-token: $EIGEN_API_KEY"
55
- ```
56
-
57
- ### Get registration events for an AVS
58
- ```bash
59
- curl -s "https://api.eigenexplorer.com/avs/0xAVS_ADDRESS/events/registration?take=20" -H "x-api-token: $EIGEN_API_KEY"
60
- ```
61
-
62
- ### Get operator-sets for an AVS
63
- ```bash
64
- curl -s "https://api.eigenexplorer.com/avs/0xAVS_ADDRESS/operator-sets?take=20" -H "x-api-token: $EIGEN_API_KEY"
65
- ```
66
-
67
- ### Get all AVS addresses (lightweight)
68
- ```bash
69
- curl -s "https://api.eigenexplorer.com/avs/addresses" -H "x-api-token: $EIGEN_API_KEY"
70
- ```
71
-
72
- ## Response Format
73
-
74
- Format results for the user with:
75
- - **Bold AVS names** and abbreviated addresses
76
- - TVL in human-readable form (e.g., "$500M")
77
- - Number of operators securing the AVS
78
- - Number of stakers
79
- - APY if available
80
- - Active/inactive status for operator registrations
81
- - Use bullet points, never tables in chat
82
-
83
- ## Programmatic Usage
84
-
85
- ```javascript
86
- const AVSAPI = require('eigen-agent-skills/skills/eigen-avs/scripts/avs-api');
87
- const api = new AVSAPI('YOUR_API_KEY');
88
-
89
- const allAVS = await api.getAllAVS({ sortByTvl: 'desc', take: 10 });
90
- const operators = await api.getAVSOperators('0xAVS_ADDRESS');
91
- const stakers = await api.getAVSStakers('0xAVS_ADDRESS');
92
- ```
@@ -1,117 +0,0 @@
1
- /**
2
- * EigenLayer AVS (Actively Validated Services) API Client
3
- *
4
- * Data source: EigenExplorer REST API
5
- * Covers: AVS listing, detail, operators per AVS, stakers per AVS, registration events
6
- */
7
-
8
- const axios = require('axios');
9
-
10
- const MAINNET = 'https://api.eigenexplorer.com';
11
- const HOLESKY = 'https://api-holesky.eigenexplorer.com';
12
-
13
- class AVSAPI {
14
- constructor(apiKey, { network = 'mainnet' } = {}) {
15
- if (!apiKey) throw new Error('EigenExplorer API key required. Get one free at https://developer.eigenexplorer.com');
16
- this.client = axios.create({
17
- baseURL: network === 'holesky' ? HOLESKY : MAINNET,
18
- headers: {
19
- 'x-api-token': apiKey,
20
- 'Content-Type': 'application/json',
21
- },
22
- timeout: 30000,
23
- });
24
- }
25
-
26
- // ─── AVS Listing ──────────────────────────────────────
27
-
28
- /**
29
- * Get all AVS with optional filtering and sorting.
30
- * @param {object} opts
31
- * @param {boolean} [opts.withTvl=true]
32
- * @param {string} [opts.searchByText] - search AVS by name
33
- * @param {'asc'|'desc'} [opts.sortByTvl]
34
- * @param {'asc'|'desc'} [opts.sortByApy]
35
- * @param {'asc'|'desc'} [opts.sortByTotalStakers]
36
- * @param {number} [opts.skip=0]
37
- * @param {number} [opts.take=12]
38
- */
39
- async getAllAVS(opts = {}) {
40
- const params = {
41
- withTvl: opts.withTvl !== false ? 'true' : 'false',
42
- skip: opts.skip || 0,
43
- take: opts.take || 12,
44
- };
45
- if (opts.searchByText) params.searchByText = opts.searchByText;
46
- if (opts.sortByTvl) params.sortByTvl = opts.sortByTvl;
47
- if (opts.sortByApy) params.sortByApy = opts.sortByApy;
48
- if (opts.sortByTotalStakers) params.sortByTotalStakers = opts.sortByTotalStakers;
49
-
50
- const { data } = await this.client.get('/avs', { params });
51
- return data;
52
- }
53
-
54
- /**
55
- * Get AVS addresses only (lightweight).
56
- */
57
- async getAVSAddresses() {
58
- const { data } = await this.client.get('/avs/addresses');
59
- return data;
60
- }
61
-
62
- /**
63
- * Get detailed info for a single AVS.
64
- * @param {string} address - AVS contract address
65
- * @param {boolean} [withTvl=true]
66
- */
67
- async getAVS(address, withTvl = true) {
68
- const { data } = await this.client.get(`/avs/${address}`, {
69
- params: { withTvl: withTvl ? 'true' : 'false' },
70
- });
71
- return data;
72
- }
73
-
74
- // ─── AVS ↔ Operators ─────────────────────────────────
75
-
76
- /**
77
- * Get operators registered to a specific AVS.
78
- * @param {string} avsAddress
79
- * @param {object} opts
80
- */
81
- async getAVSOperators(avsAddress, opts = {}) {
82
- const { data } = await this.client.get(`/avs/${avsAddress}/operators`, {
83
- params: { skip: opts.skip || 0, take: opts.take || 12 },
84
- });
85
- return data;
86
- }
87
-
88
- // ─── AVS ↔ Stakers ───────────────────────────────────
89
-
90
- /**
91
- * Get stakers delegated to a specific AVS.
92
- * @param {string} avsAddress
93
- * @param {object} opts
94
- */
95
- async getAVSStakers(avsAddress, opts = {}) {
96
- const { data } = await this.client.get(`/avs/${avsAddress}/stakers`, {
97
- params: { skip: opts.skip || 0, take: opts.take || 12 },
98
- });
99
- return data;
100
- }
101
-
102
- // ─── AVS Registration Events ──────────────────────────
103
-
104
- /**
105
- * Get registration/deregistration events for a specific AVS.
106
- * @param {string} avsAddress
107
- * @param {object} opts
108
- */
109
- async getAVSRegistrationEvents(avsAddress, opts = {}) {
110
- const { data } = await this.client.get(`/avs/${avsAddress}/events/registration-status`, {
111
- params: { skip: opts.skip || 0, take: opts.take || 12 },
112
- });
113
- return data;
114
- }
115
- }
116
-
117
- module.exports = AVSAPI;