kompass-sdk 0.6.0 → 0.7.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.
@@ -1,6 +1,7 @@
1
1
  /**
2
- * ERC-8004 On-Chain Source Adapter
3
- * Indexes agent identities from the ERC-8004 Identity Registry on Base
2
+ * ERC-8004 Source Adapter
3
+ * Searches 8004scan.io API for registered AI agents
4
+ * Real data — agent identity, reputation, supported protocols
4
5
  */
5
6
  import type { SourceAdapter } from "./types.js";
6
7
  export declare function createErc8004Adapter(network?: "base" | "base-sepolia"): SourceAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"erc8004.d.ts","sourceRoot":"","sources":["../../src/sources/erc8004.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAqC,MAAM,YAAY,CAAC;AAsBnF,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,MAAM,GAAG,cAA+B,GAAG,aAAa,CAyFrG"}
1
+ {"version":3,"file":"erc8004.d.ts","sourceRoot":"","sources":["../../src/sources/erc8004.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAqC,MAAM,YAAY,CAAC;AAInF,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,MAAM,GAAG,cAAuB,GAAG,aAAa,CAkD7F"}
@@ -1,90 +1,40 @@
1
1
  /**
2
- * ERC-8004 On-Chain Source Adapter
3
- * Indexes agent identities from the ERC-8004 Identity Registry on Base
2
+ * ERC-8004 Source Adapter
3
+ * Searches 8004scan.io API for registered AI agents
4
+ * Real data — agent identity, reputation, supported protocols
4
5
  */
5
- import { createPublicClient, http, parseAbiItem } from "viem";
6
- import { base, baseSepolia } from "viem/chains";
7
- // ERC-8004 Identity Registry addresses
8
- const REGISTRY_ADDRESSES = {
9
- "base": "0x8004A818BFB912233c491871b3d84c89A494BD9e",
10
- "base-sepolia": "0x8004A818BFB912233c491871b3d84c89A494BD9e",
11
- };
12
- const TRANSFER_EVENT = parseAbiItem("event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)");
13
- const TOKEN_URI_ABI = [
14
- {
15
- type: "function",
16
- name: "tokenURI",
17
- inputs: [{ name: "tokenId", type: "uint256" }],
18
- outputs: [{ name: "", type: "string" }],
19
- stateMutability: "view",
20
- },
21
- ];
22
- export function createErc8004Adapter(network = "base-sepolia") {
23
- const chain = network === "base" ? base : baseSepolia;
24
- const registryAddress = REGISTRY_ADDRESSES[network];
25
- const client = createPublicClient({
26
- chain,
27
- transport: http(),
28
- });
6
+ const SCAN_API = "https://www.8004scan.io/api/v1";
7
+ export function createErc8004Adapter(network = "base") {
29
8
  return {
30
9
  name: "erc8004",
31
- displayName: "ERC-8004 Identity Registry",
10
+ displayName: "ERC-8004 Identity Registry (8004scan)",
32
11
  async search(query, options) {
33
12
  const limit = options?.limit ?? 20;
13
+ const timeout = options?.timeout ?? 10000;
34
14
  try {
35
- // Get recent Transfer events (minting = from 0x0)
36
- const logs = await client.getLogs({
37
- address: registryAddress,
38
- event: TRANSFER_EVENT,
39
- args: { from: "0x0000000000000000000000000000000000000000" },
40
- fromBlock: "earliest",
41
- toBlock: "latest",
15
+ // Search across all chains on 8004scan
16
+ const url = new URL(`${SCAN_API}/agents`);
17
+ if (query)
18
+ url.searchParams.set("search", query);
19
+ url.searchParams.set("limit", String(limit));
20
+ const res = await fetch(url.toString(), {
21
+ signal: AbortSignal.timeout(timeout),
42
22
  });
43
- const agents = [];
44
- // Process most recent first
45
- const recentLogs = logs.slice(-limit * 2).reverse();
46
- for (const log of recentLogs) {
47
- if (agents.length >= limit)
48
- break;
49
- const tokenId = log.args.tokenId;
50
- const owner = log.args.to;
51
- try {
52
- // Fetch tokenURI for agent metadata
53
- const uri = await client.readContract({
54
- address: registryAddress,
55
- abi: TOKEN_URI_ABI,
56
- functionName: "tokenURI",
57
- args: [tokenId],
58
- });
59
- // Resolve URI to JSON
60
- let metadata = {};
61
- if (uri.startsWith("http") || uri.startsWith("ipfs")) {
62
- const fetchUrl = uri.startsWith("ipfs://")
63
- ? `https://ipfs.io/ipfs/${uri.slice(7)}`
64
- : uri;
65
- const res = await fetch(fetchUrl, { signal: AbortSignal.timeout(3000) });
66
- if (res.ok)
67
- metadata = await res.json();
68
- }
69
- else if (uri.startsWith("data:")) {
70
- const json = uri.split(",")[1];
71
- metadata = JSON.parse(atob(json));
72
- }
73
- const agent = mapErc8004Agent(tokenId, owner, metadata, network);
74
- // Filter by query
75
- if (query) {
76
- const searchText = `${agent.name} ${agent.description} ${agent.categories.join(" ")}`.toLowerCase();
77
- if (!searchText.includes(query.toLowerCase()))
78
- continue;
79
- }
80
- agents.push(agent);
81
- }
82
- catch {
83
- // Skip agents with unresolvable metadata
84
- continue;
85
- }
86
- }
87
- return agents;
23
+ if (!res.ok)
24
+ return [];
25
+ const data = await res.json();
26
+ const agents = data.items ?? data.agents ?? data.data ?? [];
27
+ if (!Array.isArray(agents))
28
+ return [];
29
+ return agents
30
+ .filter((a) => {
31
+ if (!query)
32
+ return true;
33
+ const text = `${a.name ?? ""} ${a.description ?? ""}`.toLowerCase();
34
+ return query.toLowerCase().split(/\s+/).some((t) => text.includes(t));
35
+ })
36
+ .slice(0, limit)
37
+ .map(mapErc8004Agent);
88
38
  }
89
39
  catch {
90
40
  return [];
@@ -92,8 +42,10 @@ export function createErc8004Adapter(network = "base-sepolia") {
92
42
  },
93
43
  async ping() {
94
44
  try {
95
- await client.getBlockNumber();
96
- return true;
45
+ const res = await fetch(`${SCAN_API}/agents?limit=1`, {
46
+ signal: AbortSignal.timeout(5000),
47
+ });
48
+ return res.ok;
97
49
  }
98
50
  catch {
99
51
  return false;
@@ -101,50 +53,52 @@ export function createErc8004Adapter(network = "base-sepolia") {
101
53
  },
102
54
  };
103
55
  }
104
- function mapErc8004Agent(tokenId, owner, metadata, network) {
105
- const services = metadata.services ?? [];
56
+ function mapErc8004Agent(agent) {
57
+ const protocols = agent.supported_protocols ?? [];
58
+ const protocol = protocols.includes("A2A") ? "a2a"
59
+ : protocols.includes("MCP") ? "mcp"
60
+ : protocols.includes("x402") || agent.x402_supported ? "x402"
61
+ : "onchain";
106
62
  const endpoints = {};
107
- for (const svc of services) {
108
- if (svc.protocol === "mcp")
109
- endpoints.mcp = svc.endpoint;
110
- if (svc.protocol === "a2a")
111
- endpoints.a2a = svc.endpoint;
112
- if (svc.protocol === "x402")
113
- endpoints.x402 = svc.endpoint;
114
- if (svc.protocol === "http")
115
- endpoints.http = svc.endpoint;
116
- }
63
+ if (protocols.includes("MCP"))
64
+ endpoints.mcp = agent.mcp_endpoint;
65
+ if (protocols.includes("A2A"))
66
+ endpoints.a2a = agent.a2a_endpoint;
67
+ if (agent.x402_supported)
68
+ endpoints.x402 = agent.x402_endpoint;
117
69
  return {
118
- id: `erc8004:${network}:${tokenId}`,
119
- nativeId: tokenId.toString(),
120
- name: metadata.name ?? `Agent #${tokenId}`,
121
- description: metadata.description ?? "",
122
- categories: metadata.categories ?? extractFromDescription(metadata.description ?? ""),
123
- capabilities: services.map((s) => `${s.protocol}: ${s.endpoint}`),
70
+ id: `erc8004:${agent.agent_id ?? agent.token_id}`,
71
+ nativeId: agent.token_id?.toString() ?? agent.agent_id ?? "",
72
+ name: agent.name ?? `Agent #${agent.token_id}`,
73
+ ensName: agent.owner_ens ?? undefined,
74
+ description: agent.description ?? "",
75
+ categories: extractCategories(agent.name ?? "", agent.description ?? ""),
76
+ capabilities: protocols.map((p) => `Supports ${p}`),
124
77
  source: "erc8004",
125
- protocol: endpoints.a2a ? "a2a" : endpoints.mcp ? "mcp" : endpoints.x402 ? "x402" : "onchain",
78
+ protocol,
126
79
  endpoints,
127
80
  reputation: {
128
- score: 0,
129
- count: 0,
130
- source: "erc8004",
81
+ score: agent.total_score ?? 0,
82
+ count: agent.star_count ?? 0,
83
+ source: "8004scan",
131
84
  },
132
- verified: true,
133
- lastSeen: Date.now(),
134
- raw: { tokenId: tokenId.toString(), owner, metadata, network },
85
+ verified: agent.is_verified ?? false,
86
+ raw: agent,
135
87
  };
136
88
  }
137
- function extractFromDescription(text) {
138
- const lower = text.toLowerCase();
89
+ function extractCategories(name, description) {
90
+ const text = `${name} ${description}`.toLowerCase();
139
91
  const cats = [];
140
- if (lower.match(/defi|yield|swap|pool/))
92
+ if (text.match(/defi|yield|swap|pool|trading/))
141
93
  cats.push("defi");
142
- if (lower.match(/data|analyt/))
94
+ if (text.match(/data|analyt|research/))
143
95
  cats.push("data");
144
- if (lower.match(/trade|trading/))
145
- cats.push("trading");
146
- if (lower.match(/research/))
147
- cats.push("research");
96
+ if (text.match(/code|develop|build/))
97
+ cats.push("development");
98
+ if (text.match(/ai|model|inference/))
99
+ cats.push("ai");
100
+ if (text.match(/security|audit/))
101
+ cats.push("security");
148
102
  return cats.length > 0 ? cats : ["general"];
149
103
  }
150
104
  //# sourceMappingURL=erc8004.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"erc8004.js","sourceRoot":"","sources":["../../src/sources/erc8004.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"erc8004.js","sourceRoot":"","sources":["../../src/sources/erc8004.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kompass-sdk",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Get any job done. Universal agent capability discovery + coordination across ACP, MCP, x402, A2A, skills, L402, and ERC-8004.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,107 +1,47 @@
1
1
  /**
2
- * ERC-8004 On-Chain Source Adapter
3
- * Indexes agent identities from the ERC-8004 Identity Registry on Base
2
+ * ERC-8004 Source Adapter
3
+ * Searches 8004scan.io API for registered AI agents
4
+ * Real data — agent identity, reputation, supported protocols
4
5
  */
5
6
 
6
- import { createPublicClient, http, type Address, parseAbiItem } from "viem";
7
- import { base, baseSepolia } from "viem/chains";
8
7
  import type { SourceAdapter, UnifiedAgent, SourceSearchOptions } from "./types.js";
9
8
 
10
- // ERC-8004 Identity Registry addresses
11
- const REGISTRY_ADDRESSES: Record<string, Address> = {
12
- "base": "0x8004A818BFB912233c491871b3d84c89A494BD9e" as Address,
13
- "base-sepolia": "0x8004A818BFB912233c491871b3d84c89A494BD9e" as Address,
14
- };
15
-
16
- const TRANSFER_EVENT = parseAbiItem(
17
- "event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)"
18
- );
19
-
20
- const TOKEN_URI_ABI = [
21
- {
22
- type: "function",
23
- name: "tokenURI",
24
- inputs: [{ name: "tokenId", type: "uint256" }],
25
- outputs: [{ name: "", type: "string" }],
26
- stateMutability: "view",
27
- },
28
- ] as const;
29
-
30
- export function createErc8004Adapter(network: "base" | "base-sepolia" = "base-sepolia"): SourceAdapter {
31
- const chain = network === "base" ? base : baseSepolia;
32
- const registryAddress = REGISTRY_ADDRESSES[network];
33
-
34
- const client = createPublicClient({
35
- chain,
36
- transport: http(),
37
- });
9
+ const SCAN_API = "https://www.8004scan.io/api/v1";
38
10
 
11
+ export function createErc8004Adapter(network: "base" | "base-sepolia" = "base"): SourceAdapter {
39
12
  return {
40
13
  name: "erc8004",
41
- displayName: "ERC-8004 Identity Registry",
14
+ displayName: "ERC-8004 Identity Registry (8004scan)",
42
15
 
43
16
  async search(query: string, options?: SourceSearchOptions): Promise<UnifiedAgent[]> {
44
17
  const limit = options?.limit ?? 20;
18
+ const timeout = options?.timeout ?? 10000;
45
19
 
46
20
  try {
47
- // Get recent Transfer events (minting = from 0x0)
48
- const logs = await client.getLogs({
49
- address: registryAddress,
50
- event: TRANSFER_EVENT,
51
- args: { from: "0x0000000000000000000000000000000000000000" as Address },
52
- fromBlock: "earliest",
53
- toBlock: "latest",
54
- });
55
-
56
- const agents: UnifiedAgent[] = [];
57
-
58
- // Process most recent first
59
- const recentLogs = logs.slice(-limit * 2).reverse();
21
+ // Search across all chains on 8004scan
22
+ const url = new URL(`${SCAN_API}/agents`);
23
+ if (query) url.searchParams.set("search", query);
24
+ url.searchParams.set("limit", String(limit));
60
25
 
61
- for (const log of recentLogs) {
62
- if (agents.length >= limit) break;
63
-
64
- const tokenId = log.args.tokenId!;
65
- const owner = log.args.to!;
66
-
67
- try {
68
- // Fetch tokenURI for agent metadata
69
- const uri = await client.readContract({
70
- address: registryAddress,
71
- abi: TOKEN_URI_ABI,
72
- functionName: "tokenURI",
73
- args: [tokenId],
74
- });
75
-
76
- // Resolve URI to JSON
77
- let metadata: any = {};
78
- if (uri.startsWith("http") || uri.startsWith("ipfs")) {
79
- const fetchUrl = uri.startsWith("ipfs://")
80
- ? `https://ipfs.io/ipfs/${uri.slice(7)}`
81
- : uri;
82
- const res = await fetch(fetchUrl, { signal: AbortSignal.timeout(3000) });
83
- if (res.ok) metadata = await res.json();
84
- } else if (uri.startsWith("data:")) {
85
- const json = uri.split(",")[1];
86
- metadata = JSON.parse(atob(json));
87
- }
26
+ const res = await fetch(url.toString(), {
27
+ signal: AbortSignal.timeout(timeout),
28
+ });
88
29
 
89
- const agent = mapErc8004Agent(tokenId, owner, metadata, network);
30
+ if (!res.ok) return [];
90
31
 
91
- // Filter by query
92
- if (query) {
93
- const searchText = `${agent.name} ${agent.description} ${agent.categories.join(" ")}`.toLowerCase();
94
- if (!searchText.includes(query.toLowerCase())) continue;
95
- }
32
+ const data = await res.json();
33
+ const agents = data.items ?? data.agents ?? data.data ?? [];
96
34
 
97
- agents.push(agent);
98
- } catch {
99
- // Skip agents with unresolvable metadata
100
- continue;
101
- }
102
- }
35
+ if (!Array.isArray(agents)) return [];
103
36
 
104
- return agents;
37
+ return agents
38
+ .filter((a: any) => {
39
+ if (!query) return true;
40
+ const text = `${a.name ?? ""} ${a.description ?? ""}`.toLowerCase();
41
+ return query.toLowerCase().split(/\s+/).some((t) => text.includes(t));
42
+ })
43
+ .slice(0, limit)
44
+ .map(mapErc8004Agent);
105
45
  } catch {
106
46
  return [];
107
47
  }
@@ -109,8 +49,10 @@ export function createErc8004Adapter(network: "base" | "base-sepolia" = "base-se
109
49
 
110
50
  async ping(): Promise<boolean> {
111
51
  try {
112
- await client.getBlockNumber();
113
- return true;
52
+ const res = await fetch(`${SCAN_API}/agents?limit=1`, {
53
+ signal: AbortSignal.timeout(5000),
54
+ });
55
+ return res.ok;
114
56
  } catch {
115
57
  return false;
116
58
  }
@@ -118,49 +60,46 @@ export function createErc8004Adapter(network: "base" | "base-sepolia" = "base-se
118
60
  };
119
61
  }
120
62
 
121
- function mapErc8004Agent(
122
- tokenId: bigint,
123
- owner: Address,
124
- metadata: any,
125
- network: string
126
- ): UnifiedAgent {
127
- const services = metadata.services ?? [];
128
- const endpoints: UnifiedAgent["endpoints"] = {};
63
+ function mapErc8004Agent(agent: any): UnifiedAgent {
64
+ const protocols = agent.supported_protocols ?? [];
65
+ const protocol = protocols.includes("A2A") ? "a2a" as const
66
+ : protocols.includes("MCP") ? "mcp" as const
67
+ : protocols.includes("x402") || agent.x402_supported ? "x402" as const
68
+ : "onchain" as const;
129
69
 
130
- for (const svc of services) {
131
- if (svc.protocol === "mcp") endpoints.mcp = svc.endpoint;
132
- if (svc.protocol === "a2a") endpoints.a2a = svc.endpoint;
133
- if (svc.protocol === "x402") endpoints.x402 = svc.endpoint;
134
- if (svc.protocol === "http") endpoints.http = svc.endpoint;
135
- }
70
+ const endpoints: UnifiedAgent["endpoints"] = {};
71
+ if (protocols.includes("MCP")) endpoints.mcp = agent.mcp_endpoint;
72
+ if (protocols.includes("A2A")) endpoints.a2a = agent.a2a_endpoint;
73
+ if (agent.x402_supported) endpoints.x402 = agent.x402_endpoint;
136
74
 
137
75
  return {
138
- id: `erc8004:${network}:${tokenId}`,
139
- nativeId: tokenId.toString(),
140
- name: metadata.name ?? `Agent #${tokenId}`,
141
- description: metadata.description ?? "",
142
- categories: metadata.categories ?? extractFromDescription(metadata.description ?? ""),
143
- capabilities: services.map((s: any) => `${s.protocol}: ${s.endpoint}`),
76
+ id: `erc8004:${agent.agent_id ?? agent.token_id}`,
77
+ nativeId: agent.token_id?.toString() ?? agent.agent_id ?? "",
78
+ name: agent.name ?? `Agent #${agent.token_id}`,
79
+ ensName: agent.owner_ens ?? undefined,
80
+ description: agent.description ?? "",
81
+ categories: extractCategories(agent.name ?? "", agent.description ?? ""),
82
+ capabilities: protocols.map((p: string) => `Supports ${p}`),
144
83
  source: "erc8004",
145
- protocol: endpoints.a2a ? "a2a" : endpoints.mcp ? "mcp" : endpoints.x402 ? "x402" : "onchain",
84
+ protocol,
146
85
  endpoints,
147
86
  reputation: {
148
- score: 0,
149
- count: 0,
150
- source: "erc8004",
87
+ score: agent.total_score ?? 0,
88
+ count: agent.star_count ?? 0,
89
+ source: "8004scan",
151
90
  },
152
- verified: true,
153
- lastSeen: Date.now(),
154
- raw: { tokenId: tokenId.toString(), owner, metadata, network },
91
+ verified: agent.is_verified ?? false,
92
+ raw: agent,
155
93
  };
156
94
  }
157
95
 
158
- function extractFromDescription(text: string): string[] {
159
- const lower = text.toLowerCase();
96
+ function extractCategories(name: string, description: string): string[] {
97
+ const text = `${name} ${description}`.toLowerCase();
160
98
  const cats: string[] = [];
161
- if (lower.match(/defi|yield|swap|pool/)) cats.push("defi");
162
- if (lower.match(/data|analyt/)) cats.push("data");
163
- if (lower.match(/trade|trading/)) cats.push("trading");
164
- if (lower.match(/research/)) cats.push("research");
99
+ if (text.match(/defi|yield|swap|pool|trading/)) cats.push("defi");
100
+ if (text.match(/data|analyt|research/)) cats.push("data");
101
+ if (text.match(/code|develop|build/)) cats.push("development");
102
+ if (text.match(/ai|model|inference/)) cats.push("ai");
103
+ if (text.match(/security|audit/)) cats.push("security");
165
104
  return cats.length > 0 ? cats : ["general"];
166
105
  }