kompass-sdk 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.
Files changed (205) hide show
  1. package/dist/a2a/agent-card.d.ts +13 -0
  2. package/dist/a2a/agent-card.d.ts.map +1 -0
  3. package/dist/a2a/agent-card.js +52 -0
  4. package/dist/a2a/agent-card.js.map +1 -0
  5. package/dist/a2a/bridge.d.ts +52 -0
  6. package/dist/a2a/bridge.d.ts.map +1 -0
  7. package/dist/a2a/bridge.js +123 -0
  8. package/dist/a2a/bridge.js.map +1 -0
  9. package/dist/a2a/client.d.ts +34 -0
  10. package/dist/a2a/client.d.ts.map +1 -0
  11. package/dist/a2a/client.js +65 -0
  12. package/dist/a2a/client.js.map +1 -0
  13. package/dist/a2a/server.d.ts +17 -0
  14. package/dist/a2a/server.d.ts.map +1 -0
  15. package/dist/a2a/server.js +194 -0
  16. package/dist/a2a/server.js.map +1 -0
  17. package/dist/abi.d.ts +1068 -0
  18. package/dist/abi.d.ts.map +1 -0
  19. package/dist/abi.js +1372 -0
  20. package/dist/abi.js.map +1 -0
  21. package/dist/adapters/agentkit.d.ts +41 -0
  22. package/dist/adapters/agentkit.d.ts.map +1 -0
  23. package/dist/adapters/agentkit.js +67 -0
  24. package/dist/adapters/agentkit.js.map +1 -0
  25. package/dist/adapters/generic.d.ts +35 -0
  26. package/dist/adapters/generic.d.ts.map +1 -0
  27. package/dist/adapters/generic.js +47 -0
  28. package/dist/adapters/generic.js.map +1 -0
  29. package/dist/adapters/index.d.ts +5 -0
  30. package/dist/adapters/index.d.ts.map +1 -0
  31. package/dist/adapters/index.js +5 -0
  32. package/dist/adapters/index.js.map +1 -0
  33. package/dist/adapters/langchain.d.ts +26 -0
  34. package/dist/adapters/langchain.d.ts.map +1 -0
  35. package/dist/adapters/langchain.js +228 -0
  36. package/dist/adapters/langchain.js.map +1 -0
  37. package/dist/adapters/openclaw.d.ts +18 -0
  38. package/dist/adapters/openclaw.d.ts.map +1 -0
  39. package/dist/adapters/openclaw.js +168 -0
  40. package/dist/adapters/openclaw.js.map +1 -0
  41. package/dist/aggregator.d.ts +36 -0
  42. package/dist/aggregator.d.ts.map +1 -0
  43. package/dist/aggregator.js +168 -0
  44. package/dist/aggregator.js.map +1 -0
  45. package/dist/backends/acp.d.ts +29 -0
  46. package/dist/backends/acp.d.ts.map +1 -0
  47. package/dist/backends/acp.js +126 -0
  48. package/dist/backends/acp.js.map +1 -0
  49. package/dist/backends/types.d.ts +59 -0
  50. package/dist/backends/types.d.ts.map +1 -0
  51. package/dist/backends/types.js +2 -0
  52. package/dist/backends/types.js.map +1 -0
  53. package/dist/bridge.d.ts +35 -0
  54. package/dist/bridge.d.ts.map +1 -0
  55. package/dist/bridge.js +192 -0
  56. package/dist/bridge.js.map +1 -0
  57. package/dist/cli.d.ts +12 -0
  58. package/dist/cli.d.ts.map +1 -0
  59. package/dist/cli.js +331 -0
  60. package/dist/cli.js.map +1 -0
  61. package/dist/discover.d.ts +15 -0
  62. package/dist/discover.d.ts.map +1 -0
  63. package/dist/discover.js +163 -0
  64. package/dist/discover.js.map +1 -0
  65. package/dist/escrow.d.ts +45 -0
  66. package/dist/escrow.d.ts.map +1 -0
  67. package/dist/escrow.js +243 -0
  68. package/dist/escrow.js.map +1 -0
  69. package/dist/index.d.ts +63 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +145 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/intents.d.ts +28 -0
  74. package/dist/intents.d.ts.map +1 -0
  75. package/dist/intents.js +111 -0
  76. package/dist/intents.js.map +1 -0
  77. package/dist/matching.d.ts +29 -0
  78. package/dist/matching.d.ts.map +1 -0
  79. package/dist/matching.js +147 -0
  80. package/dist/matching.js.map +1 -0
  81. package/dist/pipelineAbi.d.ts +113 -0
  82. package/dist/pipelineAbi.d.ts.map +1 -0
  83. package/dist/pipelineAbi.js +74 -0
  84. package/dist/pipelineAbi.js.map +1 -0
  85. package/dist/pipelines.d.ts +42 -0
  86. package/dist/pipelines.d.ts.map +1 -0
  87. package/dist/pipelines.js +185 -0
  88. package/dist/pipelines.js.map +1 -0
  89. package/dist/registry.d.ts +36 -0
  90. package/dist/registry.d.ts.map +1 -0
  91. package/dist/registry.js +187 -0
  92. package/dist/registry.js.map +1 -0
  93. package/dist/reputation.d.ts +10 -0
  94. package/dist/reputation.d.ts.map +1 -0
  95. package/dist/reputation.js +33 -0
  96. package/dist/reputation.js.map +1 -0
  97. package/dist/router.d.ts +72 -0
  98. package/dist/router.d.ts.map +1 -0
  99. package/dist/router.js +190 -0
  100. package/dist/router.js.map +1 -0
  101. package/dist/simple.d.ts +160 -0
  102. package/dist/simple.d.ts.map +1 -0
  103. package/dist/simple.js +237 -0
  104. package/dist/simple.js.map +1 -0
  105. package/dist/sources/a2a-wellknown.d.ts +8 -0
  106. package/dist/sources/a2a-wellknown.d.ts.map +1 -0
  107. package/dist/sources/a2a-wellknown.js +104 -0
  108. package/dist/sources/a2a-wellknown.js.map +1 -0
  109. package/dist/sources/acp.d.ts +7 -0
  110. package/dist/sources/acp.d.ts.map +1 -0
  111. package/dist/sources/acp.js +86 -0
  112. package/dist/sources/acp.js.map +1 -0
  113. package/dist/sources/adp.d.ts +7 -0
  114. package/dist/sources/adp.d.ts.map +1 -0
  115. package/dist/sources/adp.js +59 -0
  116. package/dist/sources/adp.js.map +1 -0
  117. package/dist/sources/erc8004.d.ts +7 -0
  118. package/dist/sources/erc8004.d.ts.map +1 -0
  119. package/dist/sources/erc8004.js +150 -0
  120. package/dist/sources/erc8004.js.map +1 -0
  121. package/dist/sources/index.d.ts +17 -0
  122. package/dist/sources/index.d.ts.map +1 -0
  123. package/dist/sources/index.js +35 -0
  124. package/dist/sources/index.js.map +1 -0
  125. package/dist/sources/kompass-registry.d.ts +8 -0
  126. package/dist/sources/kompass-registry.d.ts.map +1 -0
  127. package/dist/sources/kompass-registry.js +62 -0
  128. package/dist/sources/kompass-registry.js.map +1 -0
  129. package/dist/sources/l402-directory.d.ts +7 -0
  130. package/dist/sources/l402-directory.d.ts.map +1 -0
  131. package/dist/sources/l402-directory.js +42 -0
  132. package/dist/sources/l402-directory.js.map +1 -0
  133. package/dist/sources/mcp-registry.d.ts +8 -0
  134. package/dist/sources/mcp-registry.d.ts.map +1 -0
  135. package/dist/sources/mcp-registry.js +85 -0
  136. package/dist/sources/mcp-registry.js.map +1 -0
  137. package/dist/sources/skills.d.ts +8 -0
  138. package/dist/sources/skills.d.ts.map +1 -0
  139. package/dist/sources/skills.js +153 -0
  140. package/dist/sources/skills.js.map +1 -0
  141. package/dist/sources/types.d.ts +72 -0
  142. package/dist/sources/types.d.ts.map +1 -0
  143. package/dist/sources/types.js +8 -0
  144. package/dist/sources/types.js.map +1 -0
  145. package/dist/sources/x402-ecosystem.d.ts +7 -0
  146. package/dist/sources/x402-ecosystem.d.ts.map +1 -0
  147. package/dist/sources/x402-ecosystem.js +78 -0
  148. package/dist/sources/x402-ecosystem.js.map +1 -0
  149. package/dist/types.d.ts +133 -0
  150. package/dist/types.d.ts.map +1 -0
  151. package/dist/types.js +2 -0
  152. package/dist/types.js.map +1 -0
  153. package/dist/unified.d.ts +90 -0
  154. package/dist/unified.d.ts.map +1 -0
  155. package/dist/unified.js +107 -0
  156. package/dist/unified.js.map +1 -0
  157. package/dist/x402.d.ts +30 -0
  158. package/dist/x402.d.ts.map +1 -0
  159. package/dist/x402.js +79 -0
  160. package/dist/x402.js.map +1 -0
  161. package/package.json +61 -0
  162. package/scripts/bootstrap-agents.mjs +246 -0
  163. package/src/.gitkeep +0 -0
  164. package/src/a2a/agent-card.ts +66 -0
  165. package/src/a2a/bridge.ts +168 -0
  166. package/src/a2a/client.ts +92 -0
  167. package/src/a2a/server.ts +234 -0
  168. package/src/abi.ts +1373 -0
  169. package/src/adapters/agentkit.ts +83 -0
  170. package/src/adapters/generic.ts +62 -0
  171. package/src/adapters/index.ts +4 -0
  172. package/src/adapters/langchain.ts +282 -0
  173. package/src/adapters/openclaw.ts +203 -0
  174. package/src/aggregator.ts +203 -0
  175. package/src/backends/acp.ts +199 -0
  176. package/src/backends/types.ts +78 -0
  177. package/src/bridge.ts +263 -0
  178. package/src/cli.ts +397 -0
  179. package/src/discover.ts +187 -0
  180. package/src/escrow.ts +284 -0
  181. package/src/index.ts +245 -0
  182. package/src/intents.ts +166 -0
  183. package/src/matching.ts +192 -0
  184. package/src/pipelineAbi.ts +74 -0
  185. package/src/pipelines.ts +253 -0
  186. package/src/registry.ts +232 -0
  187. package/src/reputation.ts +43 -0
  188. package/src/router.ts +279 -0
  189. package/src/simple.ts +366 -0
  190. package/src/sources/a2a-wellknown.ts +120 -0
  191. package/src/sources/acp.ts +91 -0
  192. package/src/sources/adp.ts +64 -0
  193. package/src/sources/erc8004.ts +166 -0
  194. package/src/sources/index.ts +52 -0
  195. package/src/sources/kompass-registry.ts +67 -0
  196. package/src/sources/l402-directory.ts +51 -0
  197. package/src/sources/mcp-registry.ts +104 -0
  198. package/src/sources/skills.ts +161 -0
  199. package/src/sources/types.ts +82 -0
  200. package/src/sources/x402-ecosystem.ts +86 -0
  201. package/src/types.ts +147 -0
  202. package/src/unified.ts +155 -0
  203. package/src/x402.ts +122 -0
  204. package/tests/pipelineFlow.test.ts +239 -0
  205. package/tsconfig.json +20 -0
