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/discover.ts
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import type { KompassConfig, AgentProfile, DiscoverOptions } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/** Execute a GraphQL query against the Ponder indexer */
|
|
4
|
+
async function queryIndexer<T>(config: KompassConfig, query: string, variables?: Record<string, unknown>): Promise<T> {
|
|
5
|
+
const response = await fetch(config.indexerUrl, {
|
|
6
|
+
method: "POST",
|
|
7
|
+
headers: { "Content-Type": "application/json" },
|
|
8
|
+
body: JSON.stringify({ query, variables }),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
if (!response.ok) {
|
|
12
|
+
throw new Error(`Indexer query failed: ${response.status} ${response.statusText}`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const result = await response.json() as { data?: T; errors?: Array<{ message: string }> };
|
|
16
|
+
|
|
17
|
+
if (result.errors?.length) {
|
|
18
|
+
throw new Error(`Indexer GraphQL error: ${result.errors[0].message}`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!result.data) {
|
|
22
|
+
throw new Error("Indexer returned no data");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return result.data;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Parse raw agent data from GraphQL into AgentProfile */
|
|
29
|
+
function parseAgent(raw: Record<string, unknown>): AgentProfile {
|
|
30
|
+
const paymentMode = (raw.paymentMode as AgentProfile["paymentMode"]) ?? "unknown";
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
id: raw.id as AgentProfile["id"],
|
|
34
|
+
ensNode: raw.ensNode as `0x${string}`,
|
|
35
|
+
ensName: (raw.ensName as string) ?? "",
|
|
36
|
+
agentType: (raw.agentType as AgentProfile["agentType"]) ?? "unknown",
|
|
37
|
+
categories: (raw.categories as string) ?? "",
|
|
38
|
+
pricingModel: (raw.pricingModel as string) ?? "",
|
|
39
|
+
pricingRate: (raw.pricingRate as string) ?? "",
|
|
40
|
+
pricingToken: (raw.pricingToken as string) ?? "",
|
|
41
|
+
erc8004Id: (raw.erc8004Id as string) ?? "",
|
|
42
|
+
identityVerification: (raw.identityVerification as string) ?? "",
|
|
43
|
+
identityVerified: Boolean(raw.identityVerified),
|
|
44
|
+
paymentMode,
|
|
45
|
+
endpointMcp: (raw.endpointMcp as string) ?? "",
|
|
46
|
+
endpointA2a: (raw.endpointA2a as string) ?? "",
|
|
47
|
+
endpointX402: (raw.endpointX402 as string) ?? "",
|
|
48
|
+
x402Enabled: Boolean(raw.x402Enabled),
|
|
49
|
+
evaluatorDomains: (raw.evaluatorDomains as string) ?? "",
|
|
50
|
+
description: (raw.description as string) ?? "",
|
|
51
|
+
registered: raw.registered as boolean,
|
|
52
|
+
registeredAt: BigInt(raw.registeredAt as string),
|
|
53
|
+
updatedAt: BigInt(raw.updatedAt as string),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Discover agents matching criteria via the indexer's GraphQL API.
|
|
59
|
+
* Filters by category (substring match), agent type, and registration status.
|
|
60
|
+
*/
|
|
61
|
+
export async function discover(config: KompassConfig, options: DiscoverOptions = {}): Promise<AgentProfile[]> {
|
|
62
|
+
const {
|
|
63
|
+
category,
|
|
64
|
+
evaluatorDomain,
|
|
65
|
+
agentType,
|
|
66
|
+
paymentMode,
|
|
67
|
+
requiresX402,
|
|
68
|
+
verifiedOnly,
|
|
69
|
+
limit = 50,
|
|
70
|
+
} = options;
|
|
71
|
+
|
|
72
|
+
// Build where clause for Ponder GraphQL
|
|
73
|
+
const conditions: string[] = ['registered: true'];
|
|
74
|
+
if (agentType) {
|
|
75
|
+
conditions.push(`agentType: ${agentType}`);
|
|
76
|
+
}
|
|
77
|
+
if (category) {
|
|
78
|
+
conditions.push(`categories_contains: "${category}"`);
|
|
79
|
+
}
|
|
80
|
+
if (evaluatorDomain) {
|
|
81
|
+
conditions.push(`evaluatorDomains_contains: "${evaluatorDomain}"`);
|
|
82
|
+
}
|
|
83
|
+
if (paymentMode) {
|
|
84
|
+
conditions.push(`paymentMode: "${paymentMode}"`);
|
|
85
|
+
}
|
|
86
|
+
if (requiresX402) {
|
|
87
|
+
conditions.push("x402Enabled: true");
|
|
88
|
+
}
|
|
89
|
+
if (verifiedOnly) {
|
|
90
|
+
conditions.push("identityVerified: true");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const where = conditions.length > 0 ? `where: { ${conditions.join(", ")} }` : "";
|
|
94
|
+
|
|
95
|
+
const query = `
|
|
96
|
+
query {
|
|
97
|
+
agents(${where}, limit: ${limit}) {
|
|
98
|
+
items {
|
|
99
|
+
id
|
|
100
|
+
ensNode
|
|
101
|
+
ensName
|
|
102
|
+
agentType
|
|
103
|
+
categories
|
|
104
|
+
pricingModel
|
|
105
|
+
pricingRate
|
|
106
|
+
pricingToken
|
|
107
|
+
erc8004Id
|
|
108
|
+
identityVerification
|
|
109
|
+
identityVerified
|
|
110
|
+
paymentMode
|
|
111
|
+
endpointMcp
|
|
112
|
+
endpointA2a
|
|
113
|
+
endpointX402
|
|
114
|
+
x402Enabled
|
|
115
|
+
evaluatorDomains
|
|
116
|
+
description
|
|
117
|
+
registered
|
|
118
|
+
registeredAt
|
|
119
|
+
updatedAt
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
`;
|
|
124
|
+
|
|
125
|
+
const data = await queryIndexer<{ agents: { items: Record<string, unknown>[] } }>(config, query);
|
|
126
|
+
let agents = data.agents.items.map(parseAgent);
|
|
127
|
+
|
|
128
|
+
// Client-side filtering for maxPrice (indexer stores as string)
|
|
129
|
+
if (options.maxPrice !== undefined) {
|
|
130
|
+
agents = agents.filter((a) => {
|
|
131
|
+
if (!a.pricingRate) return true;
|
|
132
|
+
try {
|
|
133
|
+
return BigInt(a.pricingRate) <= options.maxPrice!;
|
|
134
|
+
} catch {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return agents;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get a single agent's profile by address.
|
|
145
|
+
*/
|
|
146
|
+
export async function getAgent(config: KompassConfig, address: string): Promise<AgentProfile | null> {
|
|
147
|
+
const query = `
|
|
148
|
+
query {
|
|
149
|
+
agent(id: "${address.toLowerCase()}") {
|
|
150
|
+
id
|
|
151
|
+
ensNode
|
|
152
|
+
ensName
|
|
153
|
+
agentType
|
|
154
|
+
categories
|
|
155
|
+
pricingModel
|
|
156
|
+
pricingRate
|
|
157
|
+
pricingToken
|
|
158
|
+
erc8004Id
|
|
159
|
+
identityVerification
|
|
160
|
+
identityVerified
|
|
161
|
+
paymentMode
|
|
162
|
+
endpointMcp
|
|
163
|
+
endpointA2a
|
|
164
|
+
endpointX402
|
|
165
|
+
x402Enabled
|
|
166
|
+
evaluatorDomains
|
|
167
|
+
description
|
|
168
|
+
registered
|
|
169
|
+
registeredAt
|
|
170
|
+
updatedAt
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
`;
|
|
174
|
+
|
|
175
|
+
const data = await queryIndexer<{ agent: Record<string, unknown> | null }>(config, query);
|
|
176
|
+
return data.agent ? parseAgent(data.agent) : null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Find evaluators by domain specialization.
|
|
181
|
+
*/
|
|
182
|
+
export async function findEvaluator(config: KompassConfig, domain: string): Promise<AgentProfile[]> {
|
|
183
|
+
return discover(config, {
|
|
184
|
+
category: domain,
|
|
185
|
+
agentType: "evaluator",
|
|
186
|
+
});
|
|
187
|
+
}
|
package/src/escrow.ts
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { type Address, type Hex, getContract, parseEventLogs, zeroHash } from "viem";
|
|
2
|
+
import { KompassEscrowAbi } from "./abi.js";
|
|
3
|
+
import type { KompassConfig, CreateJobOptions, CreateJobResult, Job, JobStatus, MilestoneData, MilestoneStatus, TxResult } from "./types.js";
|
|
4
|
+
|
|
5
|
+
const JOB_STATUS_MAP: Record<number, JobStatus> = {
|
|
6
|
+
0: "Open",
|
|
7
|
+
1: "Funded",
|
|
8
|
+
2: "Submitted",
|
|
9
|
+
3: "Completed",
|
|
10
|
+
4: "Rejected",
|
|
11
|
+
5: "Expired",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const MILESTONE_STATUS_MAP: Record<number, MilestoneStatus> = {
|
|
15
|
+
0: "Pending",
|
|
16
|
+
1: "Submitted",
|
|
17
|
+
2: "Approved",
|
|
18
|
+
3: "Rejected",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function requireWallet(config: KompassConfig) {
|
|
22
|
+
if (!config.walletClient) {
|
|
23
|
+
throw new Error("WalletClient required for write operations");
|
|
24
|
+
}
|
|
25
|
+
return config.walletClient;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Create a new job on the escrow contract.
|
|
30
|
+
* Supports both single-deliverable and multi-milestone jobs.
|
|
31
|
+
*/
|
|
32
|
+
export async function createJob(config: KompassConfig, options: CreateJobOptions): Promise<CreateJobResult> {
|
|
33
|
+
const wallet = requireWallet(config);
|
|
34
|
+
const hook = options.hook ?? config.defaultHookAddress ?? ("0x0000000000000000000000000000000000000000" as Address);
|
|
35
|
+
|
|
36
|
+
let txHash: Hex;
|
|
37
|
+
|
|
38
|
+
if (options.milestones && options.milestones.length > 0) {
|
|
39
|
+
const shares = options.milestones.map((m) => m.budgetShareBps);
|
|
40
|
+
txHash = await wallet.writeContract({
|
|
41
|
+
address: config.escrowAddress,
|
|
42
|
+
abi: KompassEscrowAbi,
|
|
43
|
+
functionName: "createJobWithMilestones",
|
|
44
|
+
args: [
|
|
45
|
+
options.provider,
|
|
46
|
+
options.evaluator,
|
|
47
|
+
options.expiredAt,
|
|
48
|
+
options.description,
|
|
49
|
+
hook,
|
|
50
|
+
shares,
|
|
51
|
+
],
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
txHash = await wallet.writeContract({
|
|
55
|
+
address: config.escrowAddress,
|
|
56
|
+
abi: KompassEscrowAbi,
|
|
57
|
+
functionName: "createJob",
|
|
58
|
+
args: [
|
|
59
|
+
options.provider,
|
|
60
|
+
options.evaluator,
|
|
61
|
+
options.expiredAt,
|
|
62
|
+
options.description,
|
|
63
|
+
hook,
|
|
64
|
+
],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Wait for receipt and extract jobId from JobCreated event
|
|
69
|
+
const receipt = await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
70
|
+
|
|
71
|
+
const logs = parseEventLogs({
|
|
72
|
+
abi: KompassEscrowAbi,
|
|
73
|
+
logs: receipt.logs,
|
|
74
|
+
eventName: "JobCreated",
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (logs.length === 0) {
|
|
78
|
+
throw new Error("JobCreated event not found in transaction receipt");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
txHash,
|
|
83
|
+
jobId: logs[0].args.jobId,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Set the budget for an Open job.
|
|
89
|
+
*/
|
|
90
|
+
export async function setBudget(config: KompassConfig, jobId: bigint, amount: bigint): Promise<TxResult> {
|
|
91
|
+
const wallet = requireWallet(config);
|
|
92
|
+
const txHash = await wallet.writeContract({
|
|
93
|
+
address: config.escrowAddress,
|
|
94
|
+
abi: KompassEscrowAbi,
|
|
95
|
+
functionName: "setBudget",
|
|
96
|
+
args: [jobId, amount, "0x"],
|
|
97
|
+
});
|
|
98
|
+
await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
99
|
+
return { txHash };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Fund a job, transitioning it from Open to Funded.
|
|
104
|
+
* Reads the job's budget for the expectedBudget parameter.
|
|
105
|
+
* Caller must have approved the escrow contract for the budget amount first.
|
|
106
|
+
*/
|
|
107
|
+
export async function fund(config: KompassConfig, jobId: bigint): Promise<TxResult> {
|
|
108
|
+
const wallet = requireWallet(config);
|
|
109
|
+
|
|
110
|
+
// Read current budget for front-running protection
|
|
111
|
+
const jobData = await config.publicClient.readContract({
|
|
112
|
+
address: config.escrowAddress,
|
|
113
|
+
abi: KompassEscrowAbi,
|
|
114
|
+
functionName: "jobs",
|
|
115
|
+
args: [jobId],
|
|
116
|
+
});
|
|
117
|
+
const budget = jobData[4]; // budget is index 4
|
|
118
|
+
|
|
119
|
+
if (budget === 0n) {
|
|
120
|
+
throw new Error("Job budget is 0 — set budget before funding");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const txHash = await wallet.writeContract({
|
|
124
|
+
address: config.escrowAddress,
|
|
125
|
+
abi: KompassEscrowAbi,
|
|
126
|
+
functionName: "fund",
|
|
127
|
+
args: [jobId, budget, "0x"],
|
|
128
|
+
});
|
|
129
|
+
await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
130
|
+
return { txHash };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Submit a deliverable for a job or milestone.
|
|
135
|
+
* If milestoneIndex is provided, calls submitMilestone; otherwise calls submit.
|
|
136
|
+
*/
|
|
137
|
+
export async function submit(
|
|
138
|
+
config: KompassConfig,
|
|
139
|
+
jobId: bigint,
|
|
140
|
+
deliverable: Hex,
|
|
141
|
+
milestoneIndex?: number
|
|
142
|
+
): Promise<TxResult> {
|
|
143
|
+
const wallet = requireWallet(config);
|
|
144
|
+
let txHash: Hex;
|
|
145
|
+
|
|
146
|
+
if (milestoneIndex !== undefined) {
|
|
147
|
+
txHash = await wallet.writeContract({
|
|
148
|
+
address: config.escrowAddress,
|
|
149
|
+
abi: KompassEscrowAbi,
|
|
150
|
+
functionName: "submitMilestone",
|
|
151
|
+
args: [jobId, BigInt(milestoneIndex), deliverable],
|
|
152
|
+
});
|
|
153
|
+
} else {
|
|
154
|
+
txHash = await wallet.writeContract({
|
|
155
|
+
address: config.escrowAddress,
|
|
156
|
+
abi: KompassEscrowAbi,
|
|
157
|
+
functionName: "submit",
|
|
158
|
+
args: [jobId, deliverable, "0x"],
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
163
|
+
return { txHash };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Complete a job or milestone (evaluator action).
|
|
168
|
+
* If milestoneIndex is provided, calls completeMilestone; otherwise calls complete.
|
|
169
|
+
*/
|
|
170
|
+
export async function complete(
|
|
171
|
+
config: KompassConfig,
|
|
172
|
+
jobId: bigint,
|
|
173
|
+
reason?: Hex,
|
|
174
|
+
milestoneIndex?: number
|
|
175
|
+
): Promise<TxResult> {
|
|
176
|
+
const wallet = requireWallet(config);
|
|
177
|
+
const reasonHash = reason ?? zeroHash;
|
|
178
|
+
let txHash: Hex;
|
|
179
|
+
|
|
180
|
+
if (milestoneIndex !== undefined) {
|
|
181
|
+
txHash = await wallet.writeContract({
|
|
182
|
+
address: config.escrowAddress,
|
|
183
|
+
abi: KompassEscrowAbi,
|
|
184
|
+
functionName: "completeMilestone",
|
|
185
|
+
args: [jobId, BigInt(milestoneIndex), reasonHash],
|
|
186
|
+
});
|
|
187
|
+
} else {
|
|
188
|
+
txHash = await wallet.writeContract({
|
|
189
|
+
address: config.escrowAddress,
|
|
190
|
+
abi: KompassEscrowAbi,
|
|
191
|
+
functionName: "complete",
|
|
192
|
+
args: [jobId, reasonHash, "0x"],
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
197
|
+
return { txHash };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Complete a job with partial payment (evaluator action).
|
|
202
|
+
* Releases percentageBps of the budget to the provider, refunds the rest.
|
|
203
|
+
*/
|
|
204
|
+
export async function completePartial(
|
|
205
|
+
config: KompassConfig,
|
|
206
|
+
jobId: bigint,
|
|
207
|
+
percentageBps: number,
|
|
208
|
+
reason?: Hex
|
|
209
|
+
): Promise<TxResult> {
|
|
210
|
+
const wallet = requireWallet(config);
|
|
211
|
+
const reasonHash = reason ?? zeroHash;
|
|
212
|
+
|
|
213
|
+
const txHash = await wallet.writeContract({
|
|
214
|
+
address: config.escrowAddress,
|
|
215
|
+
abi: KompassEscrowAbi,
|
|
216
|
+
functionName: "completePartial",
|
|
217
|
+
args: [jobId, percentageBps, reasonHash],
|
|
218
|
+
});
|
|
219
|
+
await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
220
|
+
return { txHash };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Reject a job (client in Open state, evaluator in Funded/Submitted state).
|
|
225
|
+
*/
|
|
226
|
+
export async function reject(config: KompassConfig, jobId: bigint, reason?: Hex): Promise<TxResult> {
|
|
227
|
+
const wallet = requireWallet(config);
|
|
228
|
+
const reasonHash = reason ?? zeroHash;
|
|
229
|
+
|
|
230
|
+
const txHash = await wallet.writeContract({
|
|
231
|
+
address: config.escrowAddress,
|
|
232
|
+
abi: KompassEscrowAbi,
|
|
233
|
+
functionName: "reject",
|
|
234
|
+
args: [jobId, reasonHash, "0x"],
|
|
235
|
+
});
|
|
236
|
+
await config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
237
|
+
return { txHash };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Read a job's full data from the contract.
|
|
242
|
+
*/
|
|
243
|
+
export async function getJob(config: KompassConfig, jobId: bigint): Promise<Job> {
|
|
244
|
+
const data = await config.publicClient.readContract({
|
|
245
|
+
address: config.escrowAddress,
|
|
246
|
+
abi: KompassEscrowAbi,
|
|
247
|
+
functionName: "jobs",
|
|
248
|
+
args: [jobId],
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Solidity struct auto-getter returns a tuple:
|
|
252
|
+
// (client, provider, evaluator, hook, budget, expiredAt, status, description, deliverable, milestoneCount, currentMilestone)
|
|
253
|
+
return {
|
|
254
|
+
client: data[0] as Address,
|
|
255
|
+
provider: data[1] as Address,
|
|
256
|
+
evaluator: data[2] as Address,
|
|
257
|
+
hook: data[3] as Address,
|
|
258
|
+
budget: data[4] as bigint,
|
|
259
|
+
expiredAt: data[5] as bigint,
|
|
260
|
+
status: JOB_STATUS_MAP[Number(data[6])] ?? "Open",
|
|
261
|
+
description: data[7] as string,
|
|
262
|
+
deliverable: data[8] as Hex,
|
|
263
|
+
milestoneCount: Number(data[9]),
|
|
264
|
+
currentMilestone: Number(data[10]),
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Read milestones for a job.
|
|
270
|
+
*/
|
|
271
|
+
export async function getMilestones(config: KompassConfig, jobId: bigint): Promise<MilestoneData[]> {
|
|
272
|
+
const data = await config.publicClient.readContract({
|
|
273
|
+
address: config.escrowAddress,
|
|
274
|
+
abi: KompassEscrowAbi,
|
|
275
|
+
functionName: "getMilestones",
|
|
276
|
+
args: [jobId],
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
return (data as Array<{ budgetShareBps: number; deliverable: Hex; status: number }>).map((ms) => ({
|
|
280
|
+
budgetShareBps: Number(ms.budgetShareBps),
|
|
281
|
+
deliverable: ms.deliverable,
|
|
282
|
+
status: MILESTONE_STATUS_MAP[Number(ms.status)] ?? "Pending",
|
|
283
|
+
}));
|
|
284
|
+
}
|