trustrouter 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 TrustRouter Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # TrustRouter
2
+
3
+ **ERC-8004 Reputation-Aware Service Router**
4
+
5
+ Discover, rank, and route to the best services on-chain — agents, MCP tools, oracles, APIs, DeFi bots, and anything registered on [ERC-8004](https://eips.ethereum.org/EIPS/eip-8004). TrustRouter queries the Identity and Reputation registries using free public RPCs to find the highest-trust provider for any given task.
6
+
7
+ > *"Reputation-aware routing: Middleware that ingests ERC-8004 reputation data and dynamically routes requests to the best-performing service for a given task at a given moment."*
8
+ > — [Vitto Rivabella](https://x.com/VittoStack), ERC-8004 co-creator
9
+
10
+ ## What It Does
11
+
12
+ - **Discovers** all registered services from the ERC-8004 Identity Registry — agents, MCP servers, oracles, APIs, and more
13
+ - **Scores** them using on-chain reputation feedback from the Reputation Registry
14
+ - **Ranks** by a composite trust score (reputation + activity)
15
+ - **Filters** by service type (A2A, MCP, OASF, x402) and keyword matching
16
+ - **Routes** you to the best available provider for your task
17
+
18
+ Works as a **CLI tool** for humans and an **OpenClaw skill** for agents. Zero config, no API keys needed.
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ # Run directly with npx (no install needed)
24
+ npx trustrouter@latest list
25
+
26
+ # Or install globally
27
+ npm install -g trustrouter
28
+ ```
29
+
30
+ TrustRouter works out of the box using free public RPCs — zero API keys required.
31
+
32
+ ```bash
33
+ # Find the best service for a task
34
+ trustrouter find --task "price feed oracle" --chain base
35
+
36
+ # List all services ranked by reputation
37
+ trustrouter list --chain ethereum --sort reputation
38
+
39
+ # Inspect a specific service (by ID or name)
40
+ trustrouter inspect 42 --chain arbitrum
41
+ trustrouter inspect "PriceFeedOracle" --chain base
42
+ ```
43
+
44
+ ## Commands
45
+
46
+ | Command | Description |
47
+ |---------|-------------|
48
+ | `trustrouter find --task "..." [--type mcp\|a2a] [--chain ethereum]` | Find best service for a task |
49
+ | `trustrouter list [--chain ethereum] [--sort reputation] [--limit 20]` | List all registered services |
50
+ | `trustrouter inspect <id-or-name> [--chain ethereum]` | Full details of a service (by ID or name) |
51
+
52
+ **Local Caching:**
53
+ All RPC responses are automatically cached locally in `~/.trustrouter/cache.json` for 1 hour. This significantly speeds up subsequent commands (e.g. from 50s down to 0.7s) and prevents rate-limiting when using free public RPCs.
54
+
55
+ All commands support the global `-o json` flag for machine-readable output:
56
+
57
+ ```bash
58
+ # JSON output (for scripts and agents)
59
+ trustrouter -o json list --limit 5
60
+ trustrouter -o json find --task "oracle" --chain base
61
+ trustrouter -o json inspect 42
62
+
63
+ # Pipe to jq
64
+ trustrouter -o json list --limit 100 | jq '.[].name'
65
+ ```
66
+
67
+ Errors follow the same pattern — table mode prints `Error: ...` to stderr, JSON mode prints `{"error": "..."}` to stdout with a non-zero exit code.
68
+
69
+ ## Supported Chains
70
+
71
+ Supports all EVM chains where the ERC-8004 registries are deployed (via CREATE2):
72
+
73
+ - **Mainnets**: Ethereum, Base, Arbitrum, Polygon, Avalanche, BNB, Gnosis, Linea, Celo
74
+ - **Testnets**: Sepolia, Base Sepolia
75
+
76
+ Specify the chain using the `-c` or `--chain` flag (e.g., `--chain base`).
77
+
78
+ ## Trust Score Algorithm
79
+
80
+ ```
81
+ trustScore = (0.6 × avg_reputation) + (0.4 × log(feedback_count))
82
+ ```
83
+
84
+ - **Reputation** — Average on-chain feedback score from the Reputation Registry `getSummary()`
85
+ - **Activity** — Log-scale bonus based on the total number of feedback events
86
+
87
+ ## What Can Be Discovered
88
+
89
+ ERC-8004 is not just for agents — it's a universal service registry. TrustRouter discovers anything registered:
90
+
91
+ | Type | Example |
92
+ |------|---------|
93
+ | AI Agents | A2A-compatible autonomous agents |
94
+ | MCP Servers | Tool providers, code sandboxes, database connectors |
95
+ | Oracles | Price feeds, data providers, block time trackers |
96
+ | DeFi Services | Liquidation bots, keeper networks, MEV searchers |
97
+ | APIs | Any HTTP service with an endpoint |
98
+
99
+ ## Agent Integration
100
+
101
+ TrustRouter ships with a [SKILL.md](./SKILL.md) for OpenClaw agents. After installing, any agent can discover and route to ERC-8004 services autonomously:
102
+
103
+ ```
104
+ "Find me the best MCP tool for price feeds on Ethereum"
105
+ → trustrouter find --task "price feed" --type mcp --chain ethereum --json
106
+ ```
107
+
108
+ ## Architecture
109
+
110
+ ```
111
+ ┌─────────────┐ ┌──────────────────┐
112
+ │ CLI / Agent │ ──▸ │ Router (Scorer │
113
+ │ Commands │ │ + Matcher) │
114
+ └──────┬──────┘ └────────┬─────────┘
115
+ │ │
116
+ ▼ ▼
117
+ ┌──────────────────────────────────────┐
118
+ │ Registry Layer (Free Public RPCs) │
119
+ │ Parallel Batched Contract Queries │
120
+ └──────────────────┬───────────────────┘
121
+
122
+ ┌────────▾─────────┐
123
+ │ ERC-8004 │
124
+ │ Identity + │
125
+ │ Reputation │
126
+ │ Registries │
127
+ └──────────────────┘
128
+ ```
129
+
130
+ ## Advanced Usage (Custom RPCs)
131
+
132
+ TrustRouter works out of the box, but for heavy usage you can set custom RPC endpoints:
133
+
134
+ ```bash
135
+ export ETH_RPC_URL="https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
136
+ export BASE_RPC_URL="https://mainnet.base.org"
137
+ ```
138
+
139
+ ## Development
140
+
141
+ ```bash
142
+ git clone https://github.com/nice-bills/trustrouter
143
+ cd trustrouter
144
+ npm install
145
+ npm run build
146
+ node dist/cli.js list --chain ethereum
147
+ ```
148
+
149
+ ## License
150
+
151
+ MIT
package/SKILL.md ADDED
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: trustrouter
3
+ description: Find the best ERC-8004 registered services — agents, MCP tools, oracles, APIs — by on-chain reputation. Routes to the highest-trust provider for any given task across 11 supported chains.
4
+ ---
5
+
6
+ # TrustRouter — ERC-8004 Service & Agent Discovery
7
+
8
+ Use this skill when you need to discover, evaluate, or route to any ERC-8004 registered service. TrustRouter queries on-chain Identity and Reputation registries via free public RPCs to find and rank the best available provider for a given task.
9
+
10
+ ## When to Use
11
+
12
+ - You need to find a service, tool, or agent to delegate a task to
13
+ - You want to evaluate the trustworthiness of a specific service using on-chain feedback
14
+ - You need to discover available MCP servers, A2A agents, oracles, or x402-compatible services
15
+ - You want to find services on specific chains like Ethereum, Base, Arbitrum, Polygon, etc.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npx trustrouter --help # Run without installing
21
+ npm install -g trustrouter # Or install globally
22
+ ```
23
+
24
+ TrustRouter is **zero-config**. It uses free public RPCs out of the box — no API keys needed.
25
+
26
+ ## Commands
27
+
28
+ ### Find the best service for a task
29
+
30
+ ```bash
31
+ trustrouter -o json find --task "audit solidity contracts" --chain ethereum
32
+ ```
33
+
34
+ Use `--type` to filter by service type: `a2a`, `mcp`, `web`, `oasf`, `x402`
35
+
36
+ ```bash
37
+ trustrouter -o json find --task "price feed oracle" --type mcp --chain base
38
+ ```
39
+
40
+ ### List all registered services
41
+
42
+ ```bash
43
+ trustrouter -o json list --chain arbitrum --sort reputation --limit 10
44
+ ```
45
+
46
+ ### Inspect a specific service (by ID or name)
47
+
48
+ ```bash
49
+ trustrouter -o json inspect 42 --chain polygon
50
+ trustrouter -o json inspect "ClawNews" --chain arbitrum
51
+ ```
52
+
53
+ ### Force fresh data (bypass cache)
54
+
55
+ ```bash
56
+ trustrouter --refresh -o json list --chain ethereum --limit 5
57
+ ```
58
+
59
+ ## Output Format
60
+
61
+ Always use `-o json` when calling from an agent context. The JSON output includes:
62
+
63
+ ```json
64
+ [
65
+ {
66
+ "agentId": 0,
67
+ "name": "ClawNews",
68
+ "trustScore": 85.5,
69
+ "feedbackCount": 156,
70
+ "services": [
71
+ { "name": "web", "endpoint": "https://clawnews.io" },
72
+ { "name": "OASF", "endpoint": "https://github.com/agntcy/oasf/", "version": "0.8.0" },
73
+ { "name": "agentWallet", "endpoint": "eip155:42161:0x89E..." },
74
+ { "name": "email", "endpoint": "hello@clawnews.io" }
75
+ ],
76
+ "x402Support": false
77
+ }
78
+ ]
79
+ ```
80
+
81
+ Errors in JSON mode return `{"error": "..."}` with a non-zero exit code.
82
+
83
+ ## Global Options
84
+
85
+ | Flag | Description |
86
+ |------|-------------|
87
+ | `-o json` / `-o table` | Output format (default: `table`) |
88
+ | `--refresh` | Bypass cache and fetch fresh data from chain |
89
+ | `-c, --chain <name>` | Target chain (default: `ethereum`) |
90
+
91
+ ## Supported Chains
92
+
93
+ Ethereum, Base, Arbitrum, Polygon, Avalanche, BNB, Gnosis, Linea, Celo, Sepolia, Base-Sepolia
94
+
95
+ ## Trust Score
96
+
97
+ Services are scored using on-chain data from the ERC-8004 Reputation Registry:
98
+ - **60%** Reputation (average feedback score, 0-100)
99
+ - **40%** Activity (log-scale bonus based on total feedback count)
100
+
101
+ Higher trust score = more reliable provider with a proven on-chain track record.
102
+
103
+ ## Caching
104
+
105
+ Results are cached locally in `~/.trustrouter/cache.json` for 1 hour. Use `--refresh` to bypass.
@@ -0,0 +1,19 @@
1
+ import { AgentData } from "./registry.js";
2
+ /** Call this to bypass cache reads for the current run */
3
+ export declare function setRefresh(enabled: boolean): void;
4
+ export interface CacheStore {
5
+ [chain: string]: {
6
+ timestamp: number;
7
+ totalAgents: number;
8
+ agents: Record<number, AgentData>;
9
+ };
10
+ }
11
+ export declare function loadCache(): CacheStore;
12
+ export declare function saveCache(cache: CacheStore): void;
13
+ /** Returns cached data for a chain, or null if expired/missing/refresh forced */
14
+ export declare function getCachedChain(chain: string): {
15
+ timestamp: number;
16
+ totalAgents: number;
17
+ agents: Record<number, AgentData>;
18
+ } | null;
19
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAW1C,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,QAE1C;AAED,MAAM,WAAW,UAAU;IACvB,CAAC,KAAK,EAAE,MAAM,GAAG;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;KACrC,CAAA;CACJ;AAED,wBAAgB,SAAS,IAAI,UAAU,CAQtC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,QAS1C;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM;eA5BzB,MAAM;iBACJ,MAAM;YACX,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;SAkCxC"}
package/dist/cache.js ADDED
@@ -0,0 +1,45 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import os from "os";
4
+ const CACHE_DIR = path.join(os.homedir(), ".trustrouter");
5
+ const CACHE_FILE = path.join(CACHE_DIR, "cache.json");
6
+ const TTL_MS = 60 * 60 * 1000; // 1 hour
7
+ let forceRefresh = false;
8
+ /** Call this to bypass cache reads for the current run */
9
+ export function setRefresh(enabled) {
10
+ forceRefresh = enabled;
11
+ }
12
+ export function loadCache() {
13
+ try {
14
+ if (!fs.existsSync(CACHE_FILE))
15
+ return {};
16
+ const data = fs.readFileSync(CACHE_FILE, "utf-8");
17
+ return JSON.parse(data);
18
+ }
19
+ catch {
20
+ return {};
21
+ }
22
+ }
23
+ export function saveCache(cache) {
24
+ try {
25
+ if (!fs.existsSync(CACHE_DIR)) {
26
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
27
+ }
28
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
29
+ }
30
+ catch {
31
+ // Silently ignore — cache is best-effort
32
+ }
33
+ }
34
+ /** Returns cached data for a chain, or null if expired/missing/refresh forced */
35
+ export function getCachedChain(chain) {
36
+ if (forceRefresh)
37
+ return null;
38
+ const cache = loadCache();
39
+ const data = cache[chain];
40
+ if (data && Date.now() - data.timestamp < TTL_MS) {
41
+ return data;
42
+ }
43
+ return null;
44
+ }
45
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AACtD,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;AAExC,IAAI,YAAY,GAAG,KAAK,CAAC;AAEzB,0DAA0D;AAC1D,MAAM,UAAU,UAAU,CAAC,OAAgB;IACvC,YAAY,GAAG,OAAO,CAAC;AAC3B,CAAC;AAUD,MAAM,UAAU,SAAS;IACrB,IAAI,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAiB;IACvC,IAAI,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACL,yCAAyC;IAC7C,CAAC;AACL,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,KAAa;IACxC,IAAI,YAAY;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,GAAG,MAAM,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import chalk from "chalk";
4
+ import { findCommand } from "./commands/find.js";
5
+ import { listCommand } from "./commands/list.js";
6
+ import { inspectCommand } from "./commands/inspect.js";
7
+ import { getSupportedChains } from "./registry.js";
8
+ import dotenv from "dotenv";
9
+ dotenv.config();
10
+ const chains = getSupportedChains().join(", ");
11
+ const program = new Command();
12
+ program
13
+ .name("trustrouter")
14
+ .description(chalk.bold("ERC-8004 Reputation-Aware Service Router") +
15
+ "\n Discover, rank, and route to the best services & agents on-chain." +
16
+ "\n Zero config — works out of the box with free public RPCs." +
17
+ "\n Results are cached locally for 1 hour (~/.trustrouter/cache.json)." +
18
+ chalk.dim(`\n\n Supported chains: ${chains}`))
19
+ .version("0.1.0")
20
+ .option("-o, --output <format>", "Output format: table or json", "table")
21
+ .option("--refresh", "Bypass cache and fetch fresh data from chain");
22
+ // trustrouter find --task "audit solidity" --type mcp --chain base
23
+ program
24
+ .command("find")
25
+ .description("Find the best service or agent for a given task")
26
+ .requiredOption("-t, --task <description>", "Task description to match against")
27
+ .option("--type <type>", "Filter by service type (a2a, mcp, web, oasf, x402)")
28
+ .option("-c, --chain <chain>", "Target chain", "ethereum")
29
+ .option("-n, --limit <number>", "Max results to return", "5")
30
+ .action((opts) => {
31
+ const { output, refresh } = program.opts();
32
+ findCommand({ ...opts, output, refresh });
33
+ });
34
+ // trustrouter list --chain base --sort reputation --limit 20
35
+ program
36
+ .command("list")
37
+ .description("List all registered services ranked by trust")
38
+ .option("-c, --chain <chain>", "Target chain", "ethereum")
39
+ .option("-s, --sort <field>", "Sort by: reputation, name, recent", "reputation")
40
+ .option("-n, --limit <number>", "Max results", "20")
41
+ .option("--type <type>", "Filter by service type (a2a, mcp, web, oasf, x402)")
42
+ .action((opts) => {
43
+ const { output, refresh } = program.opts();
44
+ listCommand({ ...opts, output, refresh });
45
+ });
46
+ // trustrouter inspect 42 --chain base
47
+ // trustrouter inspect "OracleName" --chain base
48
+ program
49
+ .command("inspect")
50
+ .description("Show full details of a registered service (by ID or name)")
51
+ .argument("<id-or-name>", "The service's on-chain token ID or name")
52
+ .option("-c, --chain <chain>", "Target chain", "ethereum")
53
+ .action((idOrName, opts) => {
54
+ const { output, refresh } = program.opts();
55
+ inspectCommand(idOrName, { ...opts, output, refresh });
56
+ });
57
+ program.parse();
58
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CACR,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC;IACtD,uEAAuE;IACvE,+DAA+D;IAC/D,wEAAwE;IACxE,KAAK,CAAC,GAAG,CAAC,2BAA2B,MAAM,EAAE,CAAC,CACjD;KACA,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,uBAAuB,EAAE,8BAA8B,EAAE,OAAO,CAAC;KACxE,MAAM,CAAC,WAAW,EAAE,8CAA8C,CAAC,CAAC;AAEzE,mEAAmE;AACnE,OAAO;KACF,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,iDAAiD,CAAC;KAC9D,cAAc,CAAC,0BAA0B,EAAE,mCAAmC,CAAC;KAC/E,MAAM,CAAC,eAAe,EAAE,oDAAoD,CAAC;KAC7E,MAAM,CAAC,qBAAqB,EAAE,cAAc,EAAE,UAAU,CAAC;KACzD,MAAM,CAAC,sBAAsB,EAAE,uBAAuB,EAAE,GAAG,CAAC;KAC5D,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;IACb,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEP,6DAA6D;AAC7D,OAAO;KACF,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8CAA8C,CAAC;KAC3D,MAAM,CAAC,qBAAqB,EAAE,cAAc,EAAE,UAAU,CAAC;KACzD,MAAM,CAAC,oBAAoB,EAAE,mCAAmC,EAAE,YAAY,CAAC;KAC/E,MAAM,CAAC,sBAAsB,EAAE,aAAa,EAAE,IAAI,CAAC;KACnD,MAAM,CAAC,eAAe,EAAE,oDAAoD,CAAC;KAC7E,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;IACb,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEP,sCAAsC;AACtC,gDAAgD;AAChD,OAAO;KACF,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,2DAA2D,CAAC;KACxE,QAAQ,CAAC,cAAc,EAAE,yCAAyC,CAAC;KACnE,MAAM,CAAC,qBAAqB,EAAE,cAAc,EAAE,UAAU,CAAC;KACzD,MAAM,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE;IACvB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC3C,cAAc,CAAC,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEP,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ interface FindOptions {
2
+ task: string;
3
+ type?: string;
4
+ chain: string;
5
+ limit: string;
6
+ output: string;
7
+ refresh?: boolean;
8
+ }
9
+ export declare function findCommand(options: FindOptions): Promise<void>;
10
+ export {};
11
+ //# sourceMappingURL=find.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../src/commands/find.ts"],"names":[],"mappings":"AAMA,UAAU,WAAW;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA4CrE"}
@@ -0,0 +1,100 @@
1
+ import chalk from "chalk";
2
+ import Table from "cli-table3";
3
+ import { fetchAgents } from "../registry.js";
4
+ import { rankAgents } from "../router/index.js";
5
+ import { setRefresh } from "../cache.js";
6
+ export async function findCommand(options) {
7
+ const isJson = options.output === "json";
8
+ if (options.refresh)
9
+ setRefresh(true);
10
+ try {
11
+ if (!isJson)
12
+ console.log(chalk.dim("\n Querying ERC-8004 service registry via public RPC..."));
13
+ const agents = await fetchAgents({ chain: options.chain, first: 100 });
14
+ const results = rankAgents(agents, {
15
+ task: options.task,
16
+ type: options.type,
17
+ limit: parseInt(options.limit),
18
+ });
19
+ if (results.length === 0) {
20
+ if (isJson) {
21
+ console.log(JSON.stringify([]));
22
+ }
23
+ else {
24
+ console.log(chalk.yellow("\n No services found matching your criteria.\n"));
25
+ }
26
+ return;
27
+ }
28
+ if (isJson) {
29
+ console.log(JSON.stringify(results.map(toJson), null, 2));
30
+ return;
31
+ }
32
+ console.log("\n" + chalk.bold.cyan(" 🔍 Results for: ") + chalk.white(`"${options.task}"`));
33
+ if (options.type)
34
+ console.log(chalk.dim(` Filtered by type: ${options.type}`));
35
+ console.log("");
36
+ printTable(results);
37
+ console.log(chalk.dim(`\n ${results.length} result(s)\n`));
38
+ }
39
+ catch (err) {
40
+ if (isJson) {
41
+ console.log(JSON.stringify({ error: err.message }));
42
+ process.exit(1);
43
+ }
44
+ console.error(chalk.red(`\n ✗ Error: ${err.message}\n`));
45
+ process.exit(1);
46
+ }
47
+ }
48
+ function toJson(s) {
49
+ return {
50
+ agentId: s.agent.agentId,
51
+ name: s.agent.registration.name,
52
+ description: s.agent.registration.description,
53
+ trustScore: s.trustScore,
54
+ feedbackCount: s.agent.feedbackCount,
55
+ avgScore: s.agent.avgScore,
56
+ validationCount: s.agent.validationCount,
57
+ validationAvg: s.agent.validationAvg,
58
+ services: s.agent.registration.services || [],
59
+ x402Support: s.agent.registration.x402Support || false,
60
+ x402Endpoint: s.agent.registration.services?.find(svc => svc.name.toLowerCase() === "x402")?.endpoint || null,
61
+ owner: s.agent.owner,
62
+ };
63
+ }
64
+ function printTable(results) {
65
+ const table = new Table({
66
+ head: ["#", "ID", "Name", "Trust", "Reviews", "Services"].map((h) => chalk.bold(h)),
67
+ colWidths: [5, 8, 30, 14, 9, 28],
68
+ style: { head: [], border: ["dim"] },
69
+ });
70
+ results.forEach((r, i) => {
71
+ const svcs = r.agent.registration.services?.map((s) => svcTag(s.name)).join(" ") || chalk.dim("-");
72
+ table.push([
73
+ chalk.dim(`${i + 1}`),
74
+ chalk.white(`${r.agent.agentId}`),
75
+ chalk.bold(trunc(r.agent.registration.name || "(unnamed)", 28)),
76
+ scoreBar(r.trustScore),
77
+ `${r.agent.feedbackCount}`,
78
+ svcs,
79
+ ]);
80
+ });
81
+ console.log(table.toString());
82
+ }
83
+ const SVC_ICONS = {
84
+ a2a: "🤖", mcp: "🔧", web: "🌐", oasf: "📦", x402: "💰",
85
+ };
86
+ function svcTag(name) {
87
+ const icon = SVC_ICONS[name.toLowerCase()] || "🔗";
88
+ return icon + chalk.dim(name.toUpperCase());
89
+ }
90
+ function trunc(s, n) {
91
+ return s.length > n ? s.slice(0, n - 1) + "…" : s;
92
+ }
93
+ function scoreBar(score) {
94
+ const n = Math.min(100, Math.max(0, score));
95
+ const filled = Math.round(n / 10);
96
+ const bar = "█".repeat(filled) + "░".repeat(10 - filled);
97
+ const color = n >= 70 ? chalk.green : n >= 40 ? chalk.yellow : chalk.red;
98
+ return color(bar) + chalk.dim(` ${n.toFixed(1)}`);
99
+ }
100
+ //# sourceMappingURL=find.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../../src/commands/find.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ interface InspectOptions {
2
+ chain: string;
3
+ output: string;
4
+ refresh?: boolean;
5
+ }
6
+ export declare function inspectCommand(idOrName: string, options: InspectOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"AAoBA,UAAU,cAAc;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAiI7F"}