@@ -0,0 +1,120 @@
1
+ /**
2
+ * A2A Agent Card Source Adapter
3
+ * Crawls .well-known/agent-card.json from known domains
4
+ * Google's A2A protocol — IANA registered well-known URI
5
+ */
6
+
7
+ import type { SourceAdapter, UnifiedAgent, SourceSearchOptions } from "./types.js";
8
+
9
+ // Seed list of domains known to support A2A agent cards
10
+ const SEED_DOMAINS = [
11
+ "https://agents.google.com",
12
+ "https://agents.anthropic.com",
13
+ "https://agents.openai.com",
14
+ "https://api.langchain.com",
15
+ "https://agents.vercel.com",
16
+ "https://agent.coinbase.com",
17
+ "https://agents.stripe.com",
18
+ "https://agent.shopify.com",
19
+ ];
20
+
21
+ interface AgentCard {
22
+ name: string;
23
+ description?: string;
24
+ url?: string;
25
+ provider?: { name: string; url?: string };
26
+ capabilities?: { streaming?: boolean; pushNotifications?: boolean };
27
+ authentication?: { type: string }[];
28
+ skills?: { id: string; name: string; description: string; inputModes?: string[]; outputModes?: string[] }[];
29
+ }
30
+
31
+ export const a2aWellknownAdapter: SourceAdapter = {
32
+ name: "a2a-wellknown",
33
+ displayName: "A2A Agent Cards (.well-known)",
34
+
35
+ async search(query: string, options?: SourceSearchOptions): Promise<UnifiedAgent[]> {
36
+ const timeout = options?.timeout ?? 3000;
37
+ const results: UnifiedAgent[] = [];
38
+
39
+ // Crawl all seed domains in parallel
40
+ const promises = SEED_DOMAINS.map(async (domain) => {
41
+ try {
42
+ const url = `${domain}/.well-known/agent-card.json`;
43
+ const res = await fetch(url, { signal: AbortSignal.timeout(timeout) });
44
+ if (!res.ok) return null;
45
+ const card: AgentCard = await res.json();
46
+ return mapAgentCard(card, domain);
47
+ } catch {
48
+ return null;
49
+ }
50
+ });
51
+
52
+ const settled = await Promise.allSettled(promises);
53
+ for (const result of settled) {
54
+ if (result.status === "fulfilled" && result.value) {
55
+ results.push(result.value);
56
+ }
57
+ }
58
+
59
+ // Filter by query
60
+ if (query) {
61
+ const lower = query.toLowerCase();
62
+ return results.filter((a) =>
63
+ a.name.toLowerCase().includes(lower) ||
64
+ a.description.toLowerCase().includes(lower) ||
65
+ a.categories.some((c) => c.toLowerCase().includes(lower))
66
+ );
67
+ }
68
+
69
+ return results.slice(0, options?.limit ?? 50);
70
+ },
71
+
72
+ async ping(): Promise<boolean> {
73
+ // Try to fetch at least one agent card
74
+ for (const domain of SEED_DOMAINS.slice(0, 3)) {
75
+ try {
76
+ const res = await fetch(`${domain}/.well-known/agent-card.json`, {
77
+ signal: AbortSignal.timeout(3000),
78
+ });
79
+ if (res.ok) return true;
80
+ } catch {
81
+ continue;
82
+ }
83
+ }
84
+ return false;
85
+ },
86
+ };
87
+
88
+ function mapAgentCard(card: AgentCard, domain: string): UnifiedAgent {
89
+ const skills = card.skills ?? [];
90
+ const categories = skills.flatMap((s) => extractSkillCategories(s.name, s.description));
91
+ const uniqueCats = [...new Set(categories)];
92
+
93
+ return {
94
+ id: `a2a-wellknown:${new URL(domain).hostname}`,
95
+ nativeId: new URL(domain).hostname,
96
+ name: card.name,
97
+ description: card.description ?? skills.map((s) => s.description).join(". "),
98
+ categories: uniqueCats.length > 0 ? uniqueCats : ["general"],
99
+ capabilities: skills.map((s) => `${s.name}: ${s.description}`),
100
+ source: "a2a-wellknown",
101
+ protocol: "a2a",
102
+ endpoints: {
103
+ a2a: card.url ?? domain,
104
+ http: domain,
105
+ },
106
+ pricing: { model: "unknown" },
107
+ verified: true,
108
+ raw: card,
109
+ };
110
+ }
111
+
112
+ function extractSkillCategories(name: string, description: string): string[] {
113
+ const text = `${name} ${description}`.toLowerCase();
114
+ const cats: string[] = [];
115
+ if (text.match(/search|research|data/)) cats.push("data");
116
+ if (text.match(/code|develop|build/)) cats.push("development");
117
+ if (text.match(/defi|yield|swap/)) cats.push("defi");
118
+ if (text.match(/write|content|generate/)) cats.push("content");
119
+ return cats;
120
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Virtuals ACP Source Adapter
3
+ * Searches the ACP marketplace via CLI (most reliable method)
4
+ */
5
+
6
+ import { execSync } from "child_process";
7
+ import type { SourceAdapter, UnifiedAgent, SourceSearchOptions } from "./types.js";
8
+
9
+ const ACP_CLI_PATH = "/tmp/openclaw-acp";
10
+
11
+ export const acpAdapter: SourceAdapter = {
12
+ name: "acp",
13
+ displayName: "Virtuals ACP Marketplace",
14
+
15
+ async search(query: string, options?: SourceSearchOptions): Promise<UnifiedAgent[]> {
16
+ try {
17
+ const result = execSync(
18
+ `cd ${ACP_CLI_PATH} && npx acp browse "${query}" --json 2>/dev/null`,
19
+ { timeout: options?.timeout ?? 30000, encoding: "utf-8" }
20
+ );
21
+
22
+ const agents: any[] = JSON.parse(result);
23
+ return agents.slice(0, options?.limit ?? 50).map(mapAcpAgent);
24
+ } catch {
25
+ return [];
26
+ }
27
+ },
28
+
29
+ async ping(): Promise<boolean> {
30
+ try {
31
+ execSync(`cd ${ACP_CLI_PATH} && npx acp whoami --json 2>/dev/null`, {
32
+ timeout: 10000,
33
+ encoding: "utf-8",
34
+ });
35
+ return true;
36
+ } catch {
37
+ return false;
38
+ }
39
+ },
40
+ };
41
+
42
+ function mapAcpAgent(agent: any): UnifiedAgent {
43
+ const offerings = agent.jobs ?? agent.jobOfferings ?? [];
44
+ const topOffering = offerings[0];
45
+
46
+ return {
47
+ id: `acp:${agent.id ?? agent.walletAddress}`,
48
+ nativeId: String(agent.id ?? agent.walletAddress),
49
+ name: agent.name ?? "Unknown ACP Agent",
50
+ description: agent.description ?? offerings.map((o: any) => o.description).join(". ") ?? "",
51
+ categories: extractAcpCategories(agent, offerings),
52
+ capabilities: offerings.map((o: any) => `${o.name}: ${o.description ?? ""}`),
53
+ source: "acp",
54
+ protocol: "acp",
55
+ endpoints: {
56
+ acp: {
57
+ walletAddress: agent.walletAddress ?? agent.contractAddress,
58
+ entityAddress: agent.entityAddress,
59
+ },
60
+ },
61
+ reputation: agent.metrics ? {
62
+ score: agent.metrics.successRate ?? 0,
63
+ count: agent.metrics.completedJobs ?? 0,
64
+ source: "acp",
65
+ } : undefined,
66
+ pricing: topOffering ? {
67
+ model: "escrow",
68
+ amount: String(topOffering.price ?? "0"),
69
+ currency: "USDC",
70
+ } : undefined,
71
+ verified: true, // ACP agents are registered
72
+ raw: agent,
73
+ };
74
+ }
75
+
76
+ function extractAcpCategories(agent: any, offerings: any[]): string[] {
77
+ const text = [
78
+ agent.name,
79
+ agent.description,
80
+ ...offerings.map((o: any) => `${o.name} ${o.description}`),
81
+ ].join(" ").toLowerCase();
82
+
83
+ const cats: string[] = [];
84
+ if (text.match(/defi|yield|swap|liquidity|pool/)) cats.push("defi");
85
+ if (text.match(/data|analyt|research|market/)) cats.push("data");
86
+ if (text.match(/trade|trading|price/)) cats.push("trading");
87
+ if (text.match(/risk|audit|security/)) cats.push("risk");
88
+ if (text.match(/content|image|video|write/)) cats.push("content");
89
+ if (text.match(/code|develop|build/)) cats.push("development");
90
+ return cats.length > 0 ? cats : ["general"];
91
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Agent Discovery Protocol (ADP) Source Adapter
3
+ * agentdiscovery.io — open protocol for autonomous agent commerce
4
+ */
5
+
6
+ import type { SourceAdapter, UnifiedAgent, SourceSearchOptions } from "./types.js";
7
+
8
+ const ADP_BASE = "https://agentdiscovery.io";
9
+
10
+ export const adpAdapter: SourceAdapter = {
11
+ name: "adp",
12
+ displayName: "Agent Discovery Protocol",
13
+
14
+ async search(query: string, options?: SourceSearchOptions): Promise<UnifiedAgent[]> {
15
+ try {
16
+ // Try the ADP API
17
+ const res = await fetch(`${ADP_BASE}/api/agents?q=${encodeURIComponent(query)}&limit=${options?.limit ?? 20}`, {
18
+ signal: AbortSignal.timeout(options?.timeout ?? 5000),
19
+ });
20
+
21
+ if (!res.ok) return [];
22
+
23
+ const data = await res.json();
24
+ const agents = Array.isArray(data) ? data : data.agents ?? data.data ?? [];
25
+
26
+ return agents.map((agent: any) => ({
27
+ id: `adp:${agent.id ?? agent.address}`,
28
+ nativeId: String(agent.id ?? agent.address),
29
+ name: agent.name ?? "ADP Agent",
30
+ description: agent.description ?? "",
31
+ categories: agent.categories ?? agent.tags ?? ["general"],
32
+ capabilities: agent.capabilities ?? [agent.description ?? ""],
33
+ source: "adp" as const,
34
+ protocol: (agent.protocol ?? "http") as any,
35
+ endpoints: {
36
+ http: agent.endpoint ?? agent.url,
37
+ a2a: agent.a2aEndpoint,
38
+ x402: agent.x402Endpoint,
39
+ },
40
+ reputation: agent.reputation ? {
41
+ score: agent.reputation.score ?? 0,
42
+ count: agent.reputation.count ?? 0,
43
+ source: "adp",
44
+ } : undefined,
45
+ pricing: agent.pricing,
46
+ verified: agent.verified ?? false,
47
+ raw: agent,
48
+ }));
49
+ } catch {
50
+ return [];
51
+ }
52
+ },
53
+
54
+ async ping(): Promise<boolean> {
55
+ try {
56
+ const res = await fetch(`${ADP_BASE}/api/health`, {
57
+ signal: AbortSignal.timeout(3000),
58
+ });
59
+ return res.ok;
60
+ } catch {
61
+ return false;
62
+ }
63
+ },
64
+ };
@@ -0,0 +1,166 @@
1
+ /**
2
+ * ERC-8004 On-Chain Source Adapter
3
+ * Indexes agent identities from the ERC-8004 Identity Registry on Base
4
+ */
5
+
6
+ import { createPublicClient, http, type Address, parseAbiItem } from "viem";
7
+ import { base, baseSepolia } from "viem/chains";
8
+ import type { SourceAdapter, UnifiedAgent, SourceSearchOptions } from "./types.js";
9
+
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
+ });
38
+
39
+ return {
40
+ name: "erc8004",
41
+ displayName: "ERC-8004 Identity Registry",
42
+
43
+ async search(query: string, options?: SourceSearchOptions): Promise<UnifiedAgent[]> {
44
+ const limit = options?.limit ?? 20;
45
+
46
+ 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();
60
+
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
+ }
88
+
89
+ const agent = mapErc8004Agent(tokenId, owner, metadata, network);
90
+
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
+ }
96
+
97
+ agents.push(agent);
98
+ } catch {
99
+ // Skip agents with unresolvable metadata
100
+ continue;
101
+ }
102
+ }
103
+
104
+ return agents;
105
+ } catch {
106
+ return [];
107
+ }
108
+ },
109
+
110
+ async ping(): Promise<boolean> {
111
+ try {
112
+ await client.getBlockNumber();
113
+ return true;
114
+ } catch {
115
+ return false;
116
+ }
117
+ },
118
+ };
119
+ }
120
+
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"] = {};
129
+
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
+ }
136
+
137
+ 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}`),
144
+ source: "erc8004",
145
+ protocol: endpoints.a2a ? "a2a" : endpoints.mcp ? "mcp" : endpoints.x402 ? "x402" : "onchain",
146
+ endpoints,
147
+ reputation: {
148
+ score: 0,
149
+ count: 0,
150
+ source: "erc8004",
151
+ },
152
+ verified: true,
153
+ lastSeen: Date.now(),
154
+ raw: { tokenId: tokenId.toString(), owner, metadata, network },
155
+ };
156
+ }
157
+
158
+ function extractFromDescription(text: string): string[] {
159
+ const lower = text.toLowerCase();
160
+ 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");
165
+ return cats.length > 0 ? cats : ["general"];
166
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Source Adapter Registry
3
+ * Creates and manages all source adapters for universal discovery
4
+ */
5
+
6
+ import type { SourceAdapter } from "./types.js";
7
+ import type { KompassConfig } from "../types.js";
8
+ import { mcpRegistryAdapter } from "./mcp-registry.js";
9
+ import { acpAdapter } from "./acp.js";
10
+ import { x402EcosystemAdapter } from "./x402-ecosystem.js";
11
+ import { createErc8004Adapter } from "./erc8004.js";
12
+ import { createKompassRegistryAdapter } from "./kompass-registry.js";
13
+ import { a2aWellknownAdapter } from "./a2a-wellknown.js";
14
+ import { l402DirectoryAdapter } from "./l402-directory.js";
15
+ import { adpAdapter } from "./adp.js";
16
+ import { skillsAdapter } from "./skills.js";
17
+
18
+ export interface SourceRegistryConfig {
19
+ /** Kompass SDK config (for kompass-registry adapter) */
20
+ kompassConfig?: KompassConfig;
21
+ /** Network for ERC-8004 adapter */
22
+ erc8004Network?: "base" | "base-sepolia";
23
+ /** Which sources to enable (default: all) */
24
+ enabledSources?: string[];
25
+ }
26
+
27
+ export function createAllSources(config?: SourceRegistryConfig): SourceAdapter[] {
28
+ const sources: SourceAdapter[] = [
29
+ mcpRegistryAdapter,
30
+ acpAdapter,
31
+ x402EcosystemAdapter,
32
+ createErc8004Adapter(config?.erc8004Network ?? "base-sepolia"),
33
+ a2aWellknownAdapter,
34
+ l402DirectoryAdapter,
35
+ adpAdapter,
36
+ skillsAdapter,
37
+ ];
38
+
39
+ // Add Kompass registry if config provided
40
+ if (config?.kompassConfig) {
41
+ sources.push(createKompassRegistryAdapter(config.kompassConfig));
42
+ }
43
+
44
+ // Filter to enabled sources if specified
45
+ if (config?.enabledSources) {
46
+ return sources.filter((s) => config.enabledSources!.includes(s.name));
47
+ }
48
+
49
+ return sources;
50
+ }
51
+
52
+ export { type SourceAdapter, type UnifiedAgent, type AgentSource, type AgentProtocol, type SourceSearchOptions } from "./types.js";
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Kompass Registry Source Adapter
3
+ * Wraps existing discover() function from sdk/src/discover.ts
4
+ */
5
+
6
+ import type { SourceAdapter, UnifiedAgent, SourceSearchOptions } from "./types.js";
7
+ import { discover } from "../discover.js";
8
+ import type { AgentProfile } from "../types.js";
9
+ import type { KompassConfig } from "../types.js";
10
+
11
+ export function createKompassRegistryAdapter(config: KompassConfig): SourceAdapter {
12
+ return {
13
+ name: "kompass-registry",
14
+ displayName: "Kompass Protocol Registry",
15
+
16
+ async search(query: string, options?: SourceSearchOptions): Promise<UnifiedAgent[]> {
17
+ try {
18
+ const agents = await discover(config, {
19
+ category: options?.category ?? query,
20
+ limit: options?.limit ?? 50,
21
+ });
22
+ return agents.map(mapKompassAgent);
23
+ } catch {
24
+ return [];
25
+ }
26
+ },
27
+
28
+ async ping(): Promise<boolean> {
29
+ try {
30
+ await discover(config, { limit: 1 });
31
+ return true;
32
+ } catch {
33
+ return false;
34
+ }
35
+ },
36
+ };
37
+ }
38
+
39
+ function mapKompassAgent(agent: AgentProfile): UnifiedAgent {
40
+ return {
41
+ id: `kompass-registry:${agent.id}`,
42
+ nativeId: agent.id,
43
+ name: agent.ensName || agent.id,
44
+ description: agent.description ?? "",
45
+ categories: agent.categories ? agent.categories.split(",").map((c: string) => c.trim()) : [],
46
+ capabilities: [agent.description, agent.categories].filter(Boolean) as string[],
47
+ source: "kompass-registry",
48
+ protocol: agent.x402Enabled ? "x402" : agent.endpointMcp ? "mcp" : agent.endpointA2a ? "a2a" : "onchain",
49
+ endpoints: {
50
+ mcp: agent.endpointMcp || undefined,
51
+ a2a: agent.endpointA2a || undefined,
52
+ x402: agent.endpointX402 || undefined,
53
+ },
54
+ reputation: agent.erc8004Id ? {
55
+ score: 0,
56
+ count: 0,
57
+ source: "kompass-erc8004",
58
+ } : undefined,
59
+ pricing: {
60
+ model: agent.paymentMode === "x402" ? "per-call" : agent.paymentMode === "escrow" ? "escrow" : "unknown",
61
+ amount: agent.pricingRate || undefined,
62
+ currency: agent.pricingToken || "USDC",
63
+ },
64
+ verified: agent.identityVerified,
65
+ raw: agent,
66
+ };
67
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * L402 Directory Source Adapter
3
+ * Indexes Lightning 402 endpoints from known directories
4
+ */
5
+
6
+ import type { SourceAdapter, UnifiedAgent, SourceSearchOptions } from "./types.js";
7
+
8
+ // Known L402 services (from satring, l402.directory, and community)
9
+ const KNOWN_L402_SERVICES = [
10
+ { name: "Satring", url: "https://satring.com", description: "Curated L402 + x402 API directory. 36 endpoints across 4 providers", categories: ["directory", "tools"] },
11
+ { name: "Lightning Faucet L402", url: "https://lightningfaucet.com", description: "L402 API registry and testing tools", categories: ["tools", "testing"] },
12
+ { name: "Nostr NIP-68 Bridge", url: "https://l402.nostr.com", description: "L402 payments over Nostr relay network", categories: ["social", "payments"] },
13
+ { name: "Stacker News", url: "https://stacker.news", description: "Lightning-powered news with L402 API access", categories: ["content", "data"] },
14
+ { name: "Nodana", url: "https://nodana.io", description: "L402 agentic access for Bitcoin app deployment", categories: ["development", "compute"] },
15
+ ];
16
+
17
+ export const l402DirectoryAdapter: SourceAdapter = {
18
+ name: "l402-directory",
19
+ displayName: "L402 Lightning Directory",
20
+
21
+ async search(query: string, options?: SourceSearchOptions): Promise<UnifiedAgent[]> {
22
+ const lower = query.toLowerCase();
23
+ const filtered = query
24
+ ? KNOWN_L402_SERVICES.filter(
25
+ (s) =>
26
+ s.name.toLowerCase().includes(lower) ||
27
+ s.description.toLowerCase().includes(lower) ||
28
+ s.categories.some((c) => c.includes(lower))
29
+ )
30
+ : KNOWN_L402_SERVICES;
31
+
32
+ return filtered.slice(0, options?.limit ?? 50).map((service) => ({
33
+ id: `l402-directory:${service.name.toLowerCase().replace(/\s+/g, "-")}`,
34
+ nativeId: service.name,
35
+ name: service.name,
36
+ description: service.description,
37
+ categories: service.categories,
38
+ capabilities: [service.description],
39
+ source: "l402-directory" as const,
40
+ protocol: "l402" as const,
41
+ endpoints: { l402: service.url, http: service.url },
42
+ pricing: { model: "per-call" as const, currency: "BTC/sats" },
43
+ verified: true,
44
+ raw: service,
45
+ }));
46
+ },
47
+
48
+ async ping(): Promise<boolean> {
49
+ return true; // Seed list always available
50
+ },
51
+ };