@wzrd_sol/solana-agent-plugin 0.1.1 → 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/README.md CHANGED
@@ -1,15 +1,42 @@
1
1
  # @wzrd_sol/solana-agent-plugin
2
2
 
3
- WZRD Liquid Attention Protocol plugin for autonomous Solana agents. Provides 5 actions for interacting with WZRD attention markets: browse the leaderboard, classify velocity signals, view portfolio positions, deposit USDC to mint vLOFI, and claim CCM yield via gasless relay.
3
+ WZRD Liquid Attention Protocol plugin for autonomous Solana agents. Provides 5 actions for the server-witnessed inference earn loop: run inference, report the outcome for verified CCM rewards, check rewards, and claim CCM via gasless relay — no deposit, no SOL required.
4
+
5
+ WZRD witnesses inference (the server calls the AI provider and grades quality), issues an execution receipt, and rewards verified contributions in CCM. Claims are gasless via a server relay.
4
6
 
5
7
  Works standalone, with [Solana Agent Kit](https://github.com/sendAI/solana-agent-kit), or as a base for ElizaOS action wrappers.
6
8
 
9
+ ## 30-Second Test
10
+
11
+ No Solana Agent Kit dependency is required for the first smoke test. The package is ESM-first, so use `type: "module"` and `import`.
12
+
13
+ ```bash
14
+ mkdir wzrd-agent && cd wzrd-agent
15
+ printf '{"name":"wzrd-agent","type":"module","private":true}\n' > package.json
16
+ npm install @wzrd_sol/solana-agent-plugin @solana/web3.js
17
+ curl -O https://raw.githubusercontent.com/twzrd-sol/wzrd-velocity/main/agents/solana-agent-kit-plugin/examples/hello-wzrd.mjs
18
+ solana-keygen new -o /tmp/agent.json --no-bip39-passphrase
19
+ WZRD_KEYPAIR_PATH=/tmp/agent.json node hello-wzrd.mjs
20
+ ```
21
+
22
+ What you should see:
23
+ - the top markets
24
+ - successful Ed25519 agent auth
25
+ - pending CCM rewards
26
+ - claimable CCM state
27
+
7
28
  ## Install
8
29
 
9
30
  ```bash
10
31
  npm install @wzrd_sol/solana-agent-plugin
11
32
  ```
12
33
 
34
+ Install with Solana Agent Kit only when you are ready to execute through its action system:
35
+
36
+ ```bash
37
+ npm install @wzrd_sol/solana-agent-plugin solana-agent-kit
38
+ ```
39
+
13
40
  ## Quick Start
14
41
 
15
42
  ```typescript
@@ -24,46 +51,77 @@ const client = new WzrdClient(keypair);
24
51
  const leaderboard = await client.getLeaderboard();
25
52
  console.log(leaderboard.markets.map(m => `${m.channel_id}: ${m.velocity_ema}`));
26
53
 
27
- // Authenticated endpoints (auto-handles challenge/verify flow)
28
- const portfolio = await client.getPortfolio();
29
- const claims = await client.getClaims();
30
- const result = await client.claimRelay(); // gasless CCM claim
54
+ // Earn loop (auth is handled automatically: challenge -> sign -> verify -> Bearer)
55
+ const infer = await client.infer('Write a Python quicksort'); // server-witnessed inference
56
+ const report = await client.report({ // verified report -> CCM
57
+ model_id: infer.model,
58
+ execution_id: infer.execution_id,
59
+ quality_score: infer.quality_score,
60
+ latency_ms: infer.latency_ms,
61
+ });
62
+ const rewards = await client.getRewards(); // pending + lifetime CCM
63
+ const claim = await client.claimRelay(); // gasless CCM claim
64
+ ```
65
+
66
+ ## Solana Agent Kit
67
+
68
+ The package works standalone or as a Solana Agent Kit plugin.
69
+
70
+ ```typescript
71
+ import { SolanaAgentKit } from 'solana-agent-kit';
72
+ import { WZRD_PLUGIN } from '@wzrd_sol/solana-agent-plugin';
73
+
74
+ const agent = new SolanaAgentKit(/* wallet + rpc + model config */);
75
+ agent.use(WZRD_PLUGIN);
31
76
  ```
32
77
 
33
78
  ## Actions
34
79
 
35
- The plugin exports 5 actions that follow the Solana Agent Kit action interface:
80
+ The plugin exports 5 actions that follow the Solana Agent Kit action interface. All earn-loop actions authenticate with the agent keypair (Ed25519 challenge/verify); none of them spend funds or sign a deposit.
36
81
 
37
- | Action | Auth | Description |
38
- |--------|------|-------------|
39
- | `LEADERBOARD_ACTION` | No | Fetch ranked attention markets |
40
- | `VELOCITY_ACTION` | No | Classify signal strength (BREAKOUT / MOMENTUM / EMERGING / STABLE / COOLING / WEAK) |
41
- | `PORTFOLIO_ACTION` | Yes | View positions and CCM earned |
42
- | `DEPOSIT_ACTION` | Yes | Deposit USDC into a market, receive vLOFI |
43
- | `CLAIM_ACTION` | Yes | Claim CCM via server-paid gasless relay |
82
+ | Action | Description |
83
+ |--------|-------------|
84
+ | `EARN_ACTION` (`wzrd_earn`) | Full earn cycle in one call: pick a model, run server-witnessed inference, report, and check rewards |
85
+ | `INFER_ACTION` (`wzrd_infer`) | Run server-witnessed inference; returns an `execution_id` receipt |
86
+ | `REPORT_ACTION` (`wzrd_report`) | Report a pick with an `execution_id` for quality-weighted CCM rewards |
87
+ | `REWARDS_ACTION` (`wzrd_rewards`) | Check pending + lifetime CCM and contribution count |
88
+ | `CLAIM_ACTION` (`wzrd_claim`) | Claim CCM via server-paid gasless relay (agent needs 0 SOL) |
44
89
 
45
90
  ```typescript
46
91
  import { WZRD_ACTIONS, WZRD_PLUGIN } from '@wzrd_sol/solana-agent-plugin';
47
92
 
48
- // Register all actions with Solana Agent Kit
49
- // WZRD_PLUGIN.actions contains all 5 actions
93
+ // WZRD_ACTIONS is the array of all 5 actions.
94
+ // WZRD_PLUGIN.actions contains the same set for direct registration.
50
95
  ```
51
96
 
52
97
  ## API
53
98
 
54
- ### `new WzrdClient(keypair: Keypair, apiUrl?: string)`
99
+ ### `new WzrdClient(signer: Keypair | WzrdSigner, apiUrl?: string)`
55
100
 
56
- Creates a client instance. The keypair is used for Ed25519 agent authentication. Default API URL is `https://api.twzrd.xyz`.
101
+ Creates a client instance. Accepts a `Keypair`, or any `WzrdSigner` with a `publicKey` plus either `signMessage()` or an Ed25519 `secretKey`. The signer is used for Ed25519 agent authentication. Default API URL is `https://api.twzrd.xyz` (override with the `apiUrl` arg or the `WZRD_API_URL` environment variable).
57
102
 
58
103
  ### Methods
59
104
 
60
- - `getLeaderboard(limit?: number, platform?: string)` -- no auth
61
- - `getPortfolio()` -- authenticated
62
- - `getClaims()` -- authenticated
63
- - `claimRelay()` -- authenticated, gasless
64
- - `getHealth()` -- no auth
105
+ - `getLeaderboard(limit?: number)` no auth; ranked attention markets
106
+ - `pickModel()` no auth; returns the top market's `channel_id` (the server-resolvable model id)
107
+ - `infer(prompt: string, model?: string, taskType?: string)` authenticated; server-witnessed inference. If `model` is omitted, `pickModel()` is used. `taskType` (`code` / `chat` / `reasoning`) steers the provider cascade.
108
+ - `report(params)` authenticated; submit `{ model_id, execution_id, task_type?, quality_score?, latency_ms? }` for verified rewards
109
+ - `getRewards()` authenticated; pending + lifetime CCM and contribution count
110
+ - `getClaimStatus()` — authenticated; cumulative / claimed / claimable CCM
111
+ - `claimRelay()` — authenticated, gasless
112
+
113
+ Auth is handled automatically: the client requests a challenge nonce, signs it, and caches the bearer token (24h TTL, auto-refreshes 1h before expiry).
114
+
115
+ For an end-to-end smoke test, use [`examples/hello-wzrd.mjs`](./examples/hello-wzrd.mjs). It works with just:
116
+ - `@wzrd_sol/solana-agent-plugin`
117
+ - `@solana/web3.js`
118
+ - `WZRD_KEYPAIR_PATH=/path/to/keypair.json`
119
+
120
+ ## Protocol
121
+
122
+ WZRD measures which open-source AI models are gaining developer attention. Verified inference against high-attention models earns more CCM. The oracle is live on Solana mainnet.
65
123
 
66
- Auth is handled automatically: the client requests a challenge nonce, signs it with the keypair, and caches the bearer token (24h TTL, auto-refreshes).
124
+ - **CCM Mint**: `Dxk8mAb3C7AM8JN6tAJfVuSja5yidhZM5sEKW3SRX2BM` (Token-2022, 9 decimals)
67
125
 
68
126
  ## License
69
127
 
@@ -3,17 +3,9 @@
3
3
  *
4
4
  * Claim accrued CCM tokens via the gasless relay.
5
5
  * Server pays tx fees — agent doesn't need SOL to claim.
6
- *
7
- * Flow: check claimable amount → relay claim → receive CCM.
8
6
  */
9
7
  import { z } from 'zod';
10
8
  import type { Action, SolanaAgentKit } from 'solana-agent-kit';
11
- export declare const claimSchema: z.ZodObject<{
12
- execute: z.ZodOptional<z.ZodBoolean>;
13
- }, "strip", z.ZodTypeAny, {
14
- execute?: boolean | undefined;
15
- }, {
16
- execute?: boolean | undefined;
17
- }>;
18
- export declare function claimHandler(agent: SolanaAgentKit, input: z.infer<typeof claimSchema>): Promise<Record<string, unknown>>;
9
+ export declare const claimSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
10
+ export declare function claimHandler(agent: SolanaAgentKit, _input: z.infer<typeof claimSchema>): Promise<Record<string, unknown>>;
19
11
  export declare const CLAIM_ACTION: Action;
@@ -3,76 +3,61 @@
3
3
  *
4
4
  * Claim accrued CCM tokens via the gasless relay.
5
5
  * Server pays tx fees — agent doesn't need SOL to claim.
6
- *
7
- * Flow: check claimable amount → relay claim → receive CCM.
8
6
  */
9
7
  import { z } from 'zod';
10
- import { formatCcm, getClaimsData, getClientForAgent } from '../runtime.js';
11
- export const claimSchema = z.object({
12
- execute: z.boolean().optional(),
13
- });
14
- export async function claimHandler(agent, input) {
15
- const claims = await getClaimsData(agent);
16
- const claimable = claims.cumulative_total - claims.claimed_total;
17
- if (claimable <= 0) {
18
- return {
19
- success: true,
20
- text: `No CCM to claim. Cumulative: ${claims.cumulative_total}, ` +
21
- `already claimed: ${claims.claimed_total}. ` +
22
- `Deposit into markets and wait for the next scoring cycle.`,
23
- data: claims,
24
- };
25
- }
26
- if (input.execute === false) {
8
+ import { formatCcm, getClientForAgent } from '../runtime.js';
9
+ export const claimSchema = z.object({});
10
+ export async function claimHandler(agent, _input) {
11
+ const client = getClientForAgent(agent);
12
+ // Check if there's anything to claim
13
+ const status = await client.getClaimStatus();
14
+ if (status.claimable <= 0) {
27
15
  return {
28
16
  success: true,
29
- text: `${formatCcm(claimable)} CCM claimable ` +
30
- `(${formatCcm(claims.cumulative_total)} cumulative, ` +
31
- `${formatCcm(claims.claimed_total)} claimed). ` +
32
- `Root seq: ${claims.root_seq}. Call with execute=true to claim.`,
33
- data: claims,
17
+ text: `No CCM to claim right now. ` +
18
+ `Cumulative: ${formatCcm(status.cumulative_total)} CCM, ` +
19
+ `already claimed: ${formatCcm(status.claimed_total)} CCM. ` +
20
+ `Run wzrd_earn first to accrue rewards.`,
21
+ data: status,
34
22
  };
35
23
  }
36
- const result = await getClientForAgent(agent).claimRelay();
24
+ const result = await client.claimRelay();
37
25
  if (result.status === 'already_claimed') {
38
26
  return {
39
27
  success: true,
40
- text: `Already claimed through root ${result.root_seq}. ` +
41
- `Claimed total: ${formatCcm(result.claimed_total ?? claims.claimed_total)} CCM.`,
28
+ text: `Already claimed through root ${result.root_seq}.`,
42
29
  data: result,
43
30
  };
44
31
  }
45
32
  return {
46
33
  success: true,
47
34
  text: `Claimed CCM via gasless relay. ` +
48
- `Cumulative total: ${formatCcm(result.cumulative_total)}. ` +
35
+ `Cumulative: ${formatCcm(result.cumulative_total)} CCM. ` +
49
36
  `Root seq: ${result.root_seq}. ` +
50
37
  `Tx: ${result.tx_sig?.slice(0, 16)}...`,
51
38
  data: {
52
39
  ...result,
53
- claimable_before: claimable,
54
- explorer: result.tx_sig ? `https://solscan.io/tx/${result.tx_sig}` : null,
40
+ claimable_before: status.claimable,
41
+ explorer: result.tx_sig ? `https://orbmarkets.io/tx/${result.tx_sig}` : null,
55
42
  },
56
43
  };
57
44
  }
58
45
  export const CLAIM_ACTION = {
59
46
  name: 'wzrd_claim',
60
- similes: ['wzrd_harvest', 'claim_ccm', 'redeem_rewards', 'collect_yield'],
61
- description: 'Claim accrued CCM tokens from your WZRD positions. Uses the gasless relay — ' +
62
- 'the server pays transaction fees, so you don\'t need SOL to claim. ' +
63
- 'CCM accrues based on your velocity multiplier and is distributed via ' +
64
- 'merkle proofs published on-chain every ~10 minutes. ' +
65
- 'Call this periodically to harvest your earned CCM.',
47
+ similes: ['wzrd_harvest', 'claim_ccm', 'collect_rewards'],
48
+ description: 'Claim accrued CCM tokens via gasless relay. The server pays transaction fees — ' +
49
+ 'no SOL needed. CCM accrues from verified inference reports (wzrd_earn/wzrd_report). ' +
50
+ 'Call this periodically to harvest earned CCM to your wallet.',
66
51
  examples: [
67
52
  [
68
53
  {
69
- input: { execute: false },
54
+ input: {},
70
55
  output: {
71
56
  success: true,
72
- claimable: 100000,
73
- cumulative_total: 250000,
57
+ cumulative_total: 250000000000,
58
+ tx_sig: '5S7L...',
74
59
  },
75
- explanation: 'Check how much CCM is available before triggering a relay claim.',
60
+ explanation: 'Claim accrued CCM via gasless relay.',
76
61
  },
77
62
  ],
78
63
  ],
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Action: wzrd_earn
3
+ *
4
+ * Full earn cycle: infer → report → check rewards.
5
+ * Single action that runs the complete server-witnessed earn loop.
6
+ */
7
+ import { z } from 'zod';
8
+ import type { Action, SolanaAgentKit } from 'solana-agent-kit';
9
+ export declare const earnSchema: z.ZodObject<{
10
+ task_type: z.ZodOptional<z.ZodEnum<["code", "chat", "reasoning"]>>;
11
+ prompt: z.ZodOptional<z.ZodString>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ task_type?: "chat" | "code" | "reasoning" | undefined;
14
+ prompt?: string | undefined;
15
+ }, {
16
+ task_type?: "chat" | "code" | "reasoning" | undefined;
17
+ prompt?: string | undefined;
18
+ }>;
19
+ export declare function earnHandler(agent: SolanaAgentKit, input: z.infer<typeof earnSchema>): Promise<Record<string, unknown>>;
20
+ export declare const EARN_ACTION: Action;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Action: wzrd_earn
3
+ *
4
+ * Full earn cycle: infer → report → check rewards.
5
+ * Single action that runs the complete server-witnessed earn loop.
6
+ */
7
+ import { z } from 'zod';
8
+ import { formatCcm, getClientForAgent } from '../runtime.js';
9
+ const EVAL_PROMPTS = {
10
+ code: [
11
+ 'Write a Python function that checks if a binary tree is balanced. Include time complexity analysis.',
12
+ 'Implement a thread-safe LRU cache in Rust with O(1) get and put operations.',
13
+ 'Write a TypeScript generic function that deep-merges two objects, handling arrays and nested objects.',
14
+ ],
15
+ chat: [
16
+ 'Explain the difference between TCP and UDP to someone who has never programmed before.',
17
+ 'What are the tradeoffs between microservices and monolithic architecture?',
18
+ 'Describe how consensus works in proof-of-stake blockchains.',
19
+ ],
20
+ reasoning: [
21
+ '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?',
22
+ 'If it takes 5 machines 5 minutes to make 5 widgets, how long does it take 100 machines to make 100 widgets?',
23
+ '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?',
24
+ ],
25
+ };
26
+ function pickPrompt(taskType) {
27
+ const prompts = EVAL_PROMPTS[taskType] || EVAL_PROMPTS.chat;
28
+ return prompts[Math.floor(Math.random() * prompts.length)];
29
+ }
30
+ export const earnSchema = z.object({
31
+ task_type: z.enum(['code', 'chat', 'reasoning']).optional(),
32
+ prompt: z.string().optional(),
33
+ });
34
+ export async function earnHandler(agent, input) {
35
+ const client = getClientForAgent(agent);
36
+ const taskType = input.task_type || 'code';
37
+ const prompt = input.prompt || pickPrompt(taskType);
38
+ const steps = [];
39
+ // Step 1: Pick model + Infer
40
+ steps.push('-> Picking model from leaderboard...');
41
+ const model = await client.pickModel();
42
+ steps.push(`-> Running inference: ${model} (${taskType})...`);
43
+ const infer = await client.infer(prompt, model, taskType);
44
+ steps.push(`OK Inference: ${infer.model} (${infer.provider}), ` +
45
+ `quality ${infer.quality_score.toFixed(2)}, ${infer.latency_ms}ms`);
46
+ // Step 2: Report with execution_id
47
+ steps.push('-> Reporting outcome...');
48
+ const report = await client.report({
49
+ model_id: infer.model,
50
+ execution_id: infer.execution_id,
51
+ task_type: taskType,
52
+ quality_score: infer.quality_score,
53
+ latency_ms: infer.latency_ms,
54
+ });
55
+ steps.push(`OK Reported: ${report.verification_state}, contribution #${report.contribution_id}`);
56
+ // Step 3: Check rewards
57
+ steps.push('-> Checking rewards...');
58
+ const rewards = await client.getRewards();
59
+ steps.push(`OK Rewards: ${formatCcm(rewards.pending_ccm)} CCM pending, ` +
60
+ `${formatCcm(rewards.total_rewarded_ccm)} CCM lifetime`);
61
+ return {
62
+ success: true,
63
+ text: `Earn cycle complete:\n${steps.join('\n')}`,
64
+ data: {
65
+ infer: {
66
+ execution_id: infer.execution_id,
67
+ model: infer.model,
68
+ provider: infer.provider,
69
+ quality_score: infer.quality_score,
70
+ latency_ms: infer.latency_ms,
71
+ },
72
+ report: {
73
+ contribution_id: report.contribution_id,
74
+ verification_state: report.verification_state,
75
+ },
76
+ rewards: {
77
+ pending_ccm: rewards.pending_ccm,
78
+ total_rewarded_ccm: rewards.total_rewarded_ccm,
79
+ contribution_count: rewards.contribution_count,
80
+ },
81
+ },
82
+ };
83
+ }
84
+ export const EARN_ACTION = {
85
+ name: 'wzrd_earn',
86
+ similes: ['wzrd_earn_ccm', 'earn_rewards', 'run_earn_loop'],
87
+ description: 'Run the full WZRD earn cycle: pick a prompt, run server-witnessed inference, ' +
88
+ 'report the outcome, and check pending rewards. One action, complete loop. ' +
89
+ 'Earns verified CCM rewards on Solana.',
90
+ examples: [
91
+ [
92
+ {
93
+ input: { task_type: 'code' },
94
+ output: {
95
+ success: true,
96
+ model: 'gemini-2.5-flash',
97
+ quality_score: 0.85,
98
+ verification_state: 'verified',
99
+ pending_ccm: 142500000000,
100
+ },
101
+ explanation: 'Run the full earn cycle: infer through WZRD, report outcome, check rewards.',
102
+ },
103
+ ],
104
+ ],
105
+ schema: earnSchema,
106
+ handler: async (agent, input) => earnHandler(agent, earnSchema.parse(input)),
107
+ };
@@ -1,6 +1,5 @@
1
- export type { MarketSignal } from './velocity.js';
2
- export { LEADERBOARD_ACTION } from './leaderboard.js';
3
- export { PORTFOLIO_ACTION } from './portfolio.js';
4
- export { DEPOSIT_ACTION } from './deposit.js';
1
+ export { EARN_ACTION } from './earn.js';
2
+ export { INFER_ACTION } from './infer.js';
3
+ export { REPORT_ACTION } from './report.js';
5
4
  export { CLAIM_ACTION } from './claim.js';
6
- export { VELOCITY_ACTION } from './velocity.js';
5
+ export { REWARDS_ACTION } from './rewards.js';
@@ -1,5 +1,5 @@
1
- export { LEADERBOARD_ACTION } from './leaderboard.js';
2
- export { PORTFOLIO_ACTION } from './portfolio.js';
3
- export { DEPOSIT_ACTION } from './deposit.js';
1
+ export { EARN_ACTION } from './earn.js';
2
+ export { INFER_ACTION } from './infer.js';
3
+ export { REPORT_ACTION } from './report.js';
4
4
  export { CLAIM_ACTION } from './claim.js';
5
- export { VELOCITY_ACTION } from './velocity.js';
5
+ export { REWARDS_ACTION } from './rewards.js';
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Action: wzrd_infer
3
+ *
4
+ * Server-witnessed inference through WZRD.
5
+ * Returns execution_id receipt for use with wzrd_report.
6
+ */
7
+ import { z } from 'zod';
8
+ import type { Action, SolanaAgentKit } from 'solana-agent-kit';
9
+ export declare const inferSchema: z.ZodObject<{
10
+ prompt: z.ZodString;
11
+ model: z.ZodOptional<z.ZodString>;
12
+ task_type: z.ZodOptional<z.ZodEnum<["code", "chat", "reasoning"]>>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ prompt: string;
15
+ task_type?: "chat" | "code" | "reasoning" | undefined;
16
+ model?: string | undefined;
17
+ }, {
18
+ prompt: string;
19
+ task_type?: "chat" | "code" | "reasoning" | undefined;
20
+ model?: string | undefined;
21
+ }>;
22
+ export declare function inferHandler(agent: SolanaAgentKit, input: z.infer<typeof inferSchema>): Promise<Record<string, unknown>>;
23
+ export declare const INFER_ACTION: Action;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Action: wzrd_infer
3
+ *
4
+ * Server-witnessed inference through WZRD.
5
+ * Returns execution_id receipt for use with wzrd_report.
6
+ */
7
+ import { z } from 'zod';
8
+ import { getClientForAgent } from '../runtime.js';
9
+ export const inferSchema = z.object({
10
+ prompt: z.string().min(1),
11
+ model: z.string().optional(),
12
+ task_type: z.enum(['code', 'chat', 'reasoning']).optional(),
13
+ });
14
+ export async function inferHandler(agent, input) {
15
+ const client = getClientForAgent(agent);
16
+ const taskType = input.task_type || 'chat';
17
+ const result = await client.infer(input.prompt, input.model, taskType);
18
+ return {
19
+ success: true,
20
+ text: `Inference complete. Model: ${result.model} (${result.provider}), ` +
21
+ `quality: ${result.quality_score.toFixed(2)}, ${result.latency_ms}ms. ` +
22
+ `execution_id: ${result.execution_id}`,
23
+ data: {
24
+ execution_id: result.execution_id,
25
+ model: result.model,
26
+ provider: result.provider,
27
+ quality_score: result.quality_score,
28
+ latency_ms: result.latency_ms,
29
+ response_preview: result.response.slice(0, 300),
30
+ },
31
+ };
32
+ }
33
+ export const INFER_ACTION = {
34
+ name: 'wzrd_infer',
35
+ similes: ['wzrd_run_inference', 'ask_model', 'run_model'],
36
+ description: 'Run server-witnessed inference through WZRD. The server calls the AI provider, ' +
37
+ 'grades quality, and returns an execution receipt (execution_id). ' +
38
+ 'Use the execution_id with wzrd_report to earn verified CCM rewards. ' +
39
+ 'If no model is specified, picks the top model from the leaderboard.',
40
+ examples: [
41
+ [
42
+ {
43
+ input: { prompt: 'Write a Python function to check if a binary tree is balanced', task_type: 'code' },
44
+ output: {
45
+ success: true,
46
+ execution_id: 'abc-123',
47
+ model: 'gemini-2.5-flash',
48
+ quality_score: 0.85,
49
+ },
50
+ explanation: 'Run inference through WZRD to get an execution receipt for verified rewards.',
51
+ },
52
+ ],
53
+ ],
54
+ schema: inferSchema,
55
+ handler: async (agent, input) => inferHandler(agent, inferSchema.parse(input)),
56
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Action: wzrd_report
3
+ *
4
+ * Report a model pick with execution receipt for verified CCM rewards.
5
+ * Must be called after wzrd_infer. Pass the execution_id from the infer result.
6
+ */
7
+ import { z } from 'zod';
8
+ import type { Action, SolanaAgentKit } from 'solana-agent-kit';
9
+ export declare const reportSchema: z.ZodObject<{
10
+ model_id: z.ZodString;
11
+ execution_id: z.ZodString;
12
+ task_type: z.ZodOptional<z.ZodEnum<["code", "chat", "reasoning"]>>;
13
+ quality_score: z.ZodOptional<z.ZodNumber>;
14
+ latency_ms: z.ZodOptional<z.ZodNumber>;
15
+ }, "strip", z.ZodTypeAny, {
16
+ execution_id: string;
17
+ model_id: string;
18
+ task_type?: "chat" | "code" | "reasoning" | undefined;
19
+ quality_score?: number | undefined;
20
+ latency_ms?: number | undefined;
21
+ }, {
22
+ execution_id: string;
23
+ model_id: string;
24
+ task_type?: "chat" | "code" | "reasoning" | undefined;
25
+ quality_score?: number | undefined;
26
+ latency_ms?: number | undefined;
27
+ }>;
28
+ export declare function reportHandler(agent: SolanaAgentKit, input: z.infer<typeof reportSchema>): Promise<Record<string, unknown>>;
29
+ export declare const REPORT_ACTION: Action;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Action: wzrd_report
3
+ *
4
+ * Report a model pick with execution receipt for verified CCM rewards.
5
+ * Must be called after wzrd_infer. Pass the execution_id from the infer result.
6
+ */
7
+ import { z } from 'zod';
8
+ import { getClientForAgent } from '../runtime.js';
9
+ export const reportSchema = z.object({
10
+ model_id: z.string().min(1),
11
+ execution_id: z.string().min(1),
12
+ task_type: z.enum(['code', 'chat', 'reasoning']).optional(),
13
+ quality_score: z.number().min(0).max(1).optional(),
14
+ latency_ms: z.number().int().positive().optional(),
15
+ });
16
+ export async function reportHandler(agent, input) {
17
+ const client = getClientForAgent(agent);
18
+ const result = await client.report({
19
+ model_id: input.model_id,
20
+ execution_id: input.execution_id,
21
+ task_type: input.task_type,
22
+ quality_score: input.quality_score,
23
+ latency_ms: input.latency_ms,
24
+ });
25
+ return {
26
+ success: true,
27
+ text: `Reported to WZRD. Verification: ${result.verification_state}, ` +
28
+ `contribution #${result.contribution_id}, model: ${result.model_id}` +
29
+ (result.quality_score != null ? `, quality: ${result.quality_score.toFixed(2)}` : ''),
30
+ data: {
31
+ contribution_id: result.contribution_id,
32
+ verification_state: result.verification_state,
33
+ quality_score: result.quality_score,
34
+ model_id: result.model_id,
35
+ },
36
+ };
37
+ }
38
+ export const REPORT_ACTION = {
39
+ name: 'wzrd_report',
40
+ similes: ['wzrd_report_outcome', 'report_model_pick', 'submit_signal'],
41
+ description: 'Report a model pick to WZRD with an execution_id from wzrd_infer. ' +
42
+ 'Verified reports earn CCM rewards with a quality multiplier. ' +
43
+ 'Requires: model_id and execution_id (both from wzrd_infer result).',
44
+ examples: [
45
+ [
46
+ {
47
+ input: { model_id: 'gemini-2.5-flash', execution_id: 'abc-123', task_type: 'code', quality_score: 0.85 },
48
+ output: {
49
+ success: true,
50
+ verification_state: 'verified',
51
+ contribution_id: 4521,
52
+ },
53
+ explanation: 'Report an inference outcome with execution receipt for verified CCM rewards.',
54
+ },
55
+ ],
56
+ ],
57
+ schema: reportSchema,
58
+ handler: async (agent, input) => reportHandler(agent, reportSchema.parse(input)),
59
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Action: wzrd_rewards
3
+ *
4
+ * Check pending and lifetime CCM rewards.
5
+ */
6
+ import { z } from 'zod';
7
+ import type { Action, SolanaAgentKit } from 'solana-agent-kit';
8
+ export declare const rewardsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
9
+ export declare function rewardsHandler(agent: SolanaAgentKit, _input: z.infer<typeof rewardsSchema>): Promise<Record<string, unknown>>;
10
+ export declare const REWARDS_ACTION: Action;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Action: wzrd_rewards
3
+ *
4
+ * Check pending and lifetime CCM rewards.
5
+ */
6
+ import { z } from 'zod';
7
+ import { formatCcm, getClientForAgent } from '../runtime.js';
8
+ export const rewardsSchema = z.object({});
9
+ export async function rewardsHandler(agent, _input) {
10
+ const client = getClientForAgent(agent);
11
+ const rewards = await client.getRewards();
12
+ return {
13
+ success: true,
14
+ text: `WZRD Rewards: ` +
15
+ `${formatCcm(rewards.pending_ccm)} CCM pending, ` +
16
+ `${formatCcm(rewards.total_rewarded_ccm)} CCM lifetime, ` +
17
+ `${rewards.contribution_count} contributions` +
18
+ (rewards.rank ? `, rank #${rewards.rank}` : ''),
19
+ data: {
20
+ pending_ccm: rewards.pending_ccm,
21
+ total_rewarded_ccm: rewards.total_rewarded_ccm,
22
+ contribution_count: rewards.contribution_count,
23
+ rank: rewards.rank,
24
+ },
25
+ };
26
+ }
27
+ export const REWARDS_ACTION = {
28
+ name: 'wzrd_rewards',
29
+ similes: ['wzrd_balance', 'check_rewards', 'my_ccm'],
30
+ description: 'Check your pending CCM rewards, lifetime total, and contribution count. ' +
31
+ 'Use this to see how much you have earned from WZRD inference before claiming.',
32
+ examples: [
33
+ [
34
+ {
35
+ input: {},
36
+ output: {
37
+ success: true,
38
+ pending_ccm: 142500000000,
39
+ total_rewarded_ccm: 326000000000,
40
+ contribution_count: 47,
41
+ },
42
+ explanation: 'Check pending and lifetime CCM rewards.',
43
+ },
44
+ ],
45
+ ],
46
+ schema: rewardsSchema,
47
+ handler: async (agent, input) => rewardsHandler(agent, rewardsSchema.parse(input)),
48
+ };