kompass-sdk 0.20.0 → 0.21.1
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/aggregator.d.ts.map +1 -1
- package/dist/aggregator.js +13 -6
- package/dist/aggregator.js.map +1 -1
- package/dist/basename.d.ts +59 -0
- package/dist/basename.d.ts.map +1 -0
- package/dist/basename.js +253 -0
- package/dist/basename.js.map +1 -0
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +64 -0
- package/dist/bridge.js.map +1 -1
- package/dist/cli.js +101 -0
- package/dist/cli.js.map +1 -1
- package/dist/erc8004.d.ts +179 -0
- package/dist/erc8004.d.ts.map +1 -0
- package/dist/erc8004.js +187 -0
- package/dist/erc8004.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/matching.d.ts.map +1 -1
- package/dist/matching.js +7 -6
- package/dist/matching.js.map +1 -1
- package/dist/onboard.d.ts +132 -0
- package/dist/onboard.d.ts.map +1 -0
- package/dist/onboard.js +285 -0
- package/dist/onboard.js.map +1 -0
- package/dist/router.js +2 -2
- package/dist/router.js.map +1 -1
- package/dist/sources/acp.d.ts.map +1 -1
- package/dist/sources/acp.js +8 -7
- package/dist/sources/acp.js.map +1 -1
- package/dist/sources/bankr.d.ts.map +1 -1
- package/dist/sources/bankr.js +7 -4
- package/dist/sources/bankr.js.map +1 -1
- package/dist/sources/erc8004.js +2 -2
- package/dist/sources/erc8004.js.map +1 -1
- package/dist/sources/locus.d.ts.map +1 -1
- package/dist/sources/locus.js +4 -0
- package/dist/sources/locus.js.map +1 -1
- package/dist/sources/mcp-registry.d.ts.map +1 -1
- package/dist/sources/mcp-registry.js +6 -0
- package/dist/sources/mcp-registry.js.map +1 -1
- package/dist/sources/olas.d.ts +3 -3
- package/dist/sources/olas.d.ts.map +1 -1
- package/dist/sources/olas.js +37 -31
- package/dist/sources/olas.js.map +1 -1
- package/dist/sources/skills.d.ts.map +1 -1
- package/dist/sources/skills.js +4 -2
- package/dist/sources/skills.js.map +1 -1
- package/dist/sources/x402-ecosystem.js +1 -1
- package/dist/sources/x402-ecosystem.js.map +1 -1
- package/dist/wallet/handlers/bankr.d.ts.map +1 -1
- package/dist/wallet/handlers/bankr.js +5 -4
- package/dist/wallet/handlers/bankr.js.map +1 -1
- package/dist/wallet/handlers/locus.d.ts.map +1 -1
- package/dist/wallet/handlers/locus.js +3 -2
- package/dist/wallet/handlers/locus.js.map +1 -1
- package/dist/wallet/handlers/olas.d.ts +5 -1
- package/dist/wallet/handlers/olas.d.ts.map +1 -1
- package/dist/wallet/handlers/olas.js +20 -28
- package/dist/wallet/handlers/olas.js.map +1 -1
- package/dist/wallet/index.d.ts +20 -20
- package/package.json +1 -1
- package/src/aggregator.ts +8 -4
- package/src/basename.ts +334 -0
- package/src/bridge.ts +53 -0
- package/src/cli.ts +113 -0
- package/src/erc8004.ts +253 -0
- package/src/index.ts +12 -0
- package/src/matching.ts +7 -6
- package/src/onboard.ts +420 -0
- package/src/router.ts +2 -2
- package/src/sources/acp.ts +8 -7
- package/src/sources/bankr.ts +6 -4
- package/src/sources/erc8004.ts +2 -2
- package/src/sources/locus.ts +5 -0
- package/src/sources/mcp-registry.ts +6 -0
- package/src/sources/olas.ts +53 -44
- package/src/sources/skills.ts +5 -2
- package/src/sources/x402-ecosystem.ts +1 -1
- package/src/wallet/handlers/bankr.ts +6 -4
- package/src/wallet/handlers/locus.ts +3 -2
- package/src/wallet/handlers/olas.ts +25 -30
package/src/onboard.ts
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kompass Agent Onboarding — Full Identity Registration
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the complete flow:
|
|
5
|
+
* 1. Create wallet (free — generates keypair)
|
|
6
|
+
* 2. Register ERC-8004 identity (~$0.005 gas)
|
|
7
|
+
* 3. Register Basename (~$0.25-$2.50)
|
|
8
|
+
* 4. Set ENS text records (~$0.02 gas)
|
|
9
|
+
* 5. Register on Kompass Registry (gas only)
|
|
10
|
+
*
|
|
11
|
+
* Total cost: ~$2.55 in ETH (agent pays from their own wallet)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { Address, Hex } from "viem";
|
|
15
|
+
import { KompassWallet } from "./wallet/index.js";
|
|
16
|
+
import {
|
|
17
|
+
registerERC8004,
|
|
18
|
+
buildAgentCard,
|
|
19
|
+
ERC8004_IDENTITY_REGISTRY,
|
|
20
|
+
type RegisterERC8004Result,
|
|
21
|
+
} from "./erc8004.js";
|
|
22
|
+
import {
|
|
23
|
+
registerBasename,
|
|
24
|
+
setBasenameTextRecords,
|
|
25
|
+
basenameNode,
|
|
26
|
+
isBasenameAvailable,
|
|
27
|
+
getBasenamePrice,
|
|
28
|
+
BASENAME_REGISTRAR,
|
|
29
|
+
BASENAME_L2_RESOLVER,
|
|
30
|
+
type BasenameResult,
|
|
31
|
+
type TextRecord,
|
|
32
|
+
} from "./basename.js";
|
|
33
|
+
|
|
34
|
+
// ── Types ──────────────────────────────────────────────────
|
|
35
|
+
|
|
36
|
+
export interface OnboardOptions {
|
|
37
|
+
/** Agent name (used for Basename, e.g. "my-agent" → my-agent.base.eth) */
|
|
38
|
+
name: string;
|
|
39
|
+
/** What this agent does */
|
|
40
|
+
description: string;
|
|
41
|
+
/** e.g. ["defi", "trading", "data"] */
|
|
42
|
+
categories: string[];
|
|
43
|
+
/** What the agent can do */
|
|
44
|
+
capabilities: string[];
|
|
45
|
+
/** Agent role */
|
|
46
|
+
agentType: "provider" | "evaluator" | "both";
|
|
47
|
+
/** Reachable endpoints */
|
|
48
|
+
endpoints?: {
|
|
49
|
+
mcp?: string;
|
|
50
|
+
a2a?: string;
|
|
51
|
+
x402?: string;
|
|
52
|
+
http?: string;
|
|
53
|
+
};
|
|
54
|
+
/** How this agent gets paid */
|
|
55
|
+
pricingModel?: "escrow" | "x402" | "free";
|
|
56
|
+
/** e.g. "0.01" (USDC per task) */
|
|
57
|
+
pricingRate?: string;
|
|
58
|
+
/** Network to deploy on */
|
|
59
|
+
network?: "base" | "base-sepolia";
|
|
60
|
+
/** Skip Basename registration if agent already has a name */
|
|
61
|
+
skipBasename?: boolean;
|
|
62
|
+
/** Skip Kompass Registry (e.g. if on mainnet where registry isn't deployed) */
|
|
63
|
+
skipKompassRegistry?: boolean;
|
|
64
|
+
/** Existing wallet path (skip wallet creation) */
|
|
65
|
+
walletPath?: string;
|
|
66
|
+
/** Wallet password */
|
|
67
|
+
walletPassword?: string;
|
|
68
|
+
/** URL where the agent card JSON will be hosted */
|
|
69
|
+
agentCardUrl?: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface OnboardResult {
|
|
73
|
+
wallet: {
|
|
74
|
+
address: Address;
|
|
75
|
+
network: string;
|
|
76
|
+
keystorePath: string;
|
|
77
|
+
isNew: boolean;
|
|
78
|
+
};
|
|
79
|
+
erc8004: RegisterERC8004Result;
|
|
80
|
+
basename?: BasenameResult;
|
|
81
|
+
ensRecords: {
|
|
82
|
+
txHashes: Hex[];
|
|
83
|
+
records: Record<string, string>;
|
|
84
|
+
};
|
|
85
|
+
kompassRegistry?: {
|
|
86
|
+
txHash: Hex;
|
|
87
|
+
ensNode: Hex;
|
|
88
|
+
};
|
|
89
|
+
agentCard: {
|
|
90
|
+
name: string;
|
|
91
|
+
description: string;
|
|
92
|
+
capabilities: string[];
|
|
93
|
+
categories: string[];
|
|
94
|
+
paymentAddress: Address;
|
|
95
|
+
};
|
|
96
|
+
totalSteps: number;
|
|
97
|
+
completedSteps: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface OnboardInitResult {
|
|
101
|
+
walletAddress: Address;
|
|
102
|
+
network: string;
|
|
103
|
+
keystorePath: string;
|
|
104
|
+
fundingRequired: {
|
|
105
|
+
eth: string;
|
|
106
|
+
description: string;
|
|
107
|
+
};
|
|
108
|
+
estimatedCosts: {
|
|
109
|
+
erc8004Gas: string;
|
|
110
|
+
basename: string;
|
|
111
|
+
ensRecordsGas: string;
|
|
112
|
+
total: string;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ── Step 1: Initialize (create wallet, return funding instructions) ────
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Initialize onboarding: create wallet, estimate costs.
|
|
120
|
+
* Call this first, then fund the wallet, then call completeOnboarding().
|
|
121
|
+
*/
|
|
122
|
+
export function initOnboarding(options: OnboardOptions): OnboardInitResult {
|
|
123
|
+
const network = options.network ?? "base";
|
|
124
|
+
|
|
125
|
+
// Create or load wallet
|
|
126
|
+
let wallet: KompassWallet;
|
|
127
|
+
if (options.walletPath) {
|
|
128
|
+
wallet = KompassWallet.load(options.walletPath, options.walletPassword);
|
|
129
|
+
} else {
|
|
130
|
+
wallet = KompassWallet.create({ network, password: options.walletPassword });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const basenameEstimate = options.skipBasename
|
|
134
|
+
? "0"
|
|
135
|
+
: options.name.length >= 10
|
|
136
|
+
? "0.0001"
|
|
137
|
+
: "0.001";
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
walletAddress: wallet.getAddress(),
|
|
141
|
+
network,
|
|
142
|
+
keystorePath: options.walletPath ?? `${process.env.HOME ?? "~"}/.kompass/wallet.json`,
|
|
143
|
+
fundingRequired: {
|
|
144
|
+
eth: options.skipBasename ? "0.001" : "0.003",
|
|
145
|
+
description: `Send ETH to ${wallet.getAddress()} on Base ${network === "base" ? "mainnet" : "Sepolia"} to cover gas + basename registration`,
|
|
146
|
+
},
|
|
147
|
+
estimatedCosts: {
|
|
148
|
+
erc8004Gas: "~0.0001 ETH",
|
|
149
|
+
basename: options.skipBasename ? "skipped" : `~${basenameEstimate} ETH`,
|
|
150
|
+
ensRecordsGas: "~0.0005 ETH",
|
|
151
|
+
total: options.skipBasename ? "~0.001 ETH" : `~${(parseFloat(basenameEstimate) + 0.001).toFixed(4)} ETH`,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ── Step 2: Complete (run full registration after funding) ─────────────
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Complete the full onboarding flow. The wallet must be funded before calling this.
|
|
160
|
+
*
|
|
161
|
+
* Flow:
|
|
162
|
+
* 1. Build agent card JSON
|
|
163
|
+
* 2. Register ERC-8004 identity (mint agent NFT)
|
|
164
|
+
* 3. Register Basename (optional)
|
|
165
|
+
* 4. Set ENS text records (agent metadata)
|
|
166
|
+
* 5. Register on Kompass Registry (optional)
|
|
167
|
+
*/
|
|
168
|
+
export async function completeOnboarding(
|
|
169
|
+
options: OnboardOptions,
|
|
170
|
+
walletPathOrWallet?: string | KompassWallet,
|
|
171
|
+
): Promise<OnboardResult> {
|
|
172
|
+
const network = options.network ?? "base";
|
|
173
|
+
|
|
174
|
+
// Load or create wallet
|
|
175
|
+
let wallet: KompassWallet;
|
|
176
|
+
let isNew = false;
|
|
177
|
+
if (walletPathOrWallet instanceof KompassWallet) {
|
|
178
|
+
wallet = walletPathOrWallet;
|
|
179
|
+
} else {
|
|
180
|
+
const loadPath = walletPathOrWallet ?? options.walletPath;
|
|
181
|
+
try {
|
|
182
|
+
wallet = KompassWallet.load(loadPath, options.walletPassword);
|
|
183
|
+
} catch {
|
|
184
|
+
// Wallet doesn't exist yet — create it
|
|
185
|
+
wallet = KompassWallet.create({ path: loadPath, network, password: options.walletPassword });
|
|
186
|
+
isNew = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const address = wallet.getAddress();
|
|
191
|
+
const totalSteps = 2 + (options.skipBasename ? 0 : 1) + 1 + (options.skipKompassRegistry ? 0 : 1);
|
|
192
|
+
let completedSteps = 0;
|
|
193
|
+
|
|
194
|
+
// Check balance
|
|
195
|
+
const balance = await wallet.getBalance();
|
|
196
|
+
if (balance.ethRaw < 500000000000000n) {
|
|
197
|
+
// < 0.0005 ETH
|
|
198
|
+
throw new Error(
|
|
199
|
+
`Insufficient ETH balance: ${balance.eth} ETH. ` +
|
|
200
|
+
`Fund wallet ${address} with at least 0.003 ETH on Base ${network === "base" ? "mainnet" : "Sepolia"}.`,
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// ── Step 1: Build agent card ──────────────────────────────
|
|
205
|
+
const agentCard = buildAgentCard({
|
|
206
|
+
name: options.name,
|
|
207
|
+
description: options.description,
|
|
208
|
+
capabilities: options.capabilities,
|
|
209
|
+
categories: options.categories,
|
|
210
|
+
walletAddress: address,
|
|
211
|
+
endpoints: options.endpoints,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Determine agent card URL
|
|
215
|
+
const agentCardUrl = options.agentCardUrl ?? `https://kompasss.xyz/agents/${address}.json`;
|
|
216
|
+
completedSteps++;
|
|
217
|
+
|
|
218
|
+
// ── Step 2: Register ERC-8004 Identity ────────────────────
|
|
219
|
+
console.log(`[onboard] Registering ERC-8004 identity for ${options.name}...`);
|
|
220
|
+
const erc8004Result = await registerERC8004(wallet, agentCardUrl);
|
|
221
|
+
console.log(`[onboard] ERC-8004 identity registered: agentId=${erc8004Result.agentId}`);
|
|
222
|
+
completedSteps++;
|
|
223
|
+
|
|
224
|
+
// ── Step 3: Register Basename (optional) ──────────────────
|
|
225
|
+
let basenameResult: BasenameResult | undefined;
|
|
226
|
+
if (!options.skipBasename) {
|
|
227
|
+
console.log(`[onboard] Registering basename: ${options.name}.base.eth...`);
|
|
228
|
+
|
|
229
|
+
// Build text records to set atomically during registration
|
|
230
|
+
const textRecords: TextRecord[] = [
|
|
231
|
+
{ key: "com.kompass.type", value: options.agentType },
|
|
232
|
+
{ key: "com.kompass.categories", value: options.categories.join(",") },
|
|
233
|
+
{ key: "com.kompass.description", value: options.description },
|
|
234
|
+
{ key: "com.kompass.erc8004.id", value: erc8004Result.agentId.toString() },
|
|
235
|
+
];
|
|
236
|
+
|
|
237
|
+
if (options.endpoints?.mcp) textRecords.push({ key: "com.kompass.endpoint.mcp", value: options.endpoints.mcp });
|
|
238
|
+
if (options.endpoints?.a2a) textRecords.push({ key: "com.kompass.endpoint.a2a", value: options.endpoints.a2a });
|
|
239
|
+
if (options.endpoints?.x402) textRecords.push({ key: "com.kompass.endpoint.x402", value: options.endpoints.x402 });
|
|
240
|
+
if (options.endpoints?.http) textRecords.push({ key: "com.kompass.endpoint.http", value: options.endpoints.http });
|
|
241
|
+
if (options.pricingModel) textRecords.push({ key: "com.kompass.payment.mode", value: options.pricingModel });
|
|
242
|
+
if (options.pricingRate) textRecords.push({ key: "com.kompass.pricing.rate", value: options.pricingRate });
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
basenameResult = await registerBasename(wallet, options.name, textRecords);
|
|
246
|
+
console.log(`[onboard] Basename registered: ${basenameResult.fullName}`);
|
|
247
|
+
} catch (err: any) {
|
|
248
|
+
console.warn(`[onboard] Basename registration failed (non-critical): ${err.message}`);
|
|
249
|
+
}
|
|
250
|
+
completedSteps++;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ── Step 4: Set ENS text records (if basename was skipped or failed) ──
|
|
254
|
+
const ensRecords: Record<string, string> = {};
|
|
255
|
+
const ensRecordTxHashes: Hex[] = [];
|
|
256
|
+
|
|
257
|
+
// If basename was registered with text records, they're already set atomically.
|
|
258
|
+
// If basename failed or was skipped but we have an existing name, set records separately.
|
|
259
|
+
if (!basenameResult && basenameResult === undefined) {
|
|
260
|
+
// Try setting records on the name if it exists (maybe registered before)
|
|
261
|
+
try {
|
|
262
|
+
const { setBasenameTextRecords } = await import("./basename.js");
|
|
263
|
+
const records = [
|
|
264
|
+
{ key: "com.kompass.type", value: options.agentType },
|
|
265
|
+
{ key: "com.kompass.categories", value: options.categories.join(",") },
|
|
266
|
+
{ key: "com.kompass.description", value: options.description },
|
|
267
|
+
{ key: "com.kompass.erc8004.id", value: erc8004Result.agentId.toString() },
|
|
268
|
+
];
|
|
269
|
+
if (options.pricingModel) records.push({ key: "com.kompass.payment.mode", value: options.pricingModel });
|
|
270
|
+
if (options.pricingRate) records.push({ key: "com.kompass.pricing.rate", value: options.pricingRate });
|
|
271
|
+
|
|
272
|
+
const txHashes = await setBasenameTextRecords(wallet, options.name, records);
|
|
273
|
+
ensRecordTxHashes.push(...txHashes);
|
|
274
|
+
console.log(`[onboard] Set ${records.length} ENS text records separately`);
|
|
275
|
+
} catch (err: any) {
|
|
276
|
+
console.warn(`[onboard] Could not set ENS text records separately: ${err.message}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Always track what records we set/would set
|
|
281
|
+
ensRecords["com.kompass.type"] = options.agentType;
|
|
282
|
+
ensRecords["com.kompass.categories"] = options.categories.join(",");
|
|
283
|
+
ensRecords["com.kompass.description"] = options.description;
|
|
284
|
+
ensRecords["com.kompass.erc8004.id"] = erc8004Result.agentId.toString();
|
|
285
|
+
if (options.pricingModel) ensRecords["com.kompass.payment.mode"] = options.pricingModel;
|
|
286
|
+
if (options.pricingRate) ensRecords["com.kompass.pricing.rate"] = options.pricingRate;
|
|
287
|
+
if (options.endpoints?.mcp) ensRecords["com.kompass.endpoint.mcp"] = options.endpoints.mcp;
|
|
288
|
+
if (options.endpoints?.x402) ensRecords["com.kompass.endpoint.x402"] = options.endpoints.x402;
|
|
289
|
+
completedSteps++;
|
|
290
|
+
|
|
291
|
+
// ── Step 5: Register on Kompass Registry (optional) ───────
|
|
292
|
+
let kompassRegistryResult: { txHash: Hex; ensNode: Hex } | undefined;
|
|
293
|
+
if (!options.skipKompassRegistry && basenameResult) {
|
|
294
|
+
console.log(`[onboard] Registering on Kompass Registry...`);
|
|
295
|
+
try {
|
|
296
|
+
// Import registry dynamically to avoid circular deps
|
|
297
|
+
const { register } = await import("./registry.js");
|
|
298
|
+
const { createPublicClient, createWalletClient, http } = await import("viem");
|
|
299
|
+
const { baseSepolia } = await import("viem/chains");
|
|
300
|
+
|
|
301
|
+
// Kompass Registry is on Base Sepolia
|
|
302
|
+
const publicClient = createPublicClient({ chain: baseSepolia, transport: http("https://sepolia.base.org") });
|
|
303
|
+
const walletClient = createWalletClient({
|
|
304
|
+
account: wallet.getAccount(),
|
|
305
|
+
chain: baseSepolia,
|
|
306
|
+
transport: http("https://sepolia.base.org"),
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const config = {
|
|
310
|
+
publicClient: publicClient as any,
|
|
311
|
+
walletClient: walletClient as any,
|
|
312
|
+
escrowAddress: "0xbc003cE4bd4B272c1C25919B6b8ec379bccdE6ac" as Address,
|
|
313
|
+
registryAddress: "0x94D394362a4BA850673bEF368Ed907996287C7d7" as Address,
|
|
314
|
+
reputationRegistryAddress: "0x8004BAa17C55a88189AE136b182e5fdA19dE9b63" as Address,
|
|
315
|
+
indexerUrl: "https://kompasss.xyz/api",
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const result = await register(config, {
|
|
319
|
+
ensNode: basenameResult.node,
|
|
320
|
+
ensName: basenameResult.fullName,
|
|
321
|
+
agentType: options.agentType,
|
|
322
|
+
categories: options.categories.join(","),
|
|
323
|
+
description: options.description,
|
|
324
|
+
erc8004Id: erc8004Result.agentId.toString(),
|
|
325
|
+
pricingModel: options.pricingModel,
|
|
326
|
+
pricingRate: options.pricingRate,
|
|
327
|
+
endpointMcp: options.endpoints?.mcp,
|
|
328
|
+
endpointA2a: options.endpoints?.a2a,
|
|
329
|
+
endpointX402: options.endpoints?.x402,
|
|
330
|
+
paymentMode: options.pricingModel as any,
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
kompassRegistryResult = { txHash: result.txHash, ensNode: basenameResult.node };
|
|
334
|
+
console.log(`[onboard] Kompass Registry registration complete`);
|
|
335
|
+
} catch (err: any) {
|
|
336
|
+
console.warn(`[onboard] Kompass Registry registration failed (non-critical): ${err.message}`);
|
|
337
|
+
}
|
|
338
|
+
completedSteps++;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return {
|
|
342
|
+
wallet: {
|
|
343
|
+
address,
|
|
344
|
+
network,
|
|
345
|
+
keystorePath: options.walletPath ?? `${process.env.HOME ?? "~"}/.kompass/wallet.json`,
|
|
346
|
+
isNew,
|
|
347
|
+
},
|
|
348
|
+
erc8004: erc8004Result,
|
|
349
|
+
basename: basenameResult,
|
|
350
|
+
ensRecords: {
|
|
351
|
+
txHashes: ensRecordTxHashes,
|
|
352
|
+
records: ensRecords,
|
|
353
|
+
},
|
|
354
|
+
kompassRegistry: kompassRegistryResult,
|
|
355
|
+
agentCard,
|
|
356
|
+
totalSteps,
|
|
357
|
+
completedSteps,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// ── Convenience: Full onboard in one call ──────────────────
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Full onboarding: create wallet + register everything.
|
|
365
|
+
* Returns immediately with wallet address if funding is needed.
|
|
366
|
+
*/
|
|
367
|
+
export async function onboardAgent(options: OnboardOptions): Promise<OnboardResult> {
|
|
368
|
+
return completeOnboarding(options);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// ── Utilities ──────────────────────────────────────────────
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Check if a wallet has enough funds for onboarding.
|
|
375
|
+
*/
|
|
376
|
+
export async function checkOnboardingFunds(
|
|
377
|
+
walletPath?: string,
|
|
378
|
+
password?: string,
|
|
379
|
+
): Promise<{
|
|
380
|
+
address: Address;
|
|
381
|
+
eth: string;
|
|
382
|
+
sufficient: boolean;
|
|
383
|
+
network: string;
|
|
384
|
+
}> {
|
|
385
|
+
const wallet = KompassWallet.load(walletPath, password);
|
|
386
|
+
const balance = await wallet.getBalance();
|
|
387
|
+
|
|
388
|
+
return {
|
|
389
|
+
address: wallet.getAddress(),
|
|
390
|
+
eth: balance.eth,
|
|
391
|
+
sufficient: balance.ethRaw >= 500000000000000n, // 0.0005 ETH minimum
|
|
392
|
+
network: balance.network,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Estimate the total cost of onboarding.
|
|
398
|
+
*/
|
|
399
|
+
export async function estimateOnboardingCost(
|
|
400
|
+
name: string,
|
|
401
|
+
skipBasename: boolean = false,
|
|
402
|
+
): Promise<{
|
|
403
|
+
basename: string;
|
|
404
|
+
gas: string;
|
|
405
|
+
total: string;
|
|
406
|
+
}> {
|
|
407
|
+
const basenameEth = skipBasename
|
|
408
|
+
? 0
|
|
409
|
+
: name.length >= 10
|
|
410
|
+
? 0.0001
|
|
411
|
+
: 0.001;
|
|
412
|
+
|
|
413
|
+
const gasEstimate = 0.001; // ~$2.50 at current prices
|
|
414
|
+
|
|
415
|
+
return {
|
|
416
|
+
basename: skipBasename ? "0" : basenameEth.toString(),
|
|
417
|
+
gas: gasEstimate.toString(),
|
|
418
|
+
total: (basenameEth + gasEstimate).toFixed(4),
|
|
419
|
+
};
|
|
420
|
+
}
|
package/src/router.ts
CHANGED
|
@@ -95,9 +95,9 @@ export class CapabilityRouter {
|
|
|
95
95
|
? `${options.task}\n\nContext from previous step:\n${options.context.slice(0, 2000)}`
|
|
96
96
|
: options.task;
|
|
97
97
|
|
|
98
|
-
// 1. Search all sources
|
|
98
|
+
// 1. Search all sources — use high limit to ensure callable agents aren't cut off
|
|
99
99
|
const searchResult = await this.aggregator.search(task, {
|
|
100
|
-
limit:
|
|
100
|
+
limit: 100,
|
|
101
101
|
timeout: options.timeout ?? 15000,
|
|
102
102
|
});
|
|
103
103
|
|
package/src/sources/acp.ts
CHANGED
|
@@ -37,16 +37,17 @@ export const acpAdapter: SourceAdapter = {
|
|
|
37
37
|
return offerings.length > 0;
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
// Client-side text matching if query provided
|
|
40
|
+
// Client-side text matching if query provided (skip for browse-all)
|
|
41
41
|
let filtered = withOfferings;
|
|
42
|
-
if (query) {
|
|
42
|
+
if (query && query !== "*") {
|
|
43
43
|
const lower = query.toLowerCase();
|
|
44
44
|
const terms = lower.split(/\s+/).filter(t => t.length > 2);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
if (terms.length > 0) {
|
|
46
|
+
filtered = withOfferings.filter((a: any) => {
|
|
47
|
+
const text = `${a.name} ${a.description ?? ""} ${(a.jobs ?? a.offerings ?? []).map((o: any) => `${o.name} ${o.description ?? ""}`).join(" ")}`.toLowerCase();
|
|
48
|
+
return terms.some(t => text.includes(t));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
return filtered.slice(0, limit).map(mapAcpAgent);
|
package/src/sources/bankr.ts
CHANGED
|
@@ -27,10 +27,12 @@ export const bankrAdapter: SourceAdapter = {
|
|
|
27
27
|
async search(query: string, options?: SourceSearchOptions): Promise<UnifiedAgent[]> {
|
|
28
28
|
if (!process.env.BANKR_API_KEY) return [];
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
// Return self for browse-all queries or when query matches capabilities
|
|
31
|
+
if (query && query !== "*") {
|
|
32
|
+
const lower = query.toLowerCase();
|
|
33
|
+
const isRelevant = BANKR_CAPABILITIES.some(cap => lower.includes(cap));
|
|
34
|
+
if (!isRelevant) return [];
|
|
35
|
+
}
|
|
34
36
|
|
|
35
37
|
return [createBankrAgent()];
|
|
36
38
|
},
|
package/src/sources/erc8004.ts
CHANGED
|
@@ -20,7 +20,7 @@ export function createErc8004Adapter(network: "base" | "base-sepolia" = "base"):
|
|
|
20
20
|
try {
|
|
21
21
|
// Search across all chains on 8004scan
|
|
22
22
|
const url = new URL(`${SCAN_API}/agents`);
|
|
23
|
-
if (query) url.searchParams.set("search", query);
|
|
23
|
+
if (query && query !== "*") url.searchParams.set("search", query);
|
|
24
24
|
url.searchParams.set("limit", String(limit));
|
|
25
25
|
|
|
26
26
|
const res = await fetch(url.toString(), {
|
|
@@ -36,7 +36,7 @@ export function createErc8004Adapter(network: "base" | "base-sepolia" = "base"):
|
|
|
36
36
|
|
|
37
37
|
return agents
|
|
38
38
|
.filter((a: any) => {
|
|
39
|
-
if (!query) return true;
|
|
39
|
+
if (!query || query === "*") return true;
|
|
40
40
|
const text = `${a.name ?? ""} ${a.description ?? ""}`.toLowerCase();
|
|
41
41
|
return query.toLowerCase().split(/\s+/).some((t) => text.includes(t));
|
|
42
42
|
})
|
package/src/sources/locus.ts
CHANGED
|
@@ -89,6 +89,11 @@ export const locusAdapter: SourceAdapter = {
|
|
|
89
89
|
|
|
90
90
|
const providers = await fetchProviders(timeout);
|
|
91
91
|
|
|
92
|
+
// Return all providers for browse-all queries
|
|
93
|
+
if (!query || query === "*" || terms.length === 0) {
|
|
94
|
+
return providers.slice(0, limit).map(mapLocusProvider);
|
|
95
|
+
}
|
|
96
|
+
|
|
92
97
|
// Score each provider by relevance
|
|
93
98
|
const scored = providers.map(provider => {
|
|
94
99
|
let score = 0;
|
|
@@ -61,7 +61,13 @@ async function fetchAllServers(timeout: number): Promise<McpServer[]> {
|
|
|
61
61
|
* Much better than the registry's keyword search which only matches names.
|
|
62
62
|
*/
|
|
63
63
|
function searchLocally(servers: McpServer[], query: string, limit: number): McpServer[] {
|
|
64
|
+
// Return all for browse-all queries
|
|
65
|
+
if (!query || query === "*") {
|
|
66
|
+
return servers.slice(0, limit);
|
|
67
|
+
}
|
|
68
|
+
|
|
64
69
|
const queryTerms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 2);
|
|
70
|
+
if (queryTerms.length === 0) return servers.slice(0, limit);
|
|
65
71
|
|
|
66
72
|
return servers
|
|
67
73
|
.map((server) => {
|