@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.js ADDED
@@ -0,0 +1,698 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ ClaimParameters: () => ClaimParameters,
35
+ DepositParameters: () => DepositParameters,
36
+ GetLeaderboardParameters: () => GetLeaderboardParameters,
37
+ GetPortfolioParameters: () => GetPortfolioParameters,
38
+ GetVelocitySignalParameters: () => GetVelocitySignalParameters,
39
+ WzrdApiClient: () => WzrdApiClient,
40
+ WzrdPlugin: () => WzrdPlugin,
41
+ wzrd: () => wzrd
42
+ });
43
+ module.exports = __toCommonJS(index_exports);
44
+
45
+ // src/wzrd.plugin.ts
46
+ var import_core7 = require("@goat-sdk/core");
47
+
48
+ // src/wzrd.service.ts
49
+ var DEFAULT_API_URL = "https://api.twzrd.xyz";
50
+ var TOKEN_REFRESH_MARGIN_MS = 5 * 60 * 1e3;
51
+ var WzrdApiClient = class {
52
+ static {
53
+ __name(this, "WzrdApiClient");
54
+ }
55
+ apiUrl;
56
+ // Cache auth tokens per wallet address to avoid re-auth on every tool call
57
+ tokenCache = /* @__PURE__ */ new Map();
58
+ constructor(options) {
59
+ this.apiUrl = options?.apiUrl?.trim() || process.env.WZRD_API_URL?.trim() || DEFAULT_API_URL;
60
+ }
61
+ /**
62
+ * Authenticate with the WZRD API using the GOAT wallet client.
63
+ *
64
+ * Flow:
65
+ * 1. GET /v1/agent/challenge — receive nonce
66
+ * 2. Sign canonical message with wallet's signMessage()
67
+ * 3. POST /v1/agent/verify — receive bearer token (24h TTL)
68
+ *
69
+ * Returns a cached bearer token if still valid.
70
+ */
71
+ async authenticate(walletClient) {
72
+ const address = walletClient.getAddress();
73
+ const cached = this.tokenCache.get(address);
74
+ if (cached && Date.now() < cached.expiresAt - TOKEN_REFRESH_MARGIN_MS) {
75
+ return cached.token;
76
+ }
77
+ const challengeRes = await fetch(`${this.apiUrl}/v1/agent/challenge`);
78
+ if (!challengeRes.ok) {
79
+ throw new Error(`WZRD auth challenge failed: ${challengeRes.status}`);
80
+ }
81
+ const { nonce } = await challengeRes.json();
82
+ const message = `wzrd-agent-auth v1 | wallet:${address} | nonce:${nonce}`;
83
+ const { signature: sigHex } = await walletClient.signMessage(message);
84
+ const sigBytes = hexToBytes(sigHex);
85
+ const sigBase58 = toBase58(sigBytes);
86
+ const verifyRes = await fetch(`${this.apiUrl}/v1/agent/verify`, {
87
+ method: "POST",
88
+ headers: {
89
+ "Content-Type": "application/json"
90
+ },
91
+ body: JSON.stringify({
92
+ pubkey: address,
93
+ nonce,
94
+ signature: sigBase58
95
+ })
96
+ });
97
+ if (!verifyRes.ok) {
98
+ throw new Error(`WZRD auth verify failed: ${verifyRes.status} ${await verifyRes.text()}`);
99
+ }
100
+ const { token, expires_at } = await verifyRes.json();
101
+ this.tokenCache.set(address, {
102
+ token,
103
+ expiresAt: new Date(expires_at).getTime()
104
+ });
105
+ return token;
106
+ }
107
+ };
108
+ var B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
109
+ function toBase58(bytes) {
110
+ const digits = [
111
+ 0
112
+ ];
113
+ for (const byte of bytes) {
114
+ let carry = byte;
115
+ for (let j = 0; j < digits.length; j++) {
116
+ carry += digits[j] << 8;
117
+ digits[j] = carry % 58;
118
+ carry = carry / 58 | 0;
119
+ }
120
+ while (carry > 0) {
121
+ digits.push(carry % 58);
122
+ carry = carry / 58 | 0;
123
+ }
124
+ }
125
+ let out = "";
126
+ for (const b of bytes) {
127
+ if (b !== 0) break;
128
+ out += "1";
129
+ }
130
+ for (let i = digits.length - 1; i >= 0; i--) out += B58[digits[i]];
131
+ return out;
132
+ }
133
+ __name(toBase58, "toBase58");
134
+ function hexToBytes(hex) {
135
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
136
+ const bytes = new Uint8Array(clean.length / 2);
137
+ for (let i = 0; i < bytes.length; i++) {
138
+ bytes[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
139
+ }
140
+ return bytes;
141
+ }
142
+ __name(hexToBytes, "hexToBytes");
143
+
144
+ // src/tools/leaderboard.ts
145
+ var import_core2 = require("@goat-sdk/core");
146
+
147
+ // src/parameters.ts
148
+ var import_core = require("@goat-sdk/core");
149
+ var import_zod = require("zod");
150
+ var GetLeaderboardParameters = class extends (0, import_core.createToolParameters)(import_zod.z.object({
151
+ limit: import_zod.z.number().int().min(1).max(50).optional().describe("Number of markets to return (default 20, max 50)"),
152
+ platform: import_zod.z.string().optional().describe("Filter by platform: 'huggingface', 'github', or omit for all")
153
+ })) {
154
+ static {
155
+ __name(this, "GetLeaderboardParameters");
156
+ }
157
+ };
158
+ var GetVelocitySignalParameters = class extends (0, import_core.createToolParameters)(import_zod.z.object({
159
+ platform: import_zod.z.string().optional().describe("Filter by platform: 'huggingface', 'github'"),
160
+ min_signal: import_zod.z.enum([
161
+ "BREAKOUT",
162
+ "MOMENTUM",
163
+ "EMERGING",
164
+ "STABLE",
165
+ "COOLING",
166
+ "WEAK"
167
+ ]).optional().describe("Minimum signal tier to include. BREAKOUT is strongest, WEAK is lowest. Only markets at or above this tier are returned.")
168
+ })) {
169
+ static {
170
+ __name(this, "GetVelocitySignalParameters");
171
+ }
172
+ };
173
+ var GetPortfolioParameters = class extends (0, import_core.createToolParameters)(import_zod.z.object({})) {
174
+ static {
175
+ __name(this, "GetPortfolioParameters");
176
+ }
177
+ };
178
+ var DepositParameters = class extends (0, import_core.createToolParameters)(import_zod.z.object({
179
+ market_id: import_zod.z.number().int().min(1).describe("Market ID to deposit into (get from wzrd_get_leaderboard)"),
180
+ amount_usdc: import_zod.z.number().positive().max(100).describe("Amount of USDC to deposit (e.g. 0.01). Max 100 per deposit."),
181
+ priority_fee: import_zod.z.number().int().positive().optional().describe("Priority fee in micro-lamports (default 50000). Higher = faster inclusion.")
182
+ })) {
183
+ static {
184
+ __name(this, "DepositParameters");
185
+ }
186
+ };
187
+ var ClaimParameters = class extends (0, import_core.createToolParameters)(import_zod.z.object({
188
+ execute: import_zod.z.boolean().optional().describe("If false, only check claimable amount without executing. Default true.")
189
+ })) {
190
+ static {
191
+ __name(this, "ClaimParameters");
192
+ }
193
+ };
194
+
195
+ // src/tools/leaderboard.ts
196
+ function _ts_decorate(decorators, target, key, desc) {
197
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
198
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
199
+ 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;
200
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
201
+ }
202
+ __name(_ts_decorate, "_ts_decorate");
203
+ function _ts_metadata(k, v) {
204
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
205
+ }
206
+ __name(_ts_metadata, "_ts_metadata");
207
+ var LeaderboardTools = class {
208
+ static {
209
+ __name(this, "LeaderboardTools");
210
+ }
211
+ api;
212
+ constructor(api) {
213
+ this.api = api;
214
+ }
215
+ async wzrd_get_leaderboard(parameters) {
216
+ const limit = parameters.limit ?? 20;
217
+ const params = new URLSearchParams({
218
+ limit: String(limit)
219
+ });
220
+ if (parameters.platform) params.set("platform", parameters.platform);
221
+ const res = await fetch(`${this.api.apiUrl}/v1/leaderboard?${params}`);
222
+ if (!res.ok) {
223
+ throw new Error(`Leaderboard request failed: ${res.status}`);
224
+ }
225
+ const data = await res.json();
226
+ const markets = data.markets ?? [];
227
+ 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");
228
+ return {
229
+ summary: `WZRD Leaderboard (${markets.length} markets, root_seq=${data.root?.root_seq ?? "N/A"}):
230
+ ${summary}`,
231
+ markets,
232
+ root: data.root,
233
+ total_positions: data.total_positions,
234
+ total_tvl_usdc: data.total_tvl_usdc
235
+ };
236
+ }
237
+ };
238
+ _ts_decorate([
239
+ (0, import_core2.Tool)({
240
+ 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."
241
+ }),
242
+ _ts_metadata("design:type", Function),
243
+ _ts_metadata("design:paramtypes", [
244
+ typeof GetLeaderboardParameters === "undefined" ? Object : GetLeaderboardParameters
245
+ ]),
246
+ _ts_metadata("design:returntype", Promise)
247
+ ], LeaderboardTools.prototype, "wzrd_get_leaderboard", null);
248
+ function formatVelocity(v) {
249
+ if (v >= 1e6) return `${(v / 1e6).toFixed(1)}M`;
250
+ if (v >= 1e3) return `${(v / 1e3).toFixed(0)}K`;
251
+ return v.toFixed(0);
252
+ }
253
+ __name(formatVelocity, "formatVelocity");
254
+
255
+ // src/tools/velocity.ts
256
+ var import_core3 = require("@goat-sdk/core");
257
+ function _ts_decorate2(decorators, target, key, desc) {
258
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
259
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
260
+ 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;
261
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
262
+ }
263
+ __name(_ts_decorate2, "_ts_decorate");
264
+ function _ts_metadata2(k, v) {
265
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
266
+ }
267
+ __name(_ts_metadata2, "_ts_metadata");
268
+ var VelocityTools = class {
269
+ static {
270
+ __name(this, "VelocityTools");
271
+ }
272
+ api;
273
+ constructor(api) {
274
+ this.api = api;
275
+ }
276
+ async wzrd_get_velocity_signal(parameters) {
277
+ const params = new URLSearchParams({
278
+ limit: "50"
279
+ });
280
+ if (parameters.platform) params.set("platform", parameters.platform);
281
+ const res = await fetch(`${this.api.apiUrl}/v1/leaderboard?${params}`);
282
+ if (!res.ok) {
283
+ throw new Error(`Leaderboard request failed: ${res.status}`);
284
+ }
285
+ const data = await res.json();
286
+ const markets = data.markets ?? [];
287
+ if (markets.length === 0) {
288
+ return {
289
+ summary: "No markets found.",
290
+ signals: []
291
+ };
292
+ }
293
+ const sorted = [
294
+ ...markets
295
+ ].sort((a, b) => a.velocity_ema - b.velocity_ema);
296
+ const signals = markets.map((m) => {
297
+ const rank = sorted.findIndex((s) => s.market_id === m.market_id);
298
+ const percentile = (rank + 1) / sorted.length * 100;
299
+ return {
300
+ market_id: m.market_id,
301
+ metric: m.metric,
302
+ platform: m.platform,
303
+ velocity_ema: m.velocity_ema,
304
+ signal: classify(m, percentile),
305
+ percentile: Math.round(percentile)
306
+ };
307
+ });
308
+ const tierOrder = [
309
+ "BREAKOUT",
310
+ "MOMENTUM",
311
+ "EMERGING",
312
+ "STABLE",
313
+ "COOLING",
314
+ "WEAK"
315
+ ];
316
+ const minIdx = parameters.min_signal ? tierOrder.indexOf(parameters.min_signal) : tierOrder.length;
317
+ const filtered = minIdx < tierOrder.length ? signals.filter((s) => tierOrder.indexOf(s.signal) <= minIdx) : signals;
318
+ const grouped = /* @__PURE__ */ new Map();
319
+ for (const s of filtered) {
320
+ const arr = grouped.get(s.signal) ?? [];
321
+ arr.push(s);
322
+ grouped.set(s.signal, arr);
323
+ }
324
+ const lines = [];
325
+ for (const tier of tierOrder) {
326
+ const group = grouped.get(tier);
327
+ if (!group?.length) continue;
328
+ lines.push(`${tier}:`);
329
+ for (const s of group) {
330
+ lines.push(` ${s.metric} (${formatVelocity2(s.velocity_ema)} velocity, p${s.percentile}) [${s.platform}]`);
331
+ }
332
+ }
333
+ const medianIdx = Math.floor(sorted.length / 2);
334
+ const medianVelocity = sorted[medianIdx]?.velocity_ema ?? 0;
335
+ return {
336
+ summary: `Velocity analysis (${markets.length} markets, median ${formatVelocity2(medianVelocity)}):
337
+ ${lines.join("\n")}`,
338
+ signals: filtered,
339
+ median_velocity: medianVelocity
340
+ };
341
+ }
342
+ };
343
+ _ts_decorate2([
344
+ (0, import_core3.Tool)({
345
+ 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."
346
+ }),
347
+ _ts_metadata2("design:type", Function),
348
+ _ts_metadata2("design:paramtypes", [
349
+ typeof GetVelocitySignalParameters === "undefined" ? Object : GetVelocitySignalParameters
350
+ ]),
351
+ _ts_metadata2("design:returntype", Promise)
352
+ ], VelocityTools.prototype, "wzrd_get_velocity_signal", null);
353
+ function classify(m, percentile) {
354
+ if (percentile >= 90) return "BREAKOUT";
355
+ if (percentile >= 70) return "MOMENTUM";
356
+ if (m.snapshot_count < 300 && percentile >= 50) return "EMERGING";
357
+ if (percentile >= 40) return "STABLE";
358
+ if (percentile >= 20) return "COOLING";
359
+ return "WEAK";
360
+ }
361
+ __name(classify, "classify");
362
+ function formatVelocity2(v) {
363
+ if (v >= 1e6) return `${(v / 1e6).toFixed(1)}M`;
364
+ if (v >= 1e3) return `${(v / 1e3).toFixed(0)}K`;
365
+ return v.toFixed(0);
366
+ }
367
+ __name(formatVelocity2, "formatVelocity");
368
+
369
+ // src/tools/portfolio.ts
370
+ var import_core4 = require("@goat-sdk/core");
371
+ var import_wallet_solana = require("@goat-sdk/wallet-solana");
372
+ function _ts_decorate3(decorators, target, key, desc) {
373
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
374
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
375
+ 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;
376
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
377
+ }
378
+ __name(_ts_decorate3, "_ts_decorate");
379
+ function _ts_metadata3(k, v) {
380
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
381
+ }
382
+ __name(_ts_metadata3, "_ts_metadata");
383
+ var PortfolioTools = class {
384
+ static {
385
+ __name(this, "PortfolioTools");
386
+ }
387
+ api;
388
+ constructor(api) {
389
+ this.api = api;
390
+ }
391
+ async wzrd_get_portfolio(walletClient, parameters) {
392
+ const token = await this.api.authenticate(walletClient);
393
+ const res = await fetch(`${this.api.apiUrl}/v1/portfolio`, {
394
+ headers: {
395
+ Authorization: `Bearer ${token}`
396
+ }
397
+ });
398
+ if (!res.ok) {
399
+ throw new Error(`Portfolio request failed: ${res.status}`);
400
+ }
401
+ const portfolio = await res.json();
402
+ const positions = portfolio.positions ?? [];
403
+ 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]" : ""));
404
+ return {
405
+ summary: `Portfolio (${positions.length} positions):
406
+ ${lines.join("\n")}
407
+ Total: ${formatUsdc(portfolio.total_deposited_usdc)} USDC deposited, ${formatUsdc(portfolio.total_vlofi)} vLOFI, ${formatCcm(portfolio.total_ccm_earned)} CCM earned`,
408
+ positions,
409
+ total_deposited_usdc: portfolio.total_deposited_usdc,
410
+ total_vlofi: portfolio.total_vlofi,
411
+ total_ccm_earned: portfolio.total_ccm_earned
412
+ };
413
+ }
414
+ };
415
+ _ts_decorate3([
416
+ (0, import_core4.Tool)({
417
+ 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."
418
+ }),
419
+ _ts_metadata3("design:type", Function),
420
+ _ts_metadata3("design:paramtypes", [
421
+ typeof import_wallet_solana.SolanaWalletClient === "undefined" ? Object : import_wallet_solana.SolanaWalletClient,
422
+ typeof GetPortfolioParameters === "undefined" ? Object : GetPortfolioParameters
423
+ ]),
424
+ _ts_metadata3("design:returntype", Promise)
425
+ ], PortfolioTools.prototype, "wzrd_get_portfolio", null);
426
+ function formatUsdc(nativeAmount) {
427
+ return (Number(nativeAmount) / 1e6).toFixed(4);
428
+ }
429
+ __name(formatUsdc, "formatUsdc");
430
+ function formatCcm(nativeAmount) {
431
+ return (Number(nativeAmount) / 1e6).toFixed(4);
432
+ }
433
+ __name(formatCcm, "formatCcm");
434
+
435
+ // src/tools/deposit.ts
436
+ var import_core5 = require("@goat-sdk/core");
437
+ var import_wallet_solana2 = require("@goat-sdk/wallet-solana");
438
+ var import_web3 = require("@solana/web3.js");
439
+ var import_meta = {};
440
+ function _ts_decorate4(decorators, target, key, desc) {
441
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
442
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
443
+ 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;
444
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
445
+ }
446
+ __name(_ts_decorate4, "_ts_decorate");
447
+ function _ts_metadata4(k, v) {
448
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
449
+ }
450
+ __name(_ts_metadata4, "_ts_metadata");
451
+ var DepositTools = class {
452
+ static {
453
+ __name(this, "DepositTools");
454
+ }
455
+ api;
456
+ constructor(api) {
457
+ this.api = api;
458
+ }
459
+ async wzrd_deposit(walletClient, parameters) {
460
+ const { market_id, amount_usdc, priority_fee = 5e4 } = parameters;
461
+ const connection = walletClient.getConnection();
462
+ const payer = new import_web3.PublicKey(walletClient.getAddress());
463
+ const amountNative = BigInt(Math.round(amount_usdc * 1e6));
464
+ const t0 = Date.now();
465
+ const sdk = await loadSdk();
466
+ const { createDepositMarketIx, fetchMarketVault, fetchOnChainPosition, fetchTokenBalance, getAta, TOKEN_PROGRAM_ID } = sdk;
467
+ const vault = await fetchMarketVault(connection, market_id);
468
+ if (!vault) {
469
+ return {
470
+ success: false,
471
+ error: `Market ${market_id} is listed but does not have an on-chain vault yet. Pick a market with an initialized vault before depositing.`,
472
+ market_id,
473
+ reason: "missing_vault"
474
+ };
475
+ }
476
+ const existing = await fetchOnChainPosition(connection, payer, market_id);
477
+ if (existing && existing.depositedAmount > 0n && !existing.settled) {
478
+ return {
479
+ success: false,
480
+ error: `Position already exists in market ${market_id}. Cannot double-deposit.`,
481
+ market_id,
482
+ deposited_amount: existing.depositedAmount.toString()
483
+ };
484
+ }
485
+ const usdcAta = getAta(payer, vault.depositMint, TOKEN_PROGRAM_ID);
486
+ const usdcBalance = await fetchTokenBalance(connection, usdcAta);
487
+ if (usdcBalance < amountNative) {
488
+ return {
489
+ success: false,
490
+ error: `Insufficient USDC: have ${formatUsdc2(usdcBalance)}, need ${amount_usdc.toFixed(4)}`,
491
+ market_id,
492
+ required_native: amountNative.toString(),
493
+ balance_native: usdcBalance.toString()
494
+ };
495
+ }
496
+ const solBalance = await connection.getBalance(payer);
497
+ if (solBalance < 1e4) {
498
+ return {
499
+ success: false,
500
+ error: `Insufficient SOL for tx fees: ${solBalance} lamports`,
501
+ market_id,
502
+ sol_balance_lamports: solBalance
503
+ };
504
+ }
505
+ let ixs;
506
+ try {
507
+ ixs = await createDepositMarketIx(connection, payer, market_id, amountNative);
508
+ } catch (error) {
509
+ const message = error instanceof Error ? error.message : String(error);
510
+ if (message.includes("MarketVault not found")) {
511
+ return {
512
+ success: false,
513
+ error: `Market ${market_id} vault not found on-chain.`,
514
+ market_id,
515
+ reason: "missing_vault"
516
+ };
517
+ }
518
+ throw error;
519
+ }
520
+ ixs.unshift(import_web3.ComputeBudgetProgram.setComputeUnitLimit({
521
+ units: 3e5
522
+ }), import_web3.ComputeBudgetProgram.setComputeUnitPrice({
523
+ microLamports: priority_fee
524
+ }));
525
+ const { hash } = await walletClient.sendTransaction({
526
+ instructions: ixs
527
+ });
528
+ const elapsed = Date.now() - t0;
529
+ return {
530
+ success: true,
531
+ summary: `Deposited ${amount_usdc.toFixed(4)} USDC into Market #${market_id}. Tx: ${hash.slice(0, 16)}... (${elapsed}ms)`,
532
+ signature: hash,
533
+ market_id,
534
+ amount_usdc,
535
+ elapsed_ms: elapsed,
536
+ explorer: `https://solscan.io/tx/${hash}`
537
+ };
538
+ }
539
+ };
540
+ _ts_decorate4([
541
+ (0, import_core5.Tool)({
542
+ 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."
543
+ }),
544
+ _ts_metadata4("design:type", Function),
545
+ _ts_metadata4("design:paramtypes", [
546
+ typeof import_wallet_solana2.SolanaWalletClient === "undefined" ? Object : import_wallet_solana2.SolanaWalletClient,
547
+ typeof DepositParameters === "undefined" ? Object : DepositParameters
548
+ ]),
549
+ _ts_metadata4("design:returntype", Promise)
550
+ ], DepositTools.prototype, "wzrd_deposit", null);
551
+ async function loadSdk() {
552
+ try {
553
+ return await import("@wzrd_sol/sdk");
554
+ } catch (error) {
555
+ const fallbackUrl = new URL("../../../../../sdk/dist/index.js", import_meta.url);
556
+ try {
557
+ return await import(fallbackUrl.href);
558
+ } catch {
559
+ throw error;
560
+ }
561
+ }
562
+ }
563
+ __name(loadSdk, "loadSdk");
564
+ function formatUsdc2(nativeAmount) {
565
+ return (Number(nativeAmount) / 1e6).toFixed(4);
566
+ }
567
+ __name(formatUsdc2, "formatUsdc");
568
+
569
+ // src/tools/claim.ts
570
+ var import_core6 = require("@goat-sdk/core");
571
+ var import_wallet_solana3 = require("@goat-sdk/wallet-solana");
572
+ function _ts_decorate5(decorators, target, key, desc) {
573
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
574
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
575
+ 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;
576
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
577
+ }
578
+ __name(_ts_decorate5, "_ts_decorate");
579
+ function _ts_metadata5(k, v) {
580
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
581
+ }
582
+ __name(_ts_metadata5, "_ts_metadata");
583
+ var ClaimTools = class {
584
+ static {
585
+ __name(this, "ClaimTools");
586
+ }
587
+ api;
588
+ constructor(api) {
589
+ this.api = api;
590
+ }
591
+ async wzrd_claim(walletClient, parameters) {
592
+ const pubkey = walletClient.getAddress();
593
+ const token = await this.api.authenticate(walletClient);
594
+ const claimsRes = await fetch(`${this.api.apiUrl}/v1/claims/${pubkey}`, {
595
+ headers: {
596
+ Authorization: `Bearer ${token}`
597
+ }
598
+ });
599
+ if (!claimsRes.ok) {
600
+ throw new Error(`Claims check failed: ${claimsRes.status}`);
601
+ }
602
+ const claims = await claimsRes.json();
603
+ const claimable = claims.cumulative_total - claims.claimed_total;
604
+ if (claimable <= 0) {
605
+ return {
606
+ success: true,
607
+ summary: `No CCM to claim. Cumulative: ${formatCcm2(claims.cumulative_total)}, already claimed: ${formatCcm2(claims.claimed_total)}.`,
608
+ claimable: 0,
609
+ cumulative_total: claims.cumulative_total,
610
+ claimed_total: claims.claimed_total
611
+ };
612
+ }
613
+ if (parameters.execute === false) {
614
+ return {
615
+ success: true,
616
+ 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.`,
617
+ claimable,
618
+ cumulative_total: claims.cumulative_total,
619
+ claimed_total: claims.claimed_total,
620
+ root_seq: claims.root_seq
621
+ };
622
+ }
623
+ const relayRes = await fetch(`${this.api.apiUrl}/v1/claims/${pubkey}/relay`, {
624
+ method: "POST",
625
+ headers: {
626
+ Authorization: `Bearer ${token}`,
627
+ "Content-Type": "application/json"
628
+ }
629
+ });
630
+ if (!relayRes.ok) {
631
+ throw new Error(`Relay claim failed: ${relayRes.status} ${await relayRes.text()}`);
632
+ }
633
+ const result = await relayRes.json();
634
+ if (result.status === "already_claimed") {
635
+ return {
636
+ success: true,
637
+ summary: `Already claimed through root ${result.root_seq}. Claimed total: ${formatCcm2(result.claimed_total ?? claims.claimed_total)} CCM.`,
638
+ already_claimed: true,
639
+ root_seq: result.root_seq
640
+ };
641
+ }
642
+ return {
643
+ success: true,
644
+ summary: `Claimed CCM via gasless relay. Cumulative: ${formatCcm2(result.cumulative_total)}. Root seq: ${result.root_seq}. Tx: ${result.tx_sig?.slice(0, 16)}...`,
645
+ cumulative_total: result.cumulative_total,
646
+ root_seq: result.root_seq,
647
+ tx_sig: result.tx_sig,
648
+ claimable_before: claimable,
649
+ explorer: result.tx_sig ? `https://solscan.io/tx/${result.tx_sig}` : null
650
+ };
651
+ }
652
+ };
653
+ _ts_decorate5([
654
+ (0, import_core6.Tool)({
655
+ 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."
656
+ }),
657
+ _ts_metadata5("design:type", Function),
658
+ _ts_metadata5("design:paramtypes", [
659
+ typeof import_wallet_solana3.SolanaWalletClient === "undefined" ? Object : import_wallet_solana3.SolanaWalletClient,
660
+ typeof ClaimParameters === "undefined" ? Object : ClaimParameters
661
+ ]),
662
+ _ts_metadata5("design:returntype", Promise)
663
+ ], ClaimTools.prototype, "wzrd_claim", null);
664
+ function formatCcm2(nativeAmount) {
665
+ return (Number(nativeAmount) / 1e6).toFixed(4);
666
+ }
667
+ __name(formatCcm2, "formatCcm");
668
+
669
+ // src/wzrd.plugin.ts
670
+ var WzrdPlugin = class extends import_core7.PluginBase {
671
+ static {
672
+ __name(this, "WzrdPlugin");
673
+ }
674
+ constructor(options) {
675
+ const api = new WzrdApiClient(options);
676
+ super("wzrd", [
677
+ new LeaderboardTools(api),
678
+ new VelocityTools(api),
679
+ new PortfolioTools(api),
680
+ new DepositTools(api),
681
+ new ClaimTools(api)
682
+ ]);
683
+ }
684
+ supportsChain = /* @__PURE__ */ __name((chain) => chain.type === "solana", "supportsChain");
685
+ };
686
+ var wzrd = /* @__PURE__ */ __name((options) => new WzrdPlugin(options), "wzrd");
687
+ // Annotate the CommonJS export names for ESM import in node:
688
+ 0 && (module.exports = {
689
+ ClaimParameters,
690
+ DepositParameters,
691
+ GetLeaderboardParameters,
692
+ GetPortfolioParameters,
693
+ GetVelocitySignalParameters,
694
+ WzrdApiClient,
695
+ WzrdPlugin,
696
+ wzrd
697
+ });
698
+ //# sourceMappingURL=index.js.map