@wzrd_sol/goat-plugin 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/index.mjs ADDED
@@ -0,0 +1,655 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/wzrd.plugin.ts
5
+ import { PluginBase } from "@goat-sdk/core";
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 {
11
+ static {
12
+ __name(this, "WzrdApiClient");
13
+ }
14
+ apiUrl;
15
+ // Cache auth tokens per wallet address to avoid re-auth on every tool call
16
+ tokenCache = /* @__PURE__ */ new Map();
17
+ 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
+ */
30
+ async authenticate(walletClient) {
31
+ const address = walletClient.getAddress();
32
+ const cached = this.tokenCache.get(address);
33
+ if (cached && Date.now() < cached.expiresAt - TOKEN_REFRESH_MARGIN_MS) {
34
+ return cached.token;
35
+ }
36
+ const challengeRes = await fetch(`${this.apiUrl}/v1/agent/challenge`);
37
+ if (!challengeRes.ok) {
38
+ throw new Error(`WZRD auth challenge failed: ${challengeRes.status}`);
39
+ }
40
+ const { nonce } = await challengeRes.json();
41
+ const message = `wzrd-agent-auth v1 | wallet:${address} | nonce:${nonce}`;
42
+ const { signature: sigHex } = await walletClient.signMessage(message);
43
+ const sigBytes = hexToBytes(sigHex);
44
+ const sigBase58 = toBase58(sigBytes);
45
+ const verifyRes = await fetch(`${this.apiUrl}/v1/agent/verify`, {
46
+ method: "POST",
47
+ headers: {
48
+ "Content-Type": "application/json"
49
+ },
50
+ body: JSON.stringify({
51
+ pubkey: address,
52
+ nonce,
53
+ signature: sigBase58
54
+ })
55
+ });
56
+ if (!verifyRes.ok) {
57
+ throw new Error(`WZRD auth verify failed: ${verifyRes.status} ${await verifyRes.text()}`);
58
+ }
59
+ const { token, expires_at } = await verifyRes.json();
60
+ this.tokenCache.set(address, {
61
+ token,
62
+ expiresAt: new Date(expires_at).getTime()
63
+ });
64
+ return token;
65
+ }
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;
78
+ }
79
+ while (carry > 0) {
80
+ digits.push(carry % 58);
81
+ carry = carry / 58 | 0;
82
+ }
83
+ }
84
+ let out = "";
85
+ for (const b of bytes) {
86
+ if (b !== 0) break;
87
+ out += "1";
88
+ }
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);
98
+ }
99
+ return bytes;
100
+ }
101
+ __name(hexToBytes, "hexToBytes");
102
+
103
+ // src/tools/leaderboard.ts
104
+ import { Tool } from "@goat-sdk/core";
105
+
106
+ // src/parameters.ts
107
+ import { createToolParameters } from "@goat-sdk/core";
108
+ 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")
112
+ })) {
113
+ static {
114
+ __name(this, "GetLeaderboardParameters");
115
+ }
116
+ };
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.")
127
+ })) {
128
+ static {
129
+ __name(this, "GetVelocitySignalParameters");
130
+ }
131
+ };
132
+ var GetPortfolioParameters = class extends createToolParameters(z.object({})) {
133
+ static {
134
+ __name(this, "GetPortfolioParameters");
135
+ }
136
+ };
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
+ })) {
142
+ static {
143
+ __name(this, "DepositParameters");
144
+ }
145
+ };
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
+ })) {
149
+ static {
150
+ __name(this, "ClaimParameters");
151
+ }
152
+ };
153
+
154
+ // src/tools/leaderboard.ts
155
+ function _ts_decorate(decorators, target, key, desc) {
156
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
157
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
158
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
159
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
160
+ }
161
+ __name(_ts_decorate, "_ts_decorate");
162
+ function _ts_metadata(k, v) {
163
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
164
+ }
165
+ __name(_ts_metadata, "_ts_metadata");
166
+ var LeaderboardTools = class {
167
+ static {
168
+ __name(this, "LeaderboardTools");
169
+ }
170
+ api;
171
+ constructor(api) {
172
+ this.api = api;
173
+ }
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");
187
+ 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
194
+ };
195
+ }
196
+ };
197
+ _ts_decorate([
198
+ 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."
200
+ }),
201
+ _ts_metadata("design:type", Function),
202
+ _ts_metadata("design:paramtypes", [
203
+ typeof GetLeaderboardParameters === "undefined" ? Object : GetLeaderboardParameters
204
+ ]),
205
+ _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");
213
+
214
+ // src/tools/velocity.ts
215
+ import { Tool as Tool2 } from "@goat-sdk/core";
216
+ function _ts_decorate2(decorators, target, key, desc) {
217
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
218
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
219
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
220
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
221
+ }
222
+ __name(_ts_decorate2, "_ts_decorate");
223
+ function _ts_metadata2(k, v) {
224
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
225
+ }
226
+ __name(_ts_metadata2, "_ts_metadata");
227
+ var VelocityTools = class {
228
+ static {
229
+ __name(this, "VelocityTools");
230
+ }
231
+ api;
232
+ constructor(api) {
233
+ this.api = api;
234
+ }
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
+ };
266
+ });
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
+ return {
295
+ summary: `Velocity analysis (${markets.length} markets, median ${formatVelocity2(medianVelocity)}):
296
+ ${lines.join("\n")}`,
297
+ signals: filtered,
298
+ median_velocity: medianVelocity
299
+ };
300
+ }
301
+ };
302
+ _ts_decorate2([
303
+ 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."
305
+ }),
306
+ _ts_metadata2("design:type", Function),
307
+ _ts_metadata2("design:paramtypes", [
308
+ typeof GetVelocitySignalParameters === "undefined" ? Object : GetVelocitySignalParameters
309
+ ]),
310
+ _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");
327
+
328
+ // src/tools/portfolio.ts
329
+ import { Tool as Tool3 } from "@goat-sdk/core";
330
+ import { SolanaWalletClient } from "@goat-sdk/wallet-solana";
331
+ function _ts_decorate3(decorators, target, key, desc) {
332
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
333
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
334
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
335
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
336
+ }
337
+ __name(_ts_decorate3, "_ts_decorate");
338
+ function _ts_metadata3(k, v) {
339
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
340
+ }
341
+ __name(_ts_metadata3, "_ts_metadata");
342
+ var PortfolioTools = class {
343
+ static {
344
+ __name(this, "PortfolioTools");
345
+ }
346
+ api;
347
+ constructor(api) {
348
+ this.api = api;
349
+ }
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
+ }
356
+ });
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]" : ""));
363
+ 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
371
+ };
372
+ }
373
+ };
374
+ _ts_decorate3([
375
+ 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."
377
+ }),
378
+ _ts_metadata3("design:type", Function),
379
+ _ts_metadata3("design:paramtypes", [
380
+ typeof SolanaWalletClient === "undefined" ? Object : SolanaWalletClient,
381
+ typeof GetPortfolioParameters === "undefined" ? Object : GetPortfolioParameters
382
+ ]),
383
+ _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");
393
+
394
+ // src/tools/deposit.ts
395
+ 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";
398
+ function _ts_decorate4(decorators, target, key, desc) {
399
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
400
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
401
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
402
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
403
+ }
404
+ __name(_ts_decorate4, "_ts_decorate");
405
+ function _ts_metadata4(k, v) {
406
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
407
+ }
408
+ __name(_ts_metadata4, "_ts_metadata");
409
+ var DepositTools = class {
410
+ 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) {
446
+ 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()
452
+ };
453
+ }
454
+ const solBalance = await connection.getBalance(payer);
455
+ if (solBalance < 1e4) {
456
+ return {
457
+ success: false,
458
+ error: `Insufficient SOL for tx fees: ${solBalance} lamports`,
459
+ market_id,
460
+ sol_balance_lamports: solBalance
461
+ };
462
+ }
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
+ return {
488
+ 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}`
495
+ };
496
+ }
497
+ };
498
+ _ts_decorate4([
499
+ 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."
501
+ }),
502
+ _ts_metadata4("design:type", Function),
503
+ _ts_metadata4("design:paramtypes", [
504
+ typeof SolanaWalletClient2 === "undefined" ? Object : SolanaWalletClient2,
505
+ typeof DepositParameters === "undefined" ? Object : DepositParameters
506
+ ]),
507
+ _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);
524
+ }
525
+ __name(formatUsdc2, "formatUsdc");
526
+
527
+ // src/tools/claim.ts
528
+ import { Tool as Tool5 } from "@goat-sdk/core";
529
+ import { SolanaWalletClient as SolanaWalletClient3 } from "@goat-sdk/wallet-solana";
530
+ function _ts_decorate5(decorators, target, key, desc) {
531
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
532
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
533
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
534
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
535
+ }
536
+ __name(_ts_decorate5, "_ts_decorate");
537
+ function _ts_metadata5(k, v) {
538
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
539
+ }
540
+ __name(_ts_metadata5, "_ts_metadata");
541
+ var ClaimTools = class {
542
+ static {
543
+ __name(this, "ClaimTools");
544
+ }
545
+ api;
546
+ constructor(api) {
547
+ this.api = api;
548
+ }
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
+ }
600
+ 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
608
+ };
609
+ }
610
+ };
611
+ _ts_decorate5([
612
+ 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."
614
+ }),
615
+ _ts_metadata5("design:type", Function),
616
+ _ts_metadata5("design:paramtypes", [
617
+ typeof SolanaWalletClient3 === "undefined" ? Object : SolanaWalletClient3,
618
+ typeof ClaimParameters === "undefined" ? Object : ClaimParameters
619
+ ]),
620
+ _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");
626
+
627
+ // src/wzrd.plugin.ts
628
+ var WzrdPlugin = class extends PluginBase {
629
+ static {
630
+ __name(this, "WzrdPlugin");
631
+ }
632
+ constructor(options) {
633
+ const api = new WzrdApiClient(options);
634
+ super("wzrd", [
635
+ new LeaderboardTools(api),
636
+ new VelocityTools(api),
637
+ new PortfolioTools(api),
638
+ new DepositTools(api),
639
+ new ClaimTools(api)
640
+ ]);
641
+ }
642
+ supportsChain = /* @__PURE__ */ __name((chain) => chain.type === "solana", "supportsChain");
643
+ };
644
+ var wzrd = /* @__PURE__ */ __name((options) => new WzrdPlugin(options), "wzrd");
645
+ export {
646
+ ClaimParameters,
647
+ DepositParameters,
648
+ GetLeaderboardParameters,
649
+ GetPortfolioParameters,
650
+ GetVelocitySignalParameters,
651
+ WzrdApiClient,
652
+ WzrdPlugin,
653
+ wzrd
654
+ };
655
+ //# sourceMappingURL=index.mjs.map