eigen-skills 1.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/index.js ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * eigen-skills — EigenLayer data & infra skills for AI agents
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.
7
+ */
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
+ const EigenCompute = require('./skills/eigen-compute/scripts/compute-api');
14
+ const EigenDA = require('./skills/eigen-da/scripts/da-api');
15
+
16
+ module.exports = {
17
+ EigenAPI,
18
+ AVSAPI,
19
+ RewardsAPI,
20
+ DelegationAPI,
21
+ EigenCompute,
22
+ EigenDA,
23
+ };
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "eigen-skills",
3
+ "version": "1.0.0",
4
+ "description": "Agent Skills for EigenLayer — restaking, AVS, operators, rewards, delegation data powered by EigenExplorer API",
5
+ "main": "index.js",
6
+ "agents": {
7
+ "skills": "skills/"
8
+ },
9
+ "scripts": {
10
+ "test": "node scripts/test-all.js",
11
+ "demo": "node scripts/demo.js"
12
+ },
13
+ "keywords": [
14
+ "eigenlayer",
15
+ "eigen",
16
+ "restaking",
17
+ "avs",
18
+ "agent-skills",
19
+ "ai-agent",
20
+ "claude",
21
+ "openclaw",
22
+ "eigenexplorer"
23
+ ],
24
+ "author": "zeeshan8281",
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "axios": "^1.7.0"
28
+ }
29
+ }
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Demo — run all eigen-agent-skills to verify they work.
5
+ *
6
+ * Usage:
7
+ * EIGEN_API_KEY=your_key node scripts/demo.js
8
+ */
9
+
10
+ const EigenAPI = require('../skills/eigen-restaking/scripts/eigen-api');
11
+ const AVSAPI = require('../skills/eigen-avs/scripts/avs-api');
12
+ const RewardsAPI = require('../skills/eigen-rewards/scripts/rewards-api');
13
+ const DelegationAPI = require('../skills/eigen-delegation/scripts/delegation-api');
14
+
15
+ const API_KEY = process.env.EIGEN_API_KEY;
16
+
17
+ if (!API_KEY) {
18
+ console.error('āŒ Set EIGEN_API_KEY env var. Get a free key at https://developer.eigenexplorer.com');
19
+ process.exit(1);
20
+ }
21
+
22
+ async function run() {
23
+ console.log('\nšŸ”„ ═════════════════════════════════════');
24
+ console.log(' Eigen Agent Skills — Demo');
25
+ console.log('═══════════════════════════════════════\n');
26
+
27
+ const eigen = new EigenAPI(API_KEY);
28
+ const avs = new AVSAPI(API_KEY);
29
+ const rewards = new RewardsAPI(API_KEY);
30
+ const delegation = new DelegationAPI(API_KEY);
31
+
32
+ // 1. Health check
33
+ console.log('šŸ“” Health check...');
34
+ const health = await eigen.healthCheck();
35
+ console.log(` Status: ${health.ok ? 'āœ… Healthy' : 'āŒ Failed'}`);
36
+ if (health.tvl) console.log(` EigenLayer TVL: ${JSON.stringify(health.tvl)}`);
37
+ console.log('');
38
+
39
+ // 2. Ecosystem metrics
40
+ console.log('šŸ“Š Ecosystem Metrics...');
41
+ const metrics = await eigen.getMetrics();
42
+ console.log(` ${JSON.stringify(metrics, null, 2).substring(0, 500)}`);
43
+ console.log('');
44
+
45
+ // 3. Top 5 operators by TVL
46
+ console.log('šŸ‘„ Top 5 Operators by TVL...');
47
+ const ops = await eigen.getOperators({ sortByTvl: 'desc', take: 5 });
48
+ if (ops.data) {
49
+ ops.data.forEach((op, i) => {
50
+ console.log(` ${i + 1}. ${op.metadataName || op.address} — TVL: ${JSON.stringify(op.tvl?.tvl || 'N/A')} — Stakers: ${op.totalStakers}`);
51
+ });
52
+ }
53
+ console.log('');
54
+
55
+ // 4. Top 5 AVS by TVL
56
+ console.log('šŸ›”ļø Top 5 AVS by TVL...');
57
+ const avsList = await avs.getAllAVS({ sortByTvl: 'desc', take: 5 });
58
+ if (avsList.data) {
59
+ avsList.data.forEach((a, i) => {
60
+ console.log(` ${i + 1}. ${a.metadataName || a.address} — TVL: ${JSON.stringify(a.tvl?.tvl || 'N/A')}`);
61
+ });
62
+ }
63
+ console.log('');
64
+
65
+ // 5. Top 5 operators by APY
66
+ console.log('šŸ’° Top 5 Operators by APY...');
67
+ const topApy = await rewards.getTopOperatorsByAPY(5);
68
+ if (topApy.data) {
69
+ topApy.data.forEach((op, i) => {
70
+ console.log(` ${i + 1}. ${op.metadataName || op.address} — APY: ${op.maxApy || 'N/A'}`);
71
+ });
72
+ }
73
+ console.log('');
74
+
75
+ // 6. Top 5 operators by delegation
76
+ console.log('šŸ¤ Top 5 Operators by Delegation (staker count)...');
77
+ const topDel = await delegation.getTopDelegatedOperators(5);
78
+ if (topDel.data) {
79
+ topDel.data.forEach((op, i) => {
80
+ console.log(` ${i + 1}. ${op.metadataName || op.address} — Stakers: ${op.totalStakers} — AVS: ${op.totalAvs}`);
81
+ });
82
+ }
83
+ console.log('');
84
+
85
+ console.log('═══════════════════════════════════════');
86
+ console.log(' āœ… Demo complete');
87
+ console.log('═══════════════════════════════════════\n');
88
+ }
89
+
90
+ run().catch(err => {
91
+ console.error('Demo failed:', err.message);
92
+ process.exit(1);
93
+ });
@@ -0,0 +1,92 @@
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
+ ```
@@ -0,0 +1,131 @@
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 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`, {
111
+ params: { skip: opts.skip || 0, take: opts.take || 12 },
112
+ });
113
+ return data;
114
+ }
115
+
116
+ // ─── Operator-Sets per AVS ────────────────────────────
117
+
118
+ /**
119
+ * Get operator sets for a specific AVS.
120
+ * @param {string} avsAddress
121
+ * @param {object} opts
122
+ */
123
+ async getAVSOperatorSets(avsAddress, opts = {}) {
124
+ const { data } = await this.client.get(`/avs/${avsAddress}/operator-sets`, {
125
+ params: { skip: opts.skip || 0, take: opts.take || 12 },
126
+ });
127
+ return data;
128
+ }
129
+ }
130
+
131
+ module.exports = AVSAPI;
@@ -0,0 +1,198 @@
1
+ ---
2
+ name: eigen-compute
3
+ description: "Deploy and manage applications on EigenCompute TEE (Trusted Execution Environment) — deploy, monitor, attest, and manage lifecycle via ecloud CLI"
4
+ version: 1.0.0
5
+ metadata:
6
+ emoji: "šŸ”’"
7
+ tags: ["eigenlayer", "eigencompute", "tee", "tdx", "deploy", "attestation"]
8
+ user-invocable: true
9
+ ---
10
+
11
+ # EigenCompute Skill
12
+
13
+ Deploy, manage, and attest applications running inside EigenCompute TEE (Trusted Execution Environment) powered by Intel TDX.
14
+
15
+ ## What is EigenCompute?
16
+
17
+ EigenCompute runs your Docker containers inside **hardware-isolated Intel TDX TEEs**. Each deployed app gets:
18
+ - **Encrypted memory** — the host cannot read your app's data
19
+ - **Unique wallet** — cryptographic identity per deployment
20
+ - **KMS signing key** — at `/usr/local/bin/kms-signing-public-key.pem`
21
+ - **Sealed secrets** — env vars are unsealed inside the TEE at runtime
22
+ - **Cryptographic attestation** — verifiable proof of what code is running
23
+
24
+ ## Prerequisites
25
+
26
+ Install the ecloud CLI:
27
+ ```bash
28
+ npm install -g @layr-labs/ecloud-cli
29
+ ```
30
+
31
+ ## When to use this skill
32
+
33
+ Use when the user asks about:
34
+ - Deploying to EigenCompute / TEE / EigenCloud
35
+ - Checking app status, logs, or info
36
+ - TEE attestation or verification
37
+ - Managing EigenCompute apps (start, stop, terminate)
38
+ - Dockerfile setup for TEE deployment
39
+ - KMS signing or sealed secrets
40
+ - EigenCompute troubleshooting
41
+
42
+ ## How to use
43
+
44
+ ### Authentication
45
+
46
+ ```bash
47
+ # Login with existing key
48
+ ecloud auth login
49
+
50
+ # Or generate a new key
51
+ ecloud auth generate --store
52
+
53
+ # Check who you're authenticated as
54
+ ecloud auth whoami
55
+ ```
56
+
57
+ ### Create a new app from template
58
+
59
+ ```bash
60
+ ecloud compute app create --name my-app --language typescript
61
+ # Languages: typescript, python, golang, rust
62
+ ```
63
+
64
+ ### Deploy from Dockerfile (recommended)
65
+
66
+ ```bash
67
+ ecloud compute app deploy
68
+ ```
69
+ - Select **"Build and deploy from Dockerfile"** (most reliable method)
70
+ - Choose **Linux/AMD64** (standard TEE architecture)
71
+ - Estimated cost: ~0.008 ETH per deploy (Sepolia testnet)
72
+
73
+ **IMPORTANT:** "Deploy from registry" method is unreliable — apps often end up in `Status: Unknown` with no error. Always use "Build from Dockerfile".
74
+
75
+ ### Check app status
76
+
77
+ ```bash
78
+ # List all your apps
79
+ ecloud compute app list
80
+
81
+ # Get info for a specific app
82
+ ecloud compute app info <APP_ID>
83
+
84
+ # View logs (may require admin permissions)
85
+ ecloud compute app logs <APP_ID>
86
+ ```
87
+
88
+ ### Set environment variables (sealed secrets)
89
+
90
+ ```bash
91
+ ecloud compute app env set \
92
+ MY_SECRET="value" \
93
+ API_KEY="key"
94
+ ```
95
+
96
+ **Note:** You cannot inspect sealed secrets after they're set. Verify through your app's logging.
97
+
98
+ ### App lifecycle
99
+
100
+ ```bash
101
+ # Start a stopped app
102
+ ecloud compute app start <APP_ID>
103
+
104
+ # Stop a running app
105
+ ecloud compute app stop <APP_ID>
106
+
107
+ # Terminate (permanent — creates new App ID on redeploy)
108
+ ecloud compute app terminate <APP_ID>
109
+ ```
110
+
111
+ ### Upgrade (update running app)
112
+ ```bash
113
+ ecloud compute app upgrade <APP_ID>
114
+ ```
115
+
116
+ ## TEE Container Internals
117
+
118
+ Inside the TEE container, these are available:
119
+
120
+ | Path | What |
121
+ |------|------|
122
+ | `/usr/local/bin/compute-source-env.sh` | Sources sealed env vars at runtime |
123
+ | `/usr/local/bin/kms-signing-public-key.pem` | KMS signing public key |
124
+ | `/usr/local/bin/kms-client` | KMS signing client binary |
125
+
126
+ ### Entrypoint pattern for TEE
127
+
128
+ ```bash
129
+ #!/bin/bash
130
+ # Source sealed secrets
131
+ if [ -f "/usr/local/bin/compute-source-env.sh" ]; then
132
+ source /usr/local/bin/compute-source-env.sh
133
+ fi
134
+
135
+ # Start your app
136
+ node server.js
137
+ ```
138
+
139
+ ### Dockerfile pattern for TEE
140
+
141
+ ```dockerfile
142
+ FROM node:20-slim
143
+ WORKDIR /app
144
+ COPY package*.json ./
145
+ RUN npm ci --production
146
+ COPY . .
147
+ EXPOSE 3000
148
+ ENTRYPOINT ["bash", "entrypoint.sh"]
149
+ ```
150
+
151
+ ## TEE Attestation
152
+
153
+ Collect attestation data to prove your app runs in a real TEE:
154
+
155
+ ```javascript
156
+ const crypto = require('crypto');
157
+ const fs = require('fs');
158
+
159
+ function getAttestation() {
160
+ return {
161
+ appId: process.env.ECLOUD_APP_ID || null,
162
+ platform: 'Intel TDX (EigenCompute)',
163
+ kmsKeyFingerprint: getKMSFingerprint(),
164
+ nodeVersion: process.version,
165
+ uptimeSeconds: Math.floor(process.uptime()),
166
+ timestamp: new Date().toISOString(),
167
+ };
168
+ }
169
+
170
+ function getKMSFingerprint() {
171
+ try {
172
+ const pem = fs.readFileSync('/usr/local/bin/kms-signing-public-key.pem', 'utf-8');
173
+ return 'sha256:' + crypto.createHash('sha256').update(pem.trim()).digest('hex');
174
+ } catch { return null; }
175
+ }
176
+ ```
177
+
178
+ Verify at: `https://verify-sepolia.eigencloud.xyz`
179
+
180
+ ## Known Issues & Workarounds
181
+
182
+ - **429 rate limiting** — The API rate-limits aggressively after deploys. Wait 30-60s before running `app list` or `app info`.
183
+ - **Logs 403** — Even with "admin viewable" selected, `app logs` may return 403. Add logging within your app and expose it via HTTP as a workaround.
184
+ - **IP changes on every deploy** — No static IP. Don't hardcode IPs in DNS or webhooks.
185
+ - **App ID changes on terminate + redeploy** — No persistent identity across deploys.
186
+ - **Secret rotation requires full redeploy** — No way to update env vars without terminate + deploy.
187
+
188
+ ## Programmatic Usage
189
+
190
+ ```javascript
191
+ const EigenCompute = require('eigen-skills/skills/eigen-compute/scripts/compute-api');
192
+ const compute = new EigenCompute();
193
+
194
+ // These are wrappers around the ecloud CLI
195
+ const apps = await compute.listApps();
196
+ const info = await compute.getAppInfo('APP_ID');
197
+ const attestation = compute.collectAttestation();
198
+ ```