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.
- package/dist/a2a/agent-card.d.ts +13 -0
- package/dist/a2a/agent-card.d.ts.map +1 -0
- package/dist/a2a/agent-card.js +52 -0
- package/dist/a2a/agent-card.js.map +1 -0
- package/dist/a2a/bridge.d.ts +52 -0
- package/dist/a2a/bridge.d.ts.map +1 -0
- package/dist/a2a/bridge.js +123 -0
- package/dist/a2a/bridge.js.map +1 -0
- package/dist/a2a/client.d.ts +34 -0
- package/dist/a2a/client.d.ts.map +1 -0
- package/dist/a2a/client.js +65 -0
- package/dist/a2a/client.js.map +1 -0
- package/dist/a2a/server.d.ts +17 -0
- package/dist/a2a/server.d.ts.map +1 -0
- package/dist/a2a/server.js +194 -0
- package/dist/a2a/server.js.map +1 -0
- package/dist/abi.d.ts +1068 -0
- package/dist/abi.d.ts.map +1 -0
- package/dist/abi.js +1372 -0
- package/dist/abi.js.map +1 -0
- package/dist/adapters/agentkit.d.ts +41 -0
- package/dist/adapters/agentkit.d.ts.map +1 -0
- package/dist/adapters/agentkit.js +67 -0
- package/dist/adapters/agentkit.js.map +1 -0
- package/dist/adapters/generic.d.ts +35 -0
- package/dist/adapters/generic.d.ts.map +1 -0
- package/dist/adapters/generic.js +47 -0
- package/dist/adapters/generic.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/langchain.d.ts +26 -0
- package/dist/adapters/langchain.d.ts.map +1 -0
- package/dist/adapters/langchain.js +228 -0
- package/dist/adapters/langchain.js.map +1 -0
- package/dist/adapters/openclaw.d.ts +18 -0
- package/dist/adapters/openclaw.d.ts.map +1 -0
- package/dist/adapters/openclaw.js +168 -0
- package/dist/adapters/openclaw.js.map +1 -0
- package/dist/aggregator.d.ts +36 -0
- package/dist/aggregator.d.ts.map +1 -0
- package/dist/aggregator.js +168 -0
- package/dist/aggregator.js.map +1 -0
- package/dist/backends/acp.d.ts +29 -0
- package/dist/backends/acp.d.ts.map +1 -0
- package/dist/backends/acp.js +126 -0
- package/dist/backends/acp.js.map +1 -0
- package/dist/backends/types.d.ts +59 -0
- package/dist/backends/types.d.ts.map +1 -0
- package/dist/backends/types.js +2 -0
- package/dist/backends/types.js.map +1 -0
- package/dist/bridge.d.ts +35 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +192 -0
- package/dist/bridge.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +331 -0
- package/dist/cli.js.map +1 -0
- package/dist/discover.d.ts +15 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +163 -0
- package/dist/discover.js.map +1 -0
- package/dist/escrow.d.ts +45 -0
- package/dist/escrow.d.ts.map +1 -0
- package/dist/escrow.js +243 -0
- package/dist/escrow.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +145 -0
- package/dist/index.js.map +1 -0
- package/dist/intents.d.ts +28 -0
- package/dist/intents.d.ts.map +1 -0
- package/dist/intents.js +111 -0
- package/dist/intents.js.map +1 -0
- package/dist/matching.d.ts +29 -0
- package/dist/matching.d.ts.map +1 -0
- package/dist/matching.js +147 -0
- package/dist/matching.js.map +1 -0
- package/dist/pipelineAbi.d.ts +113 -0
- package/dist/pipelineAbi.d.ts.map +1 -0
- package/dist/pipelineAbi.js +74 -0
- package/dist/pipelineAbi.js.map +1 -0
- package/dist/pipelines.d.ts +42 -0
- package/dist/pipelines.d.ts.map +1 -0
- package/dist/pipelines.js +185 -0
- package/dist/pipelines.js.map +1 -0
- package/dist/registry.d.ts +36 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +187 -0
- package/dist/registry.js.map +1 -0
- package/dist/reputation.d.ts +10 -0
- package/dist/reputation.d.ts.map +1 -0
- package/dist/reputation.js +33 -0
- package/dist/reputation.js.map +1 -0
- package/dist/router.d.ts +72 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +190 -0
- package/dist/router.js.map +1 -0
- package/dist/simple.d.ts +160 -0
- package/dist/simple.d.ts.map +1 -0
- package/dist/simple.js +237 -0
- package/dist/simple.js.map +1 -0
- package/dist/sources/a2a-wellknown.d.ts +8 -0
- package/dist/sources/a2a-wellknown.d.ts.map +1 -0
- package/dist/sources/a2a-wellknown.js +104 -0
- package/dist/sources/a2a-wellknown.js.map +1 -0
- package/dist/sources/acp.d.ts +7 -0
- package/dist/sources/acp.d.ts.map +1 -0
- package/dist/sources/acp.js +86 -0
- package/dist/sources/acp.js.map +1 -0
- package/dist/sources/adp.d.ts +7 -0
- package/dist/sources/adp.d.ts.map +1 -0
- package/dist/sources/adp.js +59 -0
- package/dist/sources/adp.js.map +1 -0
- package/dist/sources/erc8004.d.ts +7 -0
- package/dist/sources/erc8004.d.ts.map +1 -0
- package/dist/sources/erc8004.js +150 -0
- package/dist/sources/erc8004.js.map +1 -0
- package/dist/sources/index.d.ts +17 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +35 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/kompass-registry.d.ts +8 -0
- package/dist/sources/kompass-registry.d.ts.map +1 -0
- package/dist/sources/kompass-registry.js +62 -0
- package/dist/sources/kompass-registry.js.map +1 -0
- package/dist/sources/l402-directory.d.ts +7 -0
- package/dist/sources/l402-directory.d.ts.map +1 -0
- package/dist/sources/l402-directory.js +42 -0
- package/dist/sources/l402-directory.js.map +1 -0
- package/dist/sources/mcp-registry.d.ts +8 -0
- package/dist/sources/mcp-registry.d.ts.map +1 -0
- package/dist/sources/mcp-registry.js +85 -0
- package/dist/sources/mcp-registry.js.map +1 -0
- package/dist/sources/skills.d.ts +8 -0
- package/dist/sources/skills.d.ts.map +1 -0
- package/dist/sources/skills.js +153 -0
- package/dist/sources/skills.js.map +1 -0
- package/dist/sources/types.d.ts +72 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +8 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/sources/x402-ecosystem.d.ts +7 -0
- package/dist/sources/x402-ecosystem.d.ts.map +1 -0
- package/dist/sources/x402-ecosystem.js +78 -0
- package/dist/sources/x402-ecosystem.js.map +1 -0
- package/dist/types.d.ts +133 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/unified.d.ts +90 -0
- package/dist/unified.d.ts.map +1 -0
- package/dist/unified.js +107 -0
- package/dist/unified.js.map +1 -0
- package/dist/x402.d.ts +30 -0
- package/dist/x402.d.ts.map +1 -0
- package/dist/x402.js +79 -0
- package/dist/x402.js.map +1 -0
- package/package.json +61 -0
- package/scripts/bootstrap-agents.mjs +246 -0
- package/src/.gitkeep +0 -0
- package/src/a2a/agent-card.ts +66 -0
- package/src/a2a/bridge.ts +168 -0
- package/src/a2a/client.ts +92 -0
- package/src/a2a/server.ts +234 -0
- package/src/abi.ts +1373 -0
- package/src/adapters/agentkit.ts +83 -0
- package/src/adapters/generic.ts +62 -0
- package/src/adapters/index.ts +4 -0
- package/src/adapters/langchain.ts +282 -0
- package/src/adapters/openclaw.ts +203 -0
- package/src/aggregator.ts +203 -0
- package/src/backends/acp.ts +199 -0
- package/src/backends/types.ts +78 -0
- package/src/bridge.ts +263 -0
- package/src/cli.ts +397 -0
- package/src/discover.ts +187 -0
- package/src/escrow.ts +284 -0
- package/src/index.ts +245 -0
- package/src/intents.ts +166 -0
- package/src/matching.ts +192 -0
- package/src/pipelineAbi.ts +74 -0
- package/src/pipelines.ts +253 -0
- package/src/registry.ts +232 -0
- package/src/reputation.ts +43 -0
- package/src/router.ts +279 -0
- package/src/simple.ts +366 -0
- package/src/sources/a2a-wellknown.ts +120 -0
- package/src/sources/acp.ts +91 -0
- package/src/sources/adp.ts +64 -0
- package/src/sources/erc8004.ts +166 -0
- package/src/sources/index.ts +52 -0
- package/src/sources/kompass-registry.ts +67 -0
- package/src/sources/l402-directory.ts +51 -0
- package/src/sources/mcp-registry.ts +104 -0
- package/src/sources/skills.ts +161 -0
- package/src/sources/types.ts +82 -0
- package/src/sources/x402-ecosystem.ts +86 -0
- package/src/types.ts +147 -0
- package/src/unified.ts +155 -0
- package/src/x402.ts +122 -0
- package/tests/pipelineFlow.test.ts +239 -0
- package/tsconfig.json +20 -0
package/src/pipelines.ts
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { type Address, type Hex, keccak256, parseEventLogs, toHex } from "viem";
|
|
2
|
+
import type { AgentProfile, KompassConfig, TxResult } from "./types.js";
|
|
3
|
+
import type { IntentRoute, AgentCapabilityRole, YieldIntent } from "./intents.js";
|
|
4
|
+
import { PipelineOrchestratorAbi, Erc20ApproveAbi } from "./pipelineAbi.js";
|
|
5
|
+
|
|
6
|
+
export type PipelineSettlementMode = "escrow" | "x402";
|
|
7
|
+
|
|
8
|
+
export interface YieldPipelineSubtask {
|
|
9
|
+
role: AgentCapabilityRole;
|
|
10
|
+
provider: Address;
|
|
11
|
+
evaluator: Address;
|
|
12
|
+
budget: bigint;
|
|
13
|
+
description: string;
|
|
14
|
+
dependencies: number[];
|
|
15
|
+
settlementMode: PipelineSettlementMode;
|
|
16
|
+
agent: AgentProfile;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface YieldPipelinePlan {
|
|
20
|
+
token: Address;
|
|
21
|
+
intentHash: Hex;
|
|
22
|
+
intentSummary: string;
|
|
23
|
+
subtasks: YieldPipelineSubtask[];
|
|
24
|
+
offchainSteps: Array<{
|
|
25
|
+
role: AgentCapabilityRole;
|
|
26
|
+
description: string;
|
|
27
|
+
endpointX402: string;
|
|
28
|
+
agent: AgentProfile;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface CreatePipelineOptions {
|
|
33
|
+
token?: Address;
|
|
34
|
+
autoApprove?: boolean;
|
|
35
|
+
autoActivate?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface CreatePipelineResult extends TxResult {
|
|
39
|
+
pipelineId: bigint;
|
|
40
|
+
approveTxHash?: Hex;
|
|
41
|
+
fundTxHash: Hex;
|
|
42
|
+
activateTxHash?: Hex;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function requireWallet(config: KompassConfig) {
|
|
46
|
+
if (!config.walletClient) {
|
|
47
|
+
throw new Error("WalletClient required for pipeline creation");
|
|
48
|
+
}
|
|
49
|
+
return config.walletClient;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function requirePipelineAddress(config: KompassConfig): Address {
|
|
53
|
+
if (!config.pipelineAddress) {
|
|
54
|
+
throw new Error("pipelineAddress is required in KompassConfig for pipeline operations");
|
|
55
|
+
}
|
|
56
|
+
return config.pipelineAddress;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function roleLabel(role: AgentCapabilityRole): string {
|
|
60
|
+
switch (role) {
|
|
61
|
+
case "research":
|
|
62
|
+
return "research";
|
|
63
|
+
case "premium-data":
|
|
64
|
+
return "premium data";
|
|
65
|
+
case "risk":
|
|
66
|
+
return "risk review";
|
|
67
|
+
case "execution":
|
|
68
|
+
return "execution";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function inferSettlementMode(agent: AgentProfile, role: AgentCapabilityRole): PipelineSettlementMode {
|
|
73
|
+
if (role === "premium-data") return "x402";
|
|
74
|
+
if (agent.paymentMode === "x402" && !agent.endpointX402) return "x402";
|
|
75
|
+
return "escrow";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function fallbackBudget(agent: AgentProfile, role: AgentCapabilityRole, intent: YieldIntent): bigint {
|
|
79
|
+
const basisPoints =
|
|
80
|
+
role === "premium-data" ? 50n :
|
|
81
|
+
role === "research" ? 125n :
|
|
82
|
+
role === "risk" ? 100n :
|
|
83
|
+
150n;
|
|
84
|
+
return (intent.amount * basisPoints) / 10_000n;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function buildYieldPipelinePlan(route: IntentRoute, options: { token: Address }): YieldPipelinePlan {
|
|
88
|
+
const riskAgent = route.steps.find((step) => step.role === "risk")?.agent;
|
|
89
|
+
const onchainSubtasks: YieldPipelineSubtask[] = [];
|
|
90
|
+
const offchainSteps: YieldPipelinePlan["offchainSteps"] = [];
|
|
91
|
+
const stepIndexByRole = new Map<AgentCapabilityRole, number>();
|
|
92
|
+
|
|
93
|
+
for (const step of route.steps) {
|
|
94
|
+
if (!step.agent) continue;
|
|
95
|
+
|
|
96
|
+
const settlementMode = inferSettlementMode(step.agent, step.role);
|
|
97
|
+
const budget = step.agent.pricingRate
|
|
98
|
+
? BigInt(step.agent.pricingRate)
|
|
99
|
+
: fallbackBudget(step.agent, step.role, route.intent);
|
|
100
|
+
|
|
101
|
+
if (settlementMode === "x402") {
|
|
102
|
+
offchainSteps.push({
|
|
103
|
+
role: step.role,
|
|
104
|
+
description: `Use ${step.agent.ensName || step.agent.id} for ${roleLabel(step.role)} over x402 before escrow execution.`,
|
|
105
|
+
endpointX402: step.agent.endpointX402,
|
|
106
|
+
agent: step.agent,
|
|
107
|
+
});
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const dependencies: number[] = [];
|
|
112
|
+
const previousResearch = stepIndexByRole.get("research");
|
|
113
|
+
const previousRisk = stepIndexByRole.get("risk");
|
|
114
|
+
|
|
115
|
+
if (step.role === "risk" && previousResearch !== undefined) {
|
|
116
|
+
dependencies.push(previousResearch);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (step.role === "execution") {
|
|
120
|
+
if (previousRisk !== undefined) {
|
|
121
|
+
dependencies.push(previousRisk);
|
|
122
|
+
} else if (previousResearch !== undefined) {
|
|
123
|
+
dependencies.push(previousResearch);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const evaluator = riskAgent?.id ?? step.agent.id;
|
|
128
|
+
|
|
129
|
+
onchainSubtasks.push({
|
|
130
|
+
role: step.role,
|
|
131
|
+
provider: step.agent.id,
|
|
132
|
+
evaluator,
|
|
133
|
+
budget,
|
|
134
|
+
description: `${step.title}: ${step.summary}`,
|
|
135
|
+
dependencies,
|
|
136
|
+
settlementMode,
|
|
137
|
+
agent: step.agent,
|
|
138
|
+
});
|
|
139
|
+
stepIndexByRole.set(step.role, onchainSubtasks.length - 1);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
token: options.token,
|
|
144
|
+
intentHash: keccak256(toHex(route.summary)),
|
|
145
|
+
intentSummary: route.summary,
|
|
146
|
+
subtasks: onchainSubtasks,
|
|
147
|
+
offchainSteps,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export async function createYieldPipeline(
|
|
152
|
+
config: KompassConfig,
|
|
153
|
+
route: IntentRoute,
|
|
154
|
+
options: CreatePipelineOptions = {}
|
|
155
|
+
): Promise<CreatePipelineResult> {
|
|
156
|
+
const wallet = requireWallet(config);
|
|
157
|
+
const pipelineAddress = requirePipelineAddress(config);
|
|
158
|
+
const token = options.token ?? config.paymentTokenAddress;
|
|
159
|
+
|
|
160
|
+
if (!token) {
|
|
161
|
+
throw new Error("paymentTokenAddress is required in KompassConfig or createYieldPipeline options");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const plan = buildYieldPipelinePlan(route, { token });
|
|
165
|
+
if (plan.subtasks.length === 0) {
|
|
166
|
+
throw new Error("No escrow-capable subtasks were generated for this intent route");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const hookAddress = config.defaultHookAddress;
|
|
170
|
+
const createTxHash = hookAddress
|
|
171
|
+
? await wallet.writeContract({
|
|
172
|
+
address: pipelineAddress,
|
|
173
|
+
abi: PipelineOrchestratorAbi,
|
|
174
|
+
functionName: "createPipelineWithHook",
|
|
175
|
+
args: [token, plan.intentHash, hookAddress],
|
|
176
|
+
})
|
|
177
|
+
: await wallet.writeContract({
|
|
178
|
+
address: pipelineAddress,
|
|
179
|
+
abi: PipelineOrchestratorAbi,
|
|
180
|
+
functionName: "createPipeline",
|
|
181
|
+
args: [token, plan.intentHash],
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const createReceipt = await config.publicClient.waitForTransactionReceipt({ hash: createTxHash });
|
|
185
|
+
const events = parseEventLogs({
|
|
186
|
+
abi: PipelineOrchestratorAbi,
|
|
187
|
+
logs: createReceipt.logs,
|
|
188
|
+
eventName: "PipelineCreated",
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
if (events.length === 0) {
|
|
192
|
+
throw new Error("PipelineCreated event not found in receipt");
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const pipelineId = events[0].args.pipelineId;
|
|
196
|
+
|
|
197
|
+
for (const subtask of plan.subtasks) {
|
|
198
|
+
const descriptionHash = keccak256(toHex(subtask.description));
|
|
199
|
+
const addTxHash = await wallet.writeContract({
|
|
200
|
+
address: pipelineAddress,
|
|
201
|
+
abi: PipelineOrchestratorAbi,
|
|
202
|
+
functionName: "addSubTask",
|
|
203
|
+
args: [
|
|
204
|
+
pipelineId,
|
|
205
|
+
subtask.provider,
|
|
206
|
+
subtask.evaluator,
|
|
207
|
+
subtask.budget,
|
|
208
|
+
descriptionHash,
|
|
209
|
+
subtask.dependencies.map((dependency) => BigInt(dependency)),
|
|
210
|
+
],
|
|
211
|
+
});
|
|
212
|
+
await config.publicClient.waitForTransactionReceipt({ hash: addTxHash });
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
let approveTxHash: Hex | undefined;
|
|
216
|
+
const totalBudget = plan.subtasks.reduce((sum, subtask) => sum + subtask.budget, 0n);
|
|
217
|
+
if (options.autoApprove ?? true) {
|
|
218
|
+
approveTxHash = await wallet.writeContract({
|
|
219
|
+
address: token,
|
|
220
|
+
abi: Erc20ApproveAbi,
|
|
221
|
+
functionName: "approve",
|
|
222
|
+
args: [pipelineAddress, totalBudget],
|
|
223
|
+
});
|
|
224
|
+
await config.publicClient.waitForTransactionReceipt({ hash: approveTxHash });
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const fundTxHash = await wallet.writeContract({
|
|
228
|
+
address: pipelineAddress,
|
|
229
|
+
abi: PipelineOrchestratorAbi,
|
|
230
|
+
functionName: "fundPipeline",
|
|
231
|
+
args: [pipelineId],
|
|
232
|
+
});
|
|
233
|
+
await config.publicClient.waitForTransactionReceipt({ hash: fundTxHash });
|
|
234
|
+
|
|
235
|
+
let activateTxHash: Hex | undefined;
|
|
236
|
+
if (options.autoActivate ?? true) {
|
|
237
|
+
activateTxHash = await wallet.writeContract({
|
|
238
|
+
address: pipelineAddress,
|
|
239
|
+
abi: PipelineOrchestratorAbi,
|
|
240
|
+
functionName: "activateNextTasks",
|
|
241
|
+
args: [pipelineId],
|
|
242
|
+
});
|
|
243
|
+
await config.publicClient.waitForTransactionReceipt({ hash: activateTxHash });
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
txHash: createTxHash,
|
|
248
|
+
pipelineId,
|
|
249
|
+
approveTxHash,
|
|
250
|
+
fundTxHash,
|
|
251
|
+
activateTxHash,
|
|
252
|
+
};
|
|
253
|
+
}
|
package/src/registry.ts
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { encodePacked, type Hex } from "viem";
|
|
2
|
+
import { KompassRegistryAbi } from "./abi.js";
|
|
3
|
+
import type { KompassConfig, RegisterProfile, TxResult } from "./types.js";
|
|
4
|
+
|
|
5
|
+
/** ENS text record key mapping */
|
|
6
|
+
const RECORD_KEYS: Record<string, string> = {
|
|
7
|
+
ensName: "com.kompass.identity.name",
|
|
8
|
+
agentType: "com.kompass.type",
|
|
9
|
+
categories: "com.kompass.categories",
|
|
10
|
+
erc8004Id: "com.kompass.erc8004.id",
|
|
11
|
+
identityVerification: "com.kompass.identity.verification",
|
|
12
|
+
paymentMode: "com.kompass.payment.mode",
|
|
13
|
+
pricingModel: "com.kompass.pricing.model",
|
|
14
|
+
pricingRate: "com.kompass.pricing.rate",
|
|
15
|
+
pricingToken: "com.kompass.pricing.token",
|
|
16
|
+
endpointMcp: "com.kompass.endpoint.mcp",
|
|
17
|
+
endpointA2a: "com.kompass.endpoint.a2a",
|
|
18
|
+
endpointX402: "com.kompass.endpoint.x402",
|
|
19
|
+
evaluatorDomains: "com.kompass.evaluator.domains",
|
|
20
|
+
description: "com.kompass.description",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** ENS L2 Resolver ABI (just setText) */
|
|
24
|
+
const resolverAbi = [
|
|
25
|
+
{
|
|
26
|
+
type: "function",
|
|
27
|
+
name: "setText",
|
|
28
|
+
inputs: [
|
|
29
|
+
{ name: "node", type: "bytes32" },
|
|
30
|
+
{ name: "key", type: "string" },
|
|
31
|
+
{ name: "value", type: "string" },
|
|
32
|
+
],
|
|
33
|
+
outputs: [],
|
|
34
|
+
stateMutability: "nonpayable",
|
|
35
|
+
},
|
|
36
|
+
] as const;
|
|
37
|
+
|
|
38
|
+
function requireWallet(config: KompassConfig) {
|
|
39
|
+
if (!config.walletClient) {
|
|
40
|
+
throw new Error("WalletClient required for write operations");
|
|
41
|
+
}
|
|
42
|
+
return config.walletClient;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ── ENSIP-25 Helpers ────────────────────────────────────
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Compute the ENSIP-25 text record key for an agent.
|
|
49
|
+
*
|
|
50
|
+
* Format: `agent-registration[<registryIdentifier>][<agentId>]`
|
|
51
|
+
* Where registryIdentifier = encodePacked(chainId, registryType, registryAddress)
|
|
52
|
+
*
|
|
53
|
+
* @see https://docs.ens.domains/ensip/25
|
|
54
|
+
*/
|
|
55
|
+
export function computeENSIP25Key(
|
|
56
|
+
chainId: bigint,
|
|
57
|
+
registryAddress: `0x${string}`,
|
|
58
|
+
agentId: string,
|
|
59
|
+
registryType: number = 0x01 // ERC-8004
|
|
60
|
+
): string {
|
|
61
|
+
const registryIdentifier = encodePacked(
|
|
62
|
+
["uint256", "uint8", "address"],
|
|
63
|
+
[chainId, registryType, registryAddress as `0x${string}`]
|
|
64
|
+
);
|
|
65
|
+
return `agent-registration[${registryIdentifier}][${agentId}]`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Set the ENSIP-25 text record on an agent's ENS name.
|
|
70
|
+
* Creates bidirectional verification: ENS name → on-chain agent identity.
|
|
71
|
+
*/
|
|
72
|
+
export async function setENSIP25Record(
|
|
73
|
+
config: KompassConfig,
|
|
74
|
+
ensNode: Hex,
|
|
75
|
+
agentId: string,
|
|
76
|
+
chainId: bigint = 84532n // Base Sepolia
|
|
77
|
+
): Promise<TxResult> {
|
|
78
|
+
const wallet = requireWallet(config);
|
|
79
|
+
|
|
80
|
+
const resolverAddress = await config.publicClient.readContract({
|
|
81
|
+
address: config.registryAddress,
|
|
82
|
+
abi: KompassRegistryAbi,
|
|
83
|
+
functionName: "resolver",
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const key = computeENSIP25Key(
|
|
87
|
+
chainId,
|
|
88
|
+
config.reputationRegistryAddress,
|
|
89
|
+
agentId
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const txHash = await wallet.writeContract({
|
|
93
|
+
address: resolverAddress,
|
|
94
|
+
abi: resolverAbi,
|
|
95
|
+
functionName: "setText",
|
|
96
|
+
args: [ensNode, key, "1"],
|
|
97
|
+
});
|
|
98
|
+
await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
99
|
+
|
|
100
|
+
return { txHash };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Register an agent with the Kompass protocol.
|
|
105
|
+
*
|
|
106
|
+
* Flow:
|
|
107
|
+
* 1. Set ENS text records on the L2 resolver (from the agent's wallet)
|
|
108
|
+
* 2. Call registerAgent(ensNode) on the registry contract
|
|
109
|
+
*
|
|
110
|
+
* The caller must own the Basename identified by ensNode.
|
|
111
|
+
*/
|
|
112
|
+
export async function register(config: KompassConfig, profile: RegisterProfile): Promise<TxResult> {
|
|
113
|
+
const wallet = requireWallet(config);
|
|
114
|
+
|
|
115
|
+
// Step 1: Read the resolver address from the registry contract
|
|
116
|
+
const resolverAddress = await config.publicClient.readContract({
|
|
117
|
+
address: config.registryAddress,
|
|
118
|
+
abi: KompassRegistryAbi,
|
|
119
|
+
functionName: "resolver",
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Step 2: Set ENS text records on the resolver
|
|
123
|
+
for (const [field, key] of Object.entries(RECORD_KEYS)) {
|
|
124
|
+
const value = profile[field as keyof RegisterProfile];
|
|
125
|
+
if (value !== undefined && typeof value === "string" && value !== "") {
|
|
126
|
+
const setTxHash = await wallet.writeContract({
|
|
127
|
+
address: resolverAddress,
|
|
128
|
+
abi: resolverAbi,
|
|
129
|
+
functionName: "setText",
|
|
130
|
+
args: [profile.ensNode, key, value],
|
|
131
|
+
});
|
|
132
|
+
await config.publicClient.waitForTransactionReceipt({ hash: setTxHash });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (profile.identityVerification) {
|
|
137
|
+
const verificationTxHash = await wallet.writeContract({
|
|
138
|
+
address: resolverAddress,
|
|
139
|
+
abi: resolverAbi,
|
|
140
|
+
functionName: "setText",
|
|
141
|
+
args: [profile.ensNode, profile.identityVerification, "verified"],
|
|
142
|
+
});
|
|
143
|
+
await config.publicClient.waitForTransactionReceipt({ hash: verificationTxHash });
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Step 3: Register the agent on the registry contract
|
|
147
|
+
const txHash = await wallet.writeContract({
|
|
148
|
+
address: config.registryAddress,
|
|
149
|
+
abi: KompassRegistryAbi,
|
|
150
|
+
functionName: "registerAgent",
|
|
151
|
+
args: [profile.ensNode],
|
|
152
|
+
});
|
|
153
|
+
await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
154
|
+
|
|
155
|
+
// Step 4: Set ENSIP-25 text record for bidirectional agent verification
|
|
156
|
+
// Uses the ERC-8004 agent ID from the profile if available
|
|
157
|
+
if (profile.erc8004Id) {
|
|
158
|
+
try {
|
|
159
|
+
await setENSIP25Record(config, profile.ensNode, profile.erc8004Id);
|
|
160
|
+
} catch (err) {
|
|
161
|
+
// Non-critical: registration succeeded, ENSIP-25 is bonus
|
|
162
|
+
console.warn("ENSIP-25 text record failed (non-critical):", err);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return { txHash };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Update an agent's ENS text records.
|
|
171
|
+
* Only updates the fields that are provided (non-undefined).
|
|
172
|
+
*/
|
|
173
|
+
export async function updateProfile(
|
|
174
|
+
config: KompassConfig,
|
|
175
|
+
ensNode: Hex,
|
|
176
|
+
updates: Partial<Omit<RegisterProfile, "ensNode">>
|
|
177
|
+
): Promise<TxResult> {
|
|
178
|
+
const wallet = requireWallet(config);
|
|
179
|
+
|
|
180
|
+
const resolverAddress = await config.publicClient.readContract({
|
|
181
|
+
address: config.registryAddress,
|
|
182
|
+
abi: KompassRegistryAbi,
|
|
183
|
+
functionName: "resolver",
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
let lastTxHash: Hex = "0x" as Hex;
|
|
187
|
+
|
|
188
|
+
for (const [field, key] of Object.entries(RECORD_KEYS)) {
|
|
189
|
+
const value = updates[field as keyof typeof updates];
|
|
190
|
+
if (value !== undefined && typeof value === "string") {
|
|
191
|
+
lastTxHash = await wallet.writeContract({
|
|
192
|
+
address: resolverAddress,
|
|
193
|
+
abi: resolverAbi,
|
|
194
|
+
functionName: "setText",
|
|
195
|
+
args: [ensNode, key, value],
|
|
196
|
+
});
|
|
197
|
+
await config.publicClient.waitForTransactionReceipt({ hash: lastTxHash });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (typeof updates.identityVerification === "string" && updates.identityVerification !== "") {
|
|
202
|
+
lastTxHash = await wallet.writeContract({
|
|
203
|
+
address: resolverAddress,
|
|
204
|
+
abi: resolverAbi,
|
|
205
|
+
functionName: "setText",
|
|
206
|
+
args: [ensNode, updates.identityVerification, "verified"],
|
|
207
|
+
});
|
|
208
|
+
await config.publicClient.waitForTransactionReceipt({ hash: lastTxHash });
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (lastTxHash === "0x") {
|
|
212
|
+
throw new Error("No fields provided to update");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return { txHash: lastTxHash };
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Deregister an agent from the protocol.
|
|
220
|
+
*/
|
|
221
|
+
export async function deregister(config: KompassConfig): Promise<TxResult> {
|
|
222
|
+
const wallet = requireWallet(config);
|
|
223
|
+
|
|
224
|
+
const txHash = await wallet.writeContract({
|
|
225
|
+
address: config.registryAddress,
|
|
226
|
+
abi: KompassRegistryAbi,
|
|
227
|
+
functionName: "deregister",
|
|
228
|
+
});
|
|
229
|
+
await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
230
|
+
|
|
231
|
+
return { txHash };
|
|
232
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Address } from "viem";
|
|
2
|
+
import { ERC8004ReputationAbi } from "./abi.js";
|
|
3
|
+
import type { KompassConfig, ReputationSummary } from "./types.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get reputation summary for an agent from the ERC-8004 Reputation Registry.
|
|
7
|
+
*
|
|
8
|
+
* @param agentId - The ERC-8004 agent ID (uint256)
|
|
9
|
+
* @param tag1 - Optional primary tag filter (e.g., "job-completed")
|
|
10
|
+
* @param tag2 - Optional secondary tag filter
|
|
11
|
+
*/
|
|
12
|
+
export async function getReputation(
|
|
13
|
+
config: KompassConfig,
|
|
14
|
+
agentId: bigint,
|
|
15
|
+
tag1: string = "",
|
|
16
|
+
tag2: string = ""
|
|
17
|
+
): Promise<ReputationSummary> {
|
|
18
|
+
// First get all clients who have given feedback
|
|
19
|
+
const clients = await config.publicClient.readContract({
|
|
20
|
+
address: config.reputationRegistryAddress,
|
|
21
|
+
abi: ERC8004ReputationAbi,
|
|
22
|
+
functionName: "getClients",
|
|
23
|
+
args: [agentId],
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if ((clients as Address[]).length === 0) {
|
|
27
|
+
return { count: 0n, summaryValue: 0n, summaryValueDecimals: 0 };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Get summary across all clients
|
|
31
|
+
const [count, summaryValue, summaryValueDecimals] = await config.publicClient.readContract({
|
|
32
|
+
address: config.reputationRegistryAddress,
|
|
33
|
+
abi: ERC8004ReputationAbi,
|
|
34
|
+
functionName: "getSummary",
|
|
35
|
+
args: [agentId, clients as Address[], tag1, tag2],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
count: BigInt(count),
|
|
40
|
+
summaryValue: BigInt(summaryValue),
|
|
41
|
+
summaryValueDecimals: Number(summaryValueDecimals),
|
|
42
|
+
};
|
|
43
|
+
}
|