@wzrd_sol/goat-plugin 0.1.0 → 0.2.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/index.mjs CHANGED
@@ -4,29 +4,55 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
4
4
  // src/wzrd.plugin.ts
5
5
  import { PluginBase } from "@goat-sdk/core";
6
6
 
7
- // src/wzrd.service.ts
8
- var DEFAULT_API_URL = "https://api.twzrd.xyz";
9
- var TOKEN_REFRESH_MARGIN_MS = 5 * 60 * 1e3;
10
- var WzrdApiClient = class {
7
+ // src/client.ts
8
+ var DEFAULT_API = "https://api.twzrd.xyz";
9
+ var TOKEN_REFRESH_MARGIN_MS = 60 * 60 * 1e3;
10
+ var B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
11
+ function toBase58(bytes) {
12
+ const digits = [
13
+ 0
14
+ ];
15
+ for (const byte of bytes) {
16
+ let carry = byte;
17
+ for (let j = 0; j < digits.length; j++) {
18
+ carry += digits[j] << 8;
19
+ digits[j] = carry % 58;
20
+ carry = carry / 58 | 0;
21
+ }
22
+ while (carry > 0) {
23
+ digits.push(carry % 58);
24
+ carry = carry / 58 | 0;
25
+ }
26
+ }
27
+ let out = "";
28
+ for (const b of bytes) {
29
+ if (b !== 0) break;
30
+ out += "1";
31
+ }
32
+ for (let i = digits.length - 1; i >= 0; i--) out += B58[digits[i]];
33
+ return out;
34
+ }
35
+ __name(toBase58, "toBase58");
36
+ function hexToBytes(hex) {
37
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
38
+ const bytes = new Uint8Array(clean.length / 2);
39
+ for (let i = 0; i < bytes.length; i++) {
40
+ bytes[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
41
+ }
42
+ return bytes;
43
+ }
44
+ __name(hexToBytes, "hexToBytes");
45
+ var WzrdClient = class {
11
46
  static {
12
- __name(this, "WzrdApiClient");
47
+ __name(this, "WzrdClient");
13
48
  }
14
49
  apiUrl;
15
- // Cache auth tokens per wallet address to avoid re-auth on every tool call
50
+ // Cache auth tokens per wallet address
16
51
  tokenCache = /* @__PURE__ */ new Map();
17
52
  constructor(options) {
18
- this.apiUrl = options?.apiUrl?.trim() || process.env.WZRD_API_URL?.trim() || DEFAULT_API_URL;
19
- }
20
- /**
21
- * Authenticate with the WZRD API using the GOAT wallet client.
22
- *
23
- * Flow:
24
- * 1. GET /v1/agent/challenge — receive nonce
25
- * 2. Sign canonical message with wallet's signMessage()
26
- * 3. POST /v1/agent/verify — receive bearer token (24h TTL)
27
- *
28
- * Returns a cached bearer token if still valid.
29
- */
53
+ this.apiUrl = options?.apiUrl?.trim() || process.env.WZRD_API_URL?.trim() || DEFAULT_API;
54
+ }
55
+ /** Ed25519 challenge → sign → verify → Bearer token */
30
56
  async authenticate(walletClient) {
31
57
  const address = walletClient.getAddress();
32
58
  const cached = this.tokenCache.get(address);
@@ -59,99 +85,171 @@ var WzrdApiClient = class {
59
85
  const { token, expires_at } = await verifyRes.json();
60
86
  this.tokenCache.set(address, {
61
87
  token,
62
- expiresAt: new Date(expires_at).getTime()
88
+ expiresAt: expires_at ? new Date(expires_at).getTime() : Date.now() + 23 * 60 * 60 * 1e3
63
89
  });
64
90
  return token;
65
91
  }
66
- };
67
- var B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
68
- function toBase58(bytes) {
69
- const digits = [
70
- 0
71
- ];
72
- for (const byte of bytes) {
73
- let carry = byte;
74
- for (let j = 0; j < digits.length; j++) {
75
- carry += digits[j] << 8;
76
- digits[j] = carry % 58;
77
- carry = carry / 58 | 0;
92
+ /** Authenticated fetch helper */
93
+ async authedFetch(walletClient, path, init) {
94
+ const token = await this.authenticate(walletClient);
95
+ const headers = new Headers(init?.headers);
96
+ headers.set("Authorization", `Bearer ${token}`);
97
+ headers.set("Content-Type", "application/json");
98
+ return fetch(`${this.apiUrl}${path}`, {
99
+ ...init,
100
+ headers
101
+ });
102
+ }
103
+ /** Pick a model from the momentum signal — returns top model name */
104
+ async pickModel(taskType) {
105
+ const res = await fetch(`${this.apiUrl}/v1/signals/momentum?limit=10&trending=true`);
106
+ if (!res.ok) throw new Error(`Momentum fetch failed: ${res.status}`);
107
+ const data = await res.json();
108
+ if (!data.models?.length) throw new Error("No models available in momentum feed");
109
+ return data.models[0].model;
110
+ }
111
+ /** Server-witnessed inference — WZRD calls the provider, grades quality */
112
+ async infer(walletClient, prompt, model, taskType) {
113
+ const resolvedModel = model || await this.pickModel(taskType);
114
+ const res = await this.authedFetch(walletClient, "/v1/agent/infer", {
115
+ method: "POST",
116
+ body: JSON.stringify({
117
+ model: resolvedModel,
118
+ prompt,
119
+ task_type: taskType || "chat"
120
+ })
121
+ });
122
+ if (!res.ok) {
123
+ const body = await res.text().catch(() => "");
124
+ throw new Error(`Infer failed (${res.status}): ${body}`);
78
125
  }
79
- while (carry > 0) {
80
- digits.push(carry % 58);
81
- carry = carry / 58 | 0;
126
+ return res.json();
127
+ }
128
+ /** Report model pick with execution_id for verified rewards */
129
+ async report(walletClient, params) {
130
+ const res = await this.authedFetch(walletClient, "/v1/agent/report", {
131
+ method: "POST",
132
+ body: JSON.stringify(params)
133
+ });
134
+ if (!res.ok) {
135
+ const body = await res.text().catch(() => "");
136
+ throw new Error(`Report failed (${res.status}): ${body}`);
82
137
  }
138
+ return res.json();
83
139
  }
84
- let out = "";
85
- for (const b of bytes) {
86
- if (b !== 0) break;
87
- out += "1";
140
+ /** Check pending + total rewards */
141
+ async getRewards(walletClient) {
142
+ const res = await this.authedFetch(walletClient, "/v1/agent/earned");
143
+ if (!res.ok) throw new Error(`Rewards check failed: ${res.status}`);
144
+ const data = await res.json();
145
+ const economy = data.economy;
146
+ const routing = data.routing;
147
+ return {
148
+ pending_ccm: Number(economy?.pending_ccm ?? 0),
149
+ total_rewarded_ccm: Number(economy?.earned_ccm ?? 0),
150
+ rank: null,
151
+ contribution_count: Number(routing?.lifetime_contributions ?? 0)
152
+ };
88
153
  }
89
- for (let i = digits.length - 1; i >= 0; i--) out += B58[digits[i]];
90
- return out;
91
- }
92
- __name(toBase58, "toBase58");
93
- function hexToBytes(hex) {
94
- const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
95
- const bytes = new Uint8Array(clean.length / 2);
96
- for (let i = 0; i < bytes.length; i++) {
97
- bytes[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
154
+ /** Gasless CCM claim via server relay */
155
+ async claimRelay(walletClient) {
156
+ const pubkey = walletClient.getAddress();
157
+ const res = await this.authedFetch(walletClient, `/v1/claims/${pubkey}/relay`, {
158
+ method: "POST"
159
+ });
160
+ if (!res.ok) {
161
+ const body = await res.text().catch(() => "");
162
+ throw new Error(`Claim relay failed (${res.status}): ${body}`);
163
+ }
164
+ return res.json();
98
165
  }
99
- return bytes;
100
- }
101
- __name(hexToBytes, "hexToBytes");
166
+ /** Check claims status */
167
+ async getClaimStatus(walletClient) {
168
+ const pubkey = walletClient.getAddress();
169
+ const res = await this.authedFetch(walletClient, `/v1/claims/${pubkey}`);
170
+ if (!res.ok) {
171
+ if (res.status === 404) {
172
+ return {
173
+ cumulative_total: 0,
174
+ claimed_total: 0,
175
+ claimable: 0
176
+ };
177
+ }
178
+ throw new Error(`Claim status failed: ${res.status}`);
179
+ }
180
+ const data = await res.json();
181
+ return {
182
+ ...data,
183
+ claimable: data.cumulative_total - data.claimed_total
184
+ };
185
+ }
186
+ /** Public: fetch leaderboard (no auth) */
187
+ async getLeaderboard(limit = 20) {
188
+ const res = await fetch(`${this.apiUrl}/v1/leaderboard?limit=${limit}`);
189
+ if (!res.ok) throw new Error(`Leaderboard failed: ${res.status}`);
190
+ return res.json();
191
+ }
192
+ };
102
193
 
103
- // src/tools/leaderboard.ts
194
+ // src/tools/infer.ts
104
195
  import { Tool } from "@goat-sdk/core";
196
+ import { SolanaWalletClient } from "@goat-sdk/wallet-solana";
105
197
 
106
198
  // src/parameters.ts
107
199
  import { createToolParameters } from "@goat-sdk/core";
108
200
  import { z } from "zod";
109
- var GetLeaderboardParameters = class extends createToolParameters(z.object({
110
- limit: z.number().int().min(1).max(50).optional().describe("Number of markets to return (default 20, max 50)"),
111
- platform: z.string().optional().describe("Filter by platform: 'huggingface', 'github', or omit for all")
201
+ var InferParameters = class extends createToolParameters(z.object({
202
+ prompt: z.string().describe("The prompt to send for inference"),
203
+ model: z.string().optional().describe("Specific model to use (e.g. 'gemini-2.5-flash'). If omitted, picks the top model from the leaderboard."),
204
+ task_type: z.enum([
205
+ "code",
206
+ "chat",
207
+ "reasoning"
208
+ ]).optional().describe("Task type for prompt classification: 'code', 'chat', or 'reasoning'. Default: 'chat'.")
112
209
  })) {
113
210
  static {
114
- __name(this, "GetLeaderboardParameters");
211
+ __name(this, "InferParameters");
115
212
  }
116
213
  };
117
- var GetVelocitySignalParameters = class extends createToolParameters(z.object({
118
- platform: z.string().optional().describe("Filter by platform: 'huggingface', 'github'"),
119
- min_signal: z.enum([
120
- "BREAKOUT",
121
- "MOMENTUM",
122
- "EMERGING",
123
- "STABLE",
124
- "COOLING",
125
- "WEAK"
126
- ]).optional().describe("Minimum signal tier to include. BREAKOUT is strongest, WEAK is lowest. Only markets at or above this tier are returned.")
214
+ var ReportParameters = class extends createToolParameters(z.object({
215
+ model_id: z.string().describe("Model ID from the infer result (e.g. 'gemini-2.5-flash')"),
216
+ execution_id: z.string().describe("Execution receipt from WZRD_INFER \u2014 required for verified rewards"),
217
+ task_type: z.enum([
218
+ "code",
219
+ "chat",
220
+ "reasoning"
221
+ ]).optional().describe("Task type matching the inference request"),
222
+ quality_score: z.number().min(0).max(1).optional().describe("Quality score from the infer result (0-1)"),
223
+ latency_ms: z.number().int().positive().optional().describe("Latency in ms from the infer result")
127
224
  })) {
128
225
  static {
129
- __name(this, "GetVelocitySignalParameters");
226
+ __name(this, "ReportParameters");
130
227
  }
131
228
  };
132
- var GetPortfolioParameters = class extends createToolParameters(z.object({})) {
229
+ var EarnParameters = class extends createToolParameters(z.object({
230
+ task_type: z.enum([
231
+ "code",
232
+ "chat",
233
+ "reasoning"
234
+ ]).optional().describe("Task type for the eval prompt: 'code', 'chat', or 'reasoning'. Default: 'code'."),
235
+ prompt: z.string().optional().describe("Custom prompt to use for inference. If omitted, a random eval prompt is selected.")
236
+ })) {
133
237
  static {
134
- __name(this, "GetPortfolioParameters");
238
+ __name(this, "EarnParameters");
135
239
  }
136
240
  };
137
- var DepositParameters = class extends createToolParameters(z.object({
138
- market_id: z.number().int().min(1).describe("Market ID to deposit into (get from wzrd_get_leaderboard)"),
139
- amount_usdc: z.number().positive().max(100).describe("Amount of USDC to deposit (e.g. 0.01). Max 100 per deposit."),
140
- priority_fee: z.number().int().positive().optional().describe("Priority fee in micro-lamports (default 50000). Higher = faster inclusion.")
141
- })) {
241
+ var ClaimParameters = class extends createToolParameters(z.object({})) {
142
242
  static {
143
- __name(this, "DepositParameters");
243
+ __name(this, "ClaimParameters");
144
244
  }
145
245
  };
146
- var ClaimParameters = class extends createToolParameters(z.object({
147
- execute: z.boolean().optional().describe("If false, only check claimable amount without executing. Default true.")
148
- })) {
246
+ var RewardsParameters = class extends createToolParameters(z.object({})) {
149
247
  static {
150
- __name(this, "ClaimParameters");
248
+ __name(this, "RewardsParameters");
151
249
  }
152
250
  };
153
251
 
154
- // src/tools/leaderboard.ts
252
+ // src/tools/infer.ts
155
253
  function _ts_decorate(decorators, target, key, desc) {
156
254
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
157
255
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -163,56 +261,44 @@ function _ts_metadata(k, v) {
163
261
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
164
262
  }
165
263
  __name(_ts_metadata, "_ts_metadata");
166
- var LeaderboardTools = class {
264
+ var InferTools = class {
167
265
  static {
168
- __name(this, "LeaderboardTools");
266
+ __name(this, "InferTools");
169
267
  }
170
- api;
171
- constructor(api) {
172
- this.api = api;
268
+ client;
269
+ constructor(client) {
270
+ this.client = client;
173
271
  }
174
- async wzrd_get_leaderboard(parameters) {
175
- const limit = parameters.limit ?? 20;
176
- const params = new URLSearchParams({
177
- limit: String(limit)
178
- });
179
- if (parameters.platform) params.set("platform", parameters.platform);
180
- const res = await fetch(`${this.api.apiUrl}/v1/leaderboard?${params}`);
181
- if (!res.ok) {
182
- throw new Error(`Leaderboard request failed: ${res.status}`);
183
- }
184
- const data = await res.json();
185
- const markets = data.markets ?? [];
186
- const summary = markets.map((m, i) => `${i + 1}. ${m.metric} \u2014 ${formatVelocity(m.velocity_ema)} velocity (${m.platform}) | ${m.multiplier_bps / 1e4}x multiplier | ${m.position_count} positions | market_id=${m.market_id}`).join("\n");
272
+ async wzrd_infer(walletClient, parameters) {
273
+ const { prompt, model, task_type } = parameters;
274
+ const taskType = task_type || "chat";
275
+ const result = await this.client.infer(walletClient, prompt, model, taskType);
187
276
  return {
188
- summary: `WZRD Leaderboard (${markets.length} markets, root_seq=${data.root?.root_seq ?? "N/A"}):
189
- ${summary}`,
190
- markets,
191
- root: data.root,
192
- total_positions: data.total_positions,
193
- total_tvl_usdc: data.total_tvl_usdc
277
+ summary: `Inference complete. Model: ${result.model} (${result.provider}), quality: ${result.quality_score.toFixed(2)}, ${result.latency_ms}ms. execution_id: ${result.execution_id}`,
278
+ execution_id: result.execution_id,
279
+ model: result.model,
280
+ provider: result.provider,
281
+ quality_score: result.quality_score,
282
+ latency_ms: result.latency_ms,
283
+ response_preview: result.response.slice(0, 300)
194
284
  };
195
285
  }
196
286
  };
197
287
  _ts_decorate([
198
288
  Tool({
199
- description: "Fetch the WZRD attention market leaderboard. Shows AI models and open-source projects ranked by real-time velocity (download/star momentum). Returns market IDs, velocity EMA, multiplier, TVL, and platform. Use this to find the highest-attention markets before depositing."
289
+ description: "Run server-witnessed inference through WZRD. The server calls the AI provider, grades quality, and returns an execution receipt (execution_id). Use the execution_id with wzrd_report to earn verified CCM rewards. If no model is specified, picks the top model from the leaderboard."
200
290
  }),
201
291
  _ts_metadata("design:type", Function),
202
292
  _ts_metadata("design:paramtypes", [
203
- typeof GetLeaderboardParameters === "undefined" ? Object : GetLeaderboardParameters
293
+ typeof SolanaWalletClient === "undefined" ? Object : SolanaWalletClient,
294
+ typeof InferParameters === "undefined" ? Object : InferParameters
204
295
  ]),
205
296
  _ts_metadata("design:returntype", Promise)
206
- ], LeaderboardTools.prototype, "wzrd_get_leaderboard", null);
207
- function formatVelocity(v) {
208
- if (v >= 1e6) return `${(v / 1e6).toFixed(1)}M`;
209
- if (v >= 1e3) return `${(v / 1e3).toFixed(0)}K`;
210
- return v.toFixed(0);
211
- }
212
- __name(formatVelocity, "formatVelocity");
297
+ ], InferTools.prototype, "wzrd_infer", null);
213
298
 
214
- // src/tools/velocity.ts
299
+ // src/tools/report.ts
215
300
  import { Tool as Tool2 } from "@goat-sdk/core";
301
+ import { SolanaWalletClient as SolanaWalletClient2 } from "@goat-sdk/wallet-solana";
216
302
  function _ts_decorate2(decorators, target, key, desc) {
217
303
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
218
304
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -224,110 +310,46 @@ function _ts_metadata2(k, v) {
224
310
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
225
311
  }
226
312
  __name(_ts_metadata2, "_ts_metadata");
227
- var VelocityTools = class {
313
+ var ReportTools = class {
228
314
  static {
229
- __name(this, "VelocityTools");
315
+ __name(this, "ReportTools");
230
316
  }
231
- api;
232
- constructor(api) {
233
- this.api = api;
317
+ client;
318
+ constructor(client) {
319
+ this.client = client;
234
320
  }
235
- async wzrd_get_velocity_signal(parameters) {
236
- const params = new URLSearchParams({
237
- limit: "50"
238
- });
239
- if (parameters.platform) params.set("platform", parameters.platform);
240
- const res = await fetch(`${this.api.apiUrl}/v1/leaderboard?${params}`);
241
- if (!res.ok) {
242
- throw new Error(`Leaderboard request failed: ${res.status}`);
243
- }
244
- const data = await res.json();
245
- const markets = data.markets ?? [];
246
- if (markets.length === 0) {
247
- return {
248
- summary: "No markets found.",
249
- signals: []
250
- };
251
- }
252
- const sorted = [
253
- ...markets
254
- ].sort((a, b) => a.velocity_ema - b.velocity_ema);
255
- const signals = markets.map((m) => {
256
- const rank = sorted.findIndex((s) => s.market_id === m.market_id);
257
- const percentile = (rank + 1) / sorted.length * 100;
258
- return {
259
- market_id: m.market_id,
260
- metric: m.metric,
261
- platform: m.platform,
262
- velocity_ema: m.velocity_ema,
263
- signal: classify(m, percentile),
264
- percentile: Math.round(percentile)
265
- };
321
+ async wzrd_report(walletClient, parameters) {
322
+ const result = await this.client.report(walletClient, {
323
+ model_id: parameters.model_id,
324
+ execution_id: parameters.execution_id,
325
+ task_type: parameters.task_type,
326
+ quality_score: parameters.quality_score,
327
+ latency_ms: parameters.latency_ms
266
328
  });
267
- const tierOrder = [
268
- "BREAKOUT",
269
- "MOMENTUM",
270
- "EMERGING",
271
- "STABLE",
272
- "COOLING",
273
- "WEAK"
274
- ];
275
- const minIdx = parameters.min_signal ? tierOrder.indexOf(parameters.min_signal) : tierOrder.length;
276
- const filtered = minIdx < tierOrder.length ? signals.filter((s) => tierOrder.indexOf(s.signal) <= minIdx) : signals;
277
- const grouped = /* @__PURE__ */ new Map();
278
- for (const s of filtered) {
279
- const arr = grouped.get(s.signal) ?? [];
280
- arr.push(s);
281
- grouped.set(s.signal, arr);
282
- }
283
- const lines = [];
284
- for (const tier of tierOrder) {
285
- const group = grouped.get(tier);
286
- if (!group?.length) continue;
287
- lines.push(`${tier}:`);
288
- for (const s of group) {
289
- lines.push(` ${s.metric} (${formatVelocity2(s.velocity_ema)} velocity, p${s.percentile}) [${s.platform}]`);
290
- }
291
- }
292
- const medianIdx = Math.floor(sorted.length / 2);
293
- const medianVelocity = sorted[medianIdx]?.velocity_ema ?? 0;
294
329
  return {
295
- summary: `Velocity analysis (${markets.length} markets, median ${formatVelocity2(medianVelocity)}):
296
- ${lines.join("\n")}`,
297
- signals: filtered,
298
- median_velocity: medianVelocity
330
+ summary: `Reported to WZRD. Verification: ${result.verification_state}, contribution #${result.contribution_id}, model: ${result.model_id}` + (result.quality_score != null ? `, quality: ${result.quality_score.toFixed(2)}` : ""),
331
+ contribution_id: result.contribution_id,
332
+ verification_state: result.verification_state,
333
+ quality_score: result.quality_score,
334
+ model_id: result.model_id
299
335
  };
300
336
  }
301
337
  };
302
338
  _ts_decorate2([
303
339
  Tool2({
304
- description: "Analyze attention velocity across WZRD markets. Classifies each market into signal tiers: BREAKOUT (top 10%), MOMENTUM (70-90th percentile), EMERGING (new + above median), STABLE, COOLING, WEAK. Use this to find the best deposit opportunities \u2014 BREAKOUT and MOMENTUM markets have the strongest attention momentum."
340
+ description: "Report a model pick to WZRD with an execution_id from wzrd_infer. Verified reports earn CCM rewards with a quality multiplier. Requires: model_id and execution_id (both from wzrd_infer result)."
305
341
  }),
306
342
  _ts_metadata2("design:type", Function),
307
343
  _ts_metadata2("design:paramtypes", [
308
- typeof GetVelocitySignalParameters === "undefined" ? Object : GetVelocitySignalParameters
344
+ typeof SolanaWalletClient2 === "undefined" ? Object : SolanaWalletClient2,
345
+ typeof ReportParameters === "undefined" ? Object : ReportParameters
309
346
  ]),
310
347
  _ts_metadata2("design:returntype", Promise)
311
- ], VelocityTools.prototype, "wzrd_get_velocity_signal", null);
312
- function classify(m, percentile) {
313
- if (percentile >= 90) return "BREAKOUT";
314
- if (percentile >= 70) return "MOMENTUM";
315
- if (m.snapshot_count < 300 && percentile >= 50) return "EMERGING";
316
- if (percentile >= 40) return "STABLE";
317
- if (percentile >= 20) return "COOLING";
318
- return "WEAK";
319
- }
320
- __name(classify, "classify");
321
- function formatVelocity2(v) {
322
- if (v >= 1e6) return `${(v / 1e6).toFixed(1)}M`;
323
- if (v >= 1e3) return `${(v / 1e3).toFixed(0)}K`;
324
- return v.toFixed(0);
325
- }
326
- __name(formatVelocity2, "formatVelocity");
348
+ ], ReportTools.prototype, "wzrd_report", null);
327
349
 
328
- // src/tools/portfolio.ts
350
+ // src/tools/earn.ts
329
351
  import { Tool as Tool3 } from "@goat-sdk/core";
330
- import { SolanaWalletClient } from "@goat-sdk/wallet-solana";
352
+ import { SolanaWalletClient as SolanaWalletClient3 } from "@goat-sdk/wallet-solana";
331
353
  function _ts_decorate3(decorators, target, key, desc) {
332
354
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
333
355
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -339,62 +361,94 @@ function _ts_metadata3(k, v) {
339
361
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
340
362
  }
341
363
  __name(_ts_metadata3, "_ts_metadata");
342
- var PortfolioTools = class {
364
+ var EVAL_PROMPTS = {
365
+ code: [
366
+ "Write a Python function that checks if a binary tree is balanced. Include time complexity analysis.",
367
+ "Implement a thread-safe LRU cache in Rust with O(1) get and put operations.",
368
+ "Write a TypeScript generic function that deep-merges two objects, handling arrays and nested objects."
369
+ ],
370
+ chat: [
371
+ "Explain the difference between TCP and UDP to someone who has never programmed before.",
372
+ "What are the tradeoffs between microservices and monolithic architecture?",
373
+ "Describe how consensus works in proof-of-stake blockchains."
374
+ ],
375
+ reasoning: [
376
+ "A farmer has a fox, a chicken, and a bag of grain. He must cross a river in a boat that can only carry him and one item. How does he do it?",
377
+ "If it takes 5 machines 5 minutes to make 5 widgets, how long does it take 100 machines to make 100 widgets?",
378
+ "Three people check into a hotel room that costs $30. They each pay $10. The manager realizes the room should cost $25 and gives $5 to the bellboy to return. The bellboy keeps $2 and gives $1 back to each person. So each person paid $9 (total $27) plus the bellboy kept $2 (total $29). Where is the missing dollar?"
379
+ ]
380
+ };
381
+ function pickPrompt(taskType) {
382
+ const prompts = EVAL_PROMPTS[taskType] || EVAL_PROMPTS.chat;
383
+ return prompts[Math.floor(Math.random() * prompts.length)];
384
+ }
385
+ __name(pickPrompt, "pickPrompt");
386
+ var EarnTools = class {
343
387
  static {
344
- __name(this, "PortfolioTools");
388
+ __name(this, "EarnTools");
345
389
  }
346
- api;
347
- constructor(api) {
348
- this.api = api;
390
+ client;
391
+ constructor(client) {
392
+ this.client = client;
349
393
  }
350
- async wzrd_get_portfolio(walletClient, parameters) {
351
- const token = await this.api.authenticate(walletClient);
352
- const res = await fetch(`${this.api.apiUrl}/v1/portfolio`, {
353
- headers: {
354
- Authorization: `Bearer ${token}`
355
- }
394
+ async wzrd_earn(walletClient, parameters) {
395
+ const taskType = parameters.task_type || "code";
396
+ const prompt = parameters.prompt || pickPrompt(taskType);
397
+ const steps = [];
398
+ steps.push("-> Picking model from leaderboard...");
399
+ const model = await this.client.pickModel(taskType);
400
+ steps.push(`-> Running inference: ${model} (${taskType})...`);
401
+ const infer = await this.client.infer(walletClient, prompt, model, taskType);
402
+ steps.push(`OK Inference: ${infer.model} (${infer.provider}), quality ${infer.quality_score.toFixed(2)}, ${infer.latency_ms}ms`);
403
+ steps.push("-> Reporting outcome...");
404
+ const report = await this.client.report(walletClient, {
405
+ model_id: infer.model,
406
+ execution_id: infer.execution_id,
407
+ task_type: taskType,
408
+ quality_score: infer.quality_score,
409
+ latency_ms: infer.latency_ms
356
410
  });
357
- if (!res.ok) {
358
- throw new Error(`Portfolio request failed: ${res.status}`);
359
- }
360
- const portfolio = await res.json();
361
- const positions = portfolio.positions ?? [];
362
- const lines = positions.map((p) => `Market #${p.market_id} (${p.metric}): ${formatUsdc(p.usdc_deposited)} USDC, ${formatUsdc(p.vlofi_minted)} vLOFI, ${p.multiplier_bps / 1e4}x multiplier` + (p.is_settled ? " [SETTLED]" : ""));
411
+ steps.push(`OK Reported: ${report.verification_state}, contribution #${report.contribution_id}`);
412
+ steps.push("-> Checking rewards...");
413
+ const rewards = await this.client.getRewards(walletClient);
414
+ steps.push(`OK Rewards: ${(rewards.pending_ccm / 1e9).toFixed(2)} CCM pending, ${(rewards.total_rewarded_ccm / 1e9).toFixed(2)} CCM lifetime`);
363
415
  return {
364
- summary: `Portfolio (${positions.length} positions):
365
- ${lines.join("\n")}
366
- Total: ${formatUsdc(portfolio.total_deposited_usdc)} USDC deposited, ${formatUsdc(portfolio.total_vlofi)} vLOFI, ${formatCcm(portfolio.total_ccm_earned)} CCM earned`,
367
- positions,
368
- total_deposited_usdc: portfolio.total_deposited_usdc,
369
- total_vlofi: portfolio.total_vlofi,
370
- total_ccm_earned: portfolio.total_ccm_earned
416
+ summary: `Earn cycle complete:
417
+ ${steps.join("\n")}`,
418
+ infer: {
419
+ execution_id: infer.execution_id,
420
+ model: infer.model,
421
+ provider: infer.provider,
422
+ quality_score: infer.quality_score,
423
+ latency_ms: infer.latency_ms
424
+ },
425
+ report: {
426
+ contribution_id: report.contribution_id,
427
+ verification_state: report.verification_state
428
+ },
429
+ rewards: {
430
+ pending_ccm: rewards.pending_ccm,
431
+ total_rewarded_ccm: rewards.total_rewarded_ccm,
432
+ contribution_count: rewards.contribution_count
433
+ }
371
434
  };
372
435
  }
373
436
  };
374
437
  _ts_decorate3([
375
438
  Tool3({
376
- description: "View your WZRD portfolio \u2014 all positions, vLOFI balances, and CCM earned. Shows each market you're deposited in, your multiplier, settlement status, and aggregate totals. Use this to decide when to claim or deposit more."
439
+ description: "Run the full WZRD earn cycle: pick a prompt, run server-witnessed inference, report the outcome, and check pending rewards. One tool call, complete loop. Earns verified CCM rewards on Solana. Use task_type to control prompt category (code/chat/reasoning) or provide a custom prompt."
377
440
  }),
378
441
  _ts_metadata3("design:type", Function),
379
442
  _ts_metadata3("design:paramtypes", [
380
- typeof SolanaWalletClient === "undefined" ? Object : SolanaWalletClient,
381
- typeof GetPortfolioParameters === "undefined" ? Object : GetPortfolioParameters
443
+ typeof SolanaWalletClient3 === "undefined" ? Object : SolanaWalletClient3,
444
+ typeof EarnParameters === "undefined" ? Object : EarnParameters
382
445
  ]),
383
446
  _ts_metadata3("design:returntype", Promise)
384
- ], PortfolioTools.prototype, "wzrd_get_portfolio", null);
385
- function formatUsdc(nativeAmount) {
386
- return (Number(nativeAmount) / 1e6).toFixed(4);
387
- }
388
- __name(formatUsdc, "formatUsdc");
389
- function formatCcm(nativeAmount) {
390
- return (Number(nativeAmount) / 1e6).toFixed(4);
391
- }
392
- __name(formatCcm, "formatCcm");
447
+ ], EarnTools.prototype, "wzrd_earn", null);
393
448
 
394
- // src/tools/deposit.ts
449
+ // src/tools/claim.ts
395
450
  import { Tool as Tool4 } from "@goat-sdk/core";
396
- import { SolanaWalletClient as SolanaWalletClient2 } from "@goat-sdk/wallet-solana";
397
- import { ComputeBudgetProgram, PublicKey } from "@solana/web3.js";
451
+ import { SolanaWalletClient as SolanaWalletClient4 } from "@goat-sdk/wallet-solana";
398
452
  function _ts_decorate4(decorators, target, key, desc) {
399
453
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
400
454
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -406,127 +460,64 @@ function _ts_metadata4(k, v) {
406
460
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
407
461
  }
408
462
  __name(_ts_metadata4, "_ts_metadata");
409
- var DepositTools = class {
463
+ var ClaimTools = class {
410
464
  static {
411
- __name(this, "DepositTools");
412
- }
413
- api;
414
- constructor(api) {
415
- this.api = api;
416
- }
417
- async wzrd_deposit(walletClient, parameters) {
418
- const { market_id, amount_usdc, priority_fee = 5e4 } = parameters;
419
- const connection = walletClient.getConnection();
420
- const payer = new PublicKey(walletClient.getAddress());
421
- const amountNative = BigInt(Math.round(amount_usdc * 1e6));
422
- const t0 = Date.now();
423
- const sdk = await loadSdk();
424
- const { createDepositMarketIx, fetchMarketVault, fetchOnChainPosition, fetchTokenBalance, getAta, TOKEN_PROGRAM_ID } = sdk;
425
- const vault = await fetchMarketVault(connection, market_id);
426
- if (!vault) {
427
- return {
428
- success: false,
429
- error: `Market ${market_id} is listed but does not have an on-chain vault yet. Pick a market with an initialized vault before depositing.`,
430
- market_id,
431
- reason: "missing_vault"
432
- };
433
- }
434
- const existing = await fetchOnChainPosition(connection, payer, market_id);
435
- if (existing && existing.depositedAmount > 0n && !existing.settled) {
436
- return {
437
- success: false,
438
- error: `Position already exists in market ${market_id}. Cannot double-deposit.`,
439
- market_id,
440
- deposited_amount: existing.depositedAmount.toString()
441
- };
442
- }
443
- const usdcAta = getAta(payer, vault.depositMint, TOKEN_PROGRAM_ID);
444
- const usdcBalance = await fetchTokenBalance(connection, usdcAta);
445
- if (usdcBalance < amountNative) {
465
+ __name(this, "ClaimTools");
466
+ }
467
+ client;
468
+ constructor(client) {
469
+ this.client = client;
470
+ }
471
+ async wzrd_claim(walletClient, _parameters) {
472
+ const status = await this.client.getClaimStatus(walletClient);
473
+ if (status.claimable <= 0) {
446
474
  return {
447
- success: false,
448
- error: `Insufficient USDC: have ${formatUsdc2(usdcBalance)}, need ${amount_usdc.toFixed(4)}`,
449
- market_id,
450
- required_native: amountNative.toString(),
451
- balance_native: usdcBalance.toString()
475
+ success: true,
476
+ summary: `No CCM to claim right now. Cumulative: ${formatCcm(status.cumulative_total)} CCM, already claimed: ${formatCcm(status.claimed_total)} CCM. Run wzrd_earn first to accrue rewards.`,
477
+ claimable: 0,
478
+ cumulative_total: status.cumulative_total,
479
+ claimed_total: status.claimed_total
452
480
  };
453
481
  }
454
- const solBalance = await connection.getBalance(payer);
455
- if (solBalance < 1e4) {
482
+ const result = await this.client.claimRelay(walletClient);
483
+ if (result.status === "already_claimed") {
456
484
  return {
457
- success: false,
458
- error: `Insufficient SOL for tx fees: ${solBalance} lamports`,
459
- market_id,
460
- sol_balance_lamports: solBalance
485
+ success: true,
486
+ summary: `Already claimed through root ${result.root_seq}.`,
487
+ already_claimed: true,
488
+ root_seq: result.root_seq
461
489
  };
462
490
  }
463
- let ixs;
464
- try {
465
- ixs = await createDepositMarketIx(connection, payer, market_id, amountNative);
466
- } catch (error) {
467
- const message = error instanceof Error ? error.message : String(error);
468
- if (message.includes("MarketVault not found")) {
469
- return {
470
- success: false,
471
- error: `Market ${market_id} vault not found on-chain.`,
472
- market_id,
473
- reason: "missing_vault"
474
- };
475
- }
476
- throw error;
477
- }
478
- ixs.unshift(ComputeBudgetProgram.setComputeUnitLimit({
479
- units: 3e5
480
- }), ComputeBudgetProgram.setComputeUnitPrice({
481
- microLamports: priority_fee
482
- }));
483
- const { hash } = await walletClient.sendTransaction({
484
- instructions: ixs
485
- });
486
- const elapsed = Date.now() - t0;
487
491
  return {
488
492
  success: true,
489
- summary: `Deposited ${amount_usdc.toFixed(4)} USDC into Market #${market_id}. Tx: ${hash.slice(0, 16)}... (${elapsed}ms)`,
490
- signature: hash,
491
- market_id,
492
- amount_usdc,
493
- elapsed_ms: elapsed,
494
- explorer: `https://solscan.io/tx/${hash}`
493
+ summary: `Claimed CCM via gasless relay. Cumulative: ${formatCcm(result.cumulative_total)} CCM. Root seq: ${result.root_seq}. Tx: ${result.tx_sig?.slice(0, 16)}...`,
494
+ cumulative_total: result.cumulative_total,
495
+ root_seq: result.root_seq,
496
+ tx_sig: result.tx_sig,
497
+ claimable_before: status.claimable,
498
+ explorer: result.tx_sig ? `https://orbmarkets.io/tx/${result.tx_sig}` : null
495
499
  };
496
500
  }
497
501
  };
498
502
  _ts_decorate4([
499
503
  Tool4({
500
- description: "Deposit USDC into a WZRD attention market to mint vLOFI tokens. vLOFI represents your position in the market. As the underlying AI model gains attention (downloads, stars), your multiplier increases and you earn more CCM on each merkle root publication. Requires: market_id (from wzrd_get_leaderboard) and amount_usdc. The deposit is atomic \u2014 USDC is transferred and vLOFI is minted in one transaction."
504
+ description: "Claim accrued CCM tokens via gasless relay. The server pays transaction fees \u2014 no SOL needed. CCM accrues from verified inference reports (wzrd_earn/wzrd_report). Call this periodically to harvest earned CCM to your wallet."
501
505
  }),
502
506
  _ts_metadata4("design:type", Function),
503
507
  _ts_metadata4("design:paramtypes", [
504
- typeof SolanaWalletClient2 === "undefined" ? Object : SolanaWalletClient2,
505
- typeof DepositParameters === "undefined" ? Object : DepositParameters
508
+ typeof SolanaWalletClient4 === "undefined" ? Object : SolanaWalletClient4,
509
+ typeof ClaimParameters === "undefined" ? Object : ClaimParameters
506
510
  ]),
507
511
  _ts_metadata4("design:returntype", Promise)
508
- ], DepositTools.prototype, "wzrd_deposit", null);
509
- async function loadSdk() {
510
- try {
511
- return await import("@wzrd_sol/sdk");
512
- } catch (error) {
513
- const fallbackUrl = new URL("../../../../../sdk/dist/index.js", import.meta.url);
514
- try {
515
- return await import(fallbackUrl.href);
516
- } catch {
517
- throw error;
518
- }
519
- }
520
- }
521
- __name(loadSdk, "loadSdk");
522
- function formatUsdc2(nativeAmount) {
523
- return (Number(nativeAmount) / 1e6).toFixed(4);
512
+ ], ClaimTools.prototype, "wzrd_claim", null);
513
+ function formatCcm(nativeAmount) {
514
+ return (Number(nativeAmount) / 1e9).toFixed(2);
524
515
  }
525
- __name(formatUsdc2, "formatUsdc");
516
+ __name(formatCcm, "formatCcm");
526
517
 
527
- // src/tools/claim.ts
518
+ // src/tools/rewards.ts
528
519
  import { Tool as Tool5 } from "@goat-sdk/core";
529
- import { SolanaWalletClient as SolanaWalletClient3 } from "@goat-sdk/wallet-solana";
520
+ import { SolanaWalletClient as SolanaWalletClient5 } from "@goat-sdk/wallet-solana";
530
521
  function _ts_decorate5(decorators, target, key, desc) {
531
522
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
532
523
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -538,91 +529,36 @@ function _ts_metadata5(k, v) {
538
529
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
539
530
  }
540
531
  __name(_ts_metadata5, "_ts_metadata");
541
- var ClaimTools = class {
532
+ var RewardsTools = class {
542
533
  static {
543
- __name(this, "ClaimTools");
534
+ __name(this, "RewardsTools");
544
535
  }
545
- api;
546
- constructor(api) {
547
- this.api = api;
536
+ client;
537
+ constructor(client) {
538
+ this.client = client;
548
539
  }
549
- async wzrd_claim(walletClient, parameters) {
550
- const pubkey = walletClient.getAddress();
551
- const token = await this.api.authenticate(walletClient);
552
- const claimsRes = await fetch(`${this.api.apiUrl}/v1/claims/${pubkey}`, {
553
- headers: {
554
- Authorization: `Bearer ${token}`
555
- }
556
- });
557
- if (!claimsRes.ok) {
558
- throw new Error(`Claims check failed: ${claimsRes.status}`);
559
- }
560
- const claims = await claimsRes.json();
561
- const claimable = claims.cumulative_total - claims.claimed_total;
562
- if (claimable <= 0) {
563
- return {
564
- success: true,
565
- summary: `No CCM to claim. Cumulative: ${formatCcm2(claims.cumulative_total)}, already claimed: ${formatCcm2(claims.claimed_total)}.`,
566
- claimable: 0,
567
- cumulative_total: claims.cumulative_total,
568
- claimed_total: claims.claimed_total
569
- };
570
- }
571
- if (parameters.execute === false) {
572
- return {
573
- success: true,
574
- summary: `${formatCcm2(claimable)} CCM claimable (${formatCcm2(claims.cumulative_total)} cumulative, ${formatCcm2(claims.claimed_total)} claimed). Root seq: ${claims.root_seq}. Set execute=true to claim.`,
575
- claimable,
576
- cumulative_total: claims.cumulative_total,
577
- claimed_total: claims.claimed_total,
578
- root_seq: claims.root_seq
579
- };
580
- }
581
- const relayRes = await fetch(`${this.api.apiUrl}/v1/claims/${pubkey}/relay`, {
582
- method: "POST",
583
- headers: {
584
- Authorization: `Bearer ${token}`,
585
- "Content-Type": "application/json"
586
- }
587
- });
588
- if (!relayRes.ok) {
589
- throw new Error(`Relay claim failed: ${relayRes.status} ${await relayRes.text()}`);
590
- }
591
- const result = await relayRes.json();
592
- if (result.status === "already_claimed") {
593
- return {
594
- success: true,
595
- summary: `Already claimed through root ${result.root_seq}. Claimed total: ${formatCcm2(result.claimed_total ?? claims.claimed_total)} CCM.`,
596
- already_claimed: true,
597
- root_seq: result.root_seq
598
- };
599
- }
540
+ async wzrd_rewards(walletClient, _parameters) {
541
+ const rewards = await this.client.getRewards(walletClient);
600
542
  return {
601
- success: true,
602
- summary: `Claimed CCM via gasless relay. Cumulative: ${formatCcm2(result.cumulative_total)}. Root seq: ${result.root_seq}. Tx: ${result.tx_sig?.slice(0, 16)}...`,
603
- cumulative_total: result.cumulative_total,
604
- root_seq: result.root_seq,
605
- tx_sig: result.tx_sig,
606
- claimable_before: claimable,
607
- explorer: result.tx_sig ? `https://solscan.io/tx/${result.tx_sig}` : null
543
+ summary: `WZRD Rewards: ${(rewards.pending_ccm / 1e9).toFixed(2)} CCM pending, ${(rewards.total_rewarded_ccm / 1e9).toFixed(2)} CCM lifetime, ${rewards.contribution_count} contributions` + (rewards.rank ? `, rank #${rewards.rank}` : ""),
544
+ pending_ccm: rewards.pending_ccm,
545
+ total_rewarded_ccm: rewards.total_rewarded_ccm,
546
+ contribution_count: rewards.contribution_count,
547
+ rank: rewards.rank
608
548
  };
609
549
  }
610
550
  };
611
551
  _ts_decorate5([
612
552
  Tool5({
613
- description: "Claim accrued CCM tokens from your WZRD positions. Uses the gasless relay \u2014 the server pays transaction fees, so you don't need SOL to claim. CCM accrues based on your velocity multiplier and is distributed via merkle proofs published on-chain every ~10 minutes. Set execute=false to check claimable amount without claiming."
553
+ description: "Check your pending CCM rewards, lifetime total, and contribution count. Use this to see how much you've earned from WZRD inference before claiming."
614
554
  }),
615
555
  _ts_metadata5("design:type", Function),
616
556
  _ts_metadata5("design:paramtypes", [
617
- typeof SolanaWalletClient3 === "undefined" ? Object : SolanaWalletClient3,
618
- typeof ClaimParameters === "undefined" ? Object : ClaimParameters
557
+ typeof SolanaWalletClient5 === "undefined" ? Object : SolanaWalletClient5,
558
+ typeof RewardsParameters === "undefined" ? Object : RewardsParameters
619
559
  ]),
620
560
  _ts_metadata5("design:returntype", Promise)
621
- ], ClaimTools.prototype, "wzrd_claim", null);
622
- function formatCcm2(nativeAmount) {
623
- return (Number(nativeAmount) / 1e6).toFixed(4);
624
- }
625
- __name(formatCcm2, "formatCcm");
561
+ ], RewardsTools.prototype, "wzrd_rewards", null);
626
562
 
627
563
  // src/wzrd.plugin.ts
628
564
  var WzrdPlugin = class extends PluginBase {
@@ -630,13 +566,13 @@ var WzrdPlugin = class extends PluginBase {
630
566
  __name(this, "WzrdPlugin");
631
567
  }
632
568
  constructor(options) {
633
- const api = new WzrdApiClient(options);
569
+ const client = new WzrdClient(options);
634
570
  super("wzrd", [
635
- new LeaderboardTools(api),
636
- new VelocityTools(api),
637
- new PortfolioTools(api),
638
- new DepositTools(api),
639
- new ClaimTools(api)
571
+ new EarnTools(client),
572
+ new InferTools(client),
573
+ new ReportTools(client),
574
+ new ClaimTools(client),
575
+ new RewardsTools(client)
640
576
  ]);
641
577
  }
642
578
  supportsChain = /* @__PURE__ */ __name((chain) => chain.type === "solana", "supportsChain");
@@ -644,11 +580,11 @@ var WzrdPlugin = class extends PluginBase {
644
580
  var wzrd = /* @__PURE__ */ __name((options) => new WzrdPlugin(options), "wzrd");
645
581
  export {
646
582
  ClaimParameters,
647
- DepositParameters,
648
- GetLeaderboardParameters,
649
- GetPortfolioParameters,
650
- GetVelocitySignalParameters,
651
- WzrdApiClient,
583
+ EarnParameters,
584
+ InferParameters,
585
+ ReportParameters,
586
+ RewardsParameters,
587
+ WzrdClient,
652
588
  WzrdPlugin,
653
589
  wzrd
654
590
  };