@wzrd_sol/eliza-plugin 0.1.2 → 0.3.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.
Files changed (38) hide show
  1. package/README.md +98 -26
  2. package/dist/actions/claim.d.ts +2 -5
  3. package/dist/actions/claim.js +33 -30
  4. package/dist/actions/earn.d.ts +8 -0
  5. package/dist/actions/earn.js +83 -0
  6. package/dist/actions/infer.d.ts +8 -0
  7. package/dist/actions/infer.js +41 -0
  8. package/dist/actions/intel-preflight.d.ts +5 -0
  9. package/dist/actions/intel-preflight.js +97 -0
  10. package/dist/actions/intel-trust.d.ts +7 -0
  11. package/dist/actions/intel-trust.js +82 -0
  12. package/dist/actions/report.d.ts +8 -0
  13. package/dist/actions/report.js +45 -0
  14. package/dist/actions/rewards.d.ts +5 -0
  15. package/dist/actions/rewards.js +31 -0
  16. package/dist/actions/verify-receipt.d.ts +7 -0
  17. package/dist/actions/verify-receipt.js +44 -0
  18. package/dist/client-factory.d.ts +14 -0
  19. package/dist/client-factory.js +40 -0
  20. package/dist/client.d.ts +91 -3
  21. package/dist/client.js +136 -16
  22. package/dist/index.d.ts +26 -9
  23. package/dist/index.js +25 -9
  24. package/dist/intel-helpers.d.ts +22 -0
  25. package/dist/intel-helpers.js +181 -0
  26. package/dist/paying-fetch.d.ts +9 -0
  27. package/dist/paying-fetch.js +27 -0
  28. package/dist/test/plugin-registration.intel.d.ts +1 -0
  29. package/dist/test/plugin-registration.intel.js +253 -0
  30. package/package.json +21 -10
  31. package/dist/actions/deposit.d.ts +0 -2
  32. package/dist/actions/deposit.js +0 -79
  33. package/dist/actions/leaderboard.d.ts +0 -3
  34. package/dist/actions/leaderboard.js +0 -25
  35. package/dist/actions/portfolio.d.ts +0 -3
  36. package/dist/actions/portfolio.js +0 -20
  37. package/dist/actions/velocity.d.ts +0 -3
  38. package/dist/actions/velocity.js +0 -57
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # @wzrd_sol/eliza-plugin
2
2
 
3
- ElizaOS plugin for the WZRD Liquid Attention Protocol on Solana. Gives ElizaOS agents the ability to discover AI model velocity, manage attention market positions, deposit USDC, and claim CCM yield.
3
+ ElizaOS plugin for WZRD Agent Intel and the legacy earn loop on Solana.
4
+
5
+ **Before any x402 spend:** run `WZRD_INTEL_PREFLIGHT` (free ReadinessCard). Escalate to `WZRD_INTEL_TRUST` only when you need a signed V5 receipt. Verify offline with `WZRD_VERIFY_RECEIPT`.
4
6
 
5
7
  ## Install
6
8
 
@@ -10,52 +12,122 @@ npm install @wzrd_sol/eliza-plugin
10
12
 
11
13
  ## Configuration
12
14
 
13
- Set these in your ElizaOS runtime settings or environment:
14
-
15
15
  | Variable | Required | Default | Description |
16
16
  |----------|----------|---------|-------------|
17
- | `SOLANA_PRIVATE_KEY` | Yes (for tx) | | Base58 keypair for signing deposits/claims |
18
- | `WZRD_API_URL` | No | `https://api.twzrd.xyz` | WZRD backend endpoint |
19
- | `SOLANA_RPC_URL` | No | Helius mainnet | Solana RPC for on-chain reads |
17
+ | `WZRD_INTEL_URL` | No | `https://intel.twzrd.xyz` | Agent Intel API (preflight, trust, verify) |
18
+ | `WZRD_API_URL` | No | `https://api.twzrd.xyz` | Legacy earn API (infer/report/claim) |
19
+ | `SOLANA_PRIVATE_KEY` | Earn lane only | | JSON array of secret key bytes for agent Ed25519 auth |
20
+
21
+ ### Wiring a paying fetch (intel paid actions)
22
+
23
+ The plugin does **not** embed a wallet. Paid `WZRD_INTEL_TRUST` needs an x402-capable `fetch` from the host:
24
+
25
+ ```typescript
26
+ import { AgentRuntime } from '@elizaos/core';
27
+ import wzrdPlugin, { setPayingFetch } from '@wzrd_sol/eliza-plugin';
28
+ import { agentcashFetch } from 'your-x402-wrapper'; // agentcash, twzrd-x402-gate, etc.
29
+
30
+ setPayingFetch(agentcashFetch);
31
+
32
+ const agent = new AgentRuntime({
33
+ plugins: [wzrdPlugin],
34
+ settings: {
35
+ WZRD_INTEL_URL: 'https://intel.twzrd.xyz',
36
+ SOLANA_PRIVATE_KEY: process.env.SOLANA_PRIVATE_KEY,
37
+ },
38
+ });
39
+ ```
40
+
41
+ Without a paying fetch, `WZRD_INTEL_TRUST` returns the HTTP 402 requirements and an `npx agentcash@latest fetch ...` one-liner.
20
42
 
21
43
  ## Usage
22
44
 
23
45
  ```typescript
24
- import { wzrdPlugin } from "@wzrd_sol/eliza-plugin";
46
+ import { wzrdPlugin } from '@wzrd_sol/eliza-plugin';
25
47
 
26
- // Register with your ElizaOS agent
27
48
  const agent = new AgentRuntime({
28
49
  plugins: [wzrdPlugin],
29
- // ... other config
30
50
  });
31
51
  ```
32
52
 
33
- ## Actions
53
+ Programmatic SDK calls (same types as the plugin) are re-exported:
54
+
55
+ ```typescript
56
+ import { intelPreflight, fetchIntelTrust, verifyReceipt, IntelPaymentRequiredError } from '@wzrd_sol/eliza-plugin';
57
+ ```
58
+
59
+ ## Intel actions (primary)
60
+
61
+ | Action | Auth/Pay | Description |
62
+ |--------|----------|-------------|
63
+ | `WZRD_INTEL_PREFLIGHT` | Free | ReadinessCard: decision, trust_score, can_spend, caveats, paid upsell |
64
+ | `WZRD_INTEL_TRUST` | x402 (~0.05 USDC) | Paid trust payload + V5 `twzrd_receipt` (needs `setPayingFetch`) |
65
+ | `WZRD_VERIFY_RECEIPT` | Free (offline) | Recompute leaf + Ed25519 verify; no network when pubkey is known |
66
+
67
+ ### Example prompts
68
+
69
+ - "Preflight Jupiter Quote Preview before I pay 0.25 USDC to 6EF8rrect..."
70
+ - "Get the trust receipt for seller JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"
71
+ - "Verify this receipt: {leaf, preimage, signature...}"
72
+ - "Is it safe to call the paid intel endpoint on this seller?"
73
+
74
+ ### Free preflight (no wallet)
75
+
76
+ ```typescript
77
+ import { intelPreflightAction } from '@wzrd_sol/eliza-plugin';
78
+
79
+ // Handler reads seller_wallet / price_usdc / agent_intent from message content
80
+ await intelPreflightAction.handler(runtime, {
81
+ content: {
82
+ seller_wallet: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
83
+ price_usdc: 0.25,
84
+ agent_intent: 'quote preview',
85
+ },
86
+ }, ...);
87
+ ```
88
+
89
+ ## Legacy earn actions
34
90
 
35
91
  | Action | Auth | Description |
36
92
  |--------|------|-------------|
37
- | `WZRD_LEADERBOARD` | No | Fetch top markets ranked by velocity EMA |
38
- | `WZRD_VELOCITY` | No | Classify attention signal strength for a market |
39
- | `WZRD_PORTFOLIO` | Yes | View positions and accrued yield |
40
- | `WZRD_DEPOSIT` | Yes | Deposit USDC into an attention market, receive vLOFI |
41
- | `WZRD_CLAIM` | Yes | Claim accrued CCM via gasless relay or self-signed tx |
93
+ | `WZRD_INFER` | Agent Ed25519 | Server-witnessed inference; returns `execution_id` |
94
+ | `WZRD_REPORT` | Agent Ed25519 | Report outcome with `execution_id` for verified rewards |
95
+ | `WZRD_EARN` | Agent Ed25519 | Full infer report rewards check in one action |
96
+ | `WZRD_CLAIM` | Agent Ed25519 | Gasless CCM claim via relay |
97
+ | `WZRD_REWARDS` | Agent Ed25519 | Pending and lifetime CCM balance |
42
98
 
43
- ### Example prompts
99
+ ### Example prompts (earn)
44
100
 
45
- - "Show me the top WZRD markets"
46
- - "What's the velocity signal for market 6?"
47
- - "Check my WZRD portfolio"
48
- - "Deposit 1 USDC into market 3"
49
- - "Claim my CCM rewards"
101
+ - "Run inference through WZRD: explain quicksort in Python"
102
+ - "Earn some CCM on WZRD"
103
+ - "Check my WZRD rewards"
104
+ - "Claim my CCM"
105
+
106
+ ## Test
107
+
108
+ ```bash
109
+ cd agents/eliza-plugin
110
+ npm ci
111
+ npm run build
112
+ npm test
113
+ ```
114
+
115
+ `npm test` loads the plugin into a real `@elizaos/core` `AgentRuntime`, runs live free preflight against `intel.twzrd.xyz`, offline receipt verify, and a mocked paid trust path.
116
+
117
+ Manual earn smoke (requires `SOLANA_PRIVATE_KEY`):
118
+
119
+ ```bash
120
+ npx tsx test/earn-e2e.ts
121
+ ```
50
122
 
51
123
  ## Links
52
124
 
53
- - [WZRD Protocol](https://twzrd.xyz)
125
+ - [Agent Intel API](https://intel.twzrd.xyz)
126
+ - [Legacy API](https://api.twzrd.xyz)
54
127
  - [SDK](https://www.npmjs.com/package/@wzrd_sol/sdk)
55
- - [OpenAPI](https://twzrd.xyz/openapi.json)
56
- - [MCP Server](https://app.twzrd.xyz/api/mcp)
57
- - [Agent Discovery](https://twzrd.xyz/llms.txt)
128
+ - [twzrd-agent-intel (Python/MCP)](https://github.com/twzrd-sol/wzrd-final/tree/main/packages/twzrd-agent-intel)
129
+ - [Agent discovery](https://twzrd.xyz/llms.txt)
58
130
 
59
131
  ## License
60
132
 
61
- MIT
133
+ MIT
@@ -1,9 +1,6 @@
1
1
  /**
2
- * ELIZA Action: WZRD_CLAIM — claim accrued CCM via gasless relay (auth).
3
- *
4
- * Agents can check current APR before deciding whether to claim or hold:
5
- * WzrdClient.getMarketApr(marketId) — projected_total_apr_bps shows current yield rate.
6
- * WzrdClient.getMarketPreview(marketId) — projected_multiplier_bps for live attention signal.
2
+ * WZRD_CLAIM — Claim accrued CCM via gasless relay.
3
+ * Server pays all transaction fees. Agent needs 0 SOL.
7
4
  */
8
5
  import type { Action } from '@elizaos/core';
9
6
  export declare const claimAction: Action;
@@ -1,45 +1,48 @@
1
- import { getWzrdClient } from '../client.js';
1
+ import { getWzrdClient } from '../client-factory.js';
2
2
  export const claimAction = {
3
3
  name: 'WZRD_CLAIM',
4
- similes: ['WZRD_HARVEST', 'CLAIM_CCM', 'COLLECT_YIELD'],
5
- description: 'Claim accrued CCM tokens via gasless relay. Server pays tx fees.',
6
- examples: [[
4
+ similes: ['WZRD_HARVEST', 'CLAIM_CCM', 'COLLECT_REWARDS'],
5
+ description: 'Claim accrued CCM tokens via gasless relay. Server pays tx fees — agent needs 0 SOL.',
6
+ examples: [
7
+ [
7
8
  { name: '{{user1}}', content: { text: 'Claim my WZRD rewards' } },
8
- { name: '{{agentName}}', content: { text: 'Claimed CCM via gasless relay. Tx: 5S7L...' } },
9
- ]],
9
+ { name: '{{agentName}}', content: { text: 'Claimed 142.5 CCM via gasless relay. Tx: 5S7L...' } },
10
+ ],
11
+ ],
10
12
  validate: async () => true,
11
13
  handler: async (runtime, _msg, _state, _opt, callback) => {
12
14
  const client = getWzrdClient(runtime);
13
- let claims;
14
15
  try {
15
- claims = await client.getClaims();
16
+ // Check if there's anything to claim
17
+ const status = await client.getClaimStatus();
18
+ if (status.claimable <= 0) {
19
+ const text = `No CCM to claim right now.\n` +
20
+ `Cumulative: ${(status.cumulative_total / 1e9).toFixed(2)} CCM\n` +
21
+ `Already claimed: ${(status.claimed_total / 1e9).toFixed(2)} CCM\n` +
22
+ `Run WZRD_EARN first to accrue rewards.`;
23
+ await callback?.({ text });
24
+ return { success: true, data: status };
25
+ }
26
+ const result = await client.claimRelay();
27
+ if (result.status === 'already_claimed') {
28
+ await callback?.({ text: `Already claimed through root ${result.root_seq}.` });
29
+ return { success: true, data: result };
30
+ }
31
+ const text = `Claimed CCM via gasless relay.\n` +
32
+ `Amount: ${(result.cumulative_total / 1e9).toFixed(2)} CCM (cumulative)\n` +
33
+ `Root: ${result.root_seq}\n` +
34
+ `Tx: ${result.tx_sig?.slice(0, 20)}...`;
35
+ await callback?.({ text });
36
+ return { success: true, data: result };
16
37
  }
17
38
  catch (err) {
18
39
  const msg = err instanceof Error ? err.message : String(err);
19
40
  if (msg.includes('404')) {
20
- const text = 'No claims found. Deposit into a market first to start accruing CCM.';
21
- await callback?.({ text });
22
- return { success: true, text };
41
+ await callback?.({ text: 'No claims found yet. Run WZRD_EARN to start accruing CCM.' });
42
+ return { success: true, data: {} };
23
43
  }
24
- const text = `Failed to fetch claims: ${msg}`;
25
- await callback?.({ text });
26
- return { success: false, error: text };
27
- }
28
- const claimable = claims.cumulative_total - claims.claimed_total;
29
- if (claimable <= 0) {
30
- const text = `No CCM to claim. Cumulative: ${claims.cumulative_total}, claimed: ${claims.claimed_total}.`;
31
- await callback?.({ text });
32
- return { success: true, text, data: claims };
33
- }
34
- const result = await client.claimRelay();
35
- if (result.status === 'already_claimed') {
36
- const text = `Already claimed through root ${result.root_seq}.`;
37
- await callback?.({ text });
38
- return { success: true, text, data: result };
44
+ await callback?.({ text: `Claim failed: ${msg}` });
45
+ return { success: false, error: msg };
39
46
  }
40
- const text = `Claimed CCM via relay. Cumulative: ${(result.cumulative_total / 1e6).toFixed(4)} CCM. ` +
41
- `Root: ${result.root_seq}. Tx: ${result.tx_sig?.slice(0, 16)}...`;
42
- await callback?.({ text });
43
- return { success: true, text, data: result };
44
47
  },
45
48
  };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * WZRD_EARN — Full earn cycle: infer → report → check rewards.
3
+ *
4
+ * Single action that runs the complete server-witnessed earn loop.
5
+ * For agents that want one-shot earning without managing execution_ids.
6
+ */
7
+ import type { Action } from '@elizaos/core';
8
+ export declare const earnAction: Action;
@@ -0,0 +1,83 @@
1
+ import { getWzrdClient } from '../client-factory.js';
2
+ const EVAL_PROMPTS = {
3
+ code: [
4
+ 'Write a Python function that checks if a binary tree is balanced. Include time complexity analysis.',
5
+ 'Implement a thread-safe LRU cache in Rust with O(1) get and put operations.',
6
+ 'Write a TypeScript generic function that deep-merges two objects, handling arrays and nested objects.',
7
+ ],
8
+ chat: [
9
+ 'Explain the difference between TCP and UDP to someone who has never programmed before.',
10
+ 'What are the tradeoffs between microservices and monolithic architecture?',
11
+ 'Describe how consensus works in proof-of-stake blockchains.',
12
+ ],
13
+ reasoning: [
14
+ '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?',
15
+ 'If it takes 5 machines 5 minutes to make 5 widgets, how long does it take 100 machines to make 100 widgets?',
16
+ '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?',
17
+ ],
18
+ };
19
+ function pickPrompt(taskType) {
20
+ const prompts = EVAL_PROMPTS[taskType] || EVAL_PROMPTS.chat;
21
+ return prompts[Math.floor(Math.random() * prompts.length)];
22
+ }
23
+ export const earnAction = {
24
+ name: 'WZRD_EARN',
25
+ similes: ['WZRD_EARN_CCM', 'EARN_REWARDS', 'RUN_EARN_LOOP'],
26
+ description: 'Run the full WZRD earn cycle: pick a prompt, run server-witnessed inference, ' +
27
+ 'report the outcome, and check pending rewards. One action, complete loop.',
28
+ examples: [
29
+ [
30
+ { name: '{{user1}}', content: { text: 'Earn some CCM on WZRD' } },
31
+ {
32
+ name: '{{agentName}}',
33
+ content: {
34
+ text: 'Earn cycle complete. Model: gemini-2.5-flash, quality: 0.85, verified. Pending: 142.5 CCM.',
35
+ },
36
+ },
37
+ ],
38
+ ],
39
+ validate: async () => true,
40
+ handler: async (runtime, message, _state, _opt, callback) => {
41
+ const content = message.content;
42
+ const taskType = content.task_type || 'code';
43
+ const prompt = content.prompt || pickPrompt(taskType);
44
+ const client = getWzrdClient(runtime);
45
+ const steps = [];
46
+ try {
47
+ // Step 1: Pick model + Infer
48
+ steps.push('→ Picking model from leaderboard...');
49
+ const model = await client.pickModel(taskType);
50
+ steps.push(`→ Running inference: ${model} (${taskType})...`);
51
+ const infer = await client.infer(prompt, model, taskType);
52
+ steps.push(`✓ Inference: ${infer.executed_model} (${infer.provider}), quality ${infer.quality_score.toFixed(2)}, ${infer.latency_ms}ms`);
53
+ // Step 2: Report with execution_id
54
+ steps.push('→ Reporting outcome...');
55
+ const report = await client.report({
56
+ model_id: infer.requested_model,
57
+ execution_id: infer.execution_id,
58
+ task_type: taskType,
59
+ quality_score: infer.quality_score,
60
+ latency_ms: infer.latency_ms,
61
+ });
62
+ steps.push(`✓ Reported: ${report.verification_state}, contribution #${report.contribution_id}, pending ${(report.pending_ccm / 1e9).toFixed(2)} CCM`);
63
+ // Step 3: Check rewards
64
+ steps.push('→ Checking rewards...');
65
+ const rewards = await client.getRewards();
66
+ steps.push(`✓ Rewards: ${(rewards.pending_ccm / 1e9).toFixed(2)} CCM pending, ` +
67
+ `${(rewards.total_rewarded_ccm / 1e9).toFixed(2)} CCM lifetime` +
68
+ (rewards.rank ? `, rank #${rewards.rank}` : ''));
69
+ const text = `Earn cycle complete:\n${steps.join('\n')}`;
70
+ await callback?.({ text });
71
+ return {
72
+ success: true,
73
+ data: { infer, report, rewards },
74
+ };
75
+ }
76
+ catch (err) {
77
+ const msg = err instanceof Error ? err.message : String(err);
78
+ steps.push(`✗ Failed: ${msg}`);
79
+ await callback?.({ text: `Earn cycle failed:\n${steps.join('\n')}` });
80
+ return { success: false, error: msg };
81
+ }
82
+ },
83
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * WZRD_INFER — Server-witnessed inference through WZRD.
3
+ *
4
+ * WZRD calls the AI provider (Gemini/Nous/OpenRouter), grades the response,
5
+ * and returns an execution_id receipt. Pass this to WZRD_REPORT for verified rewards.
6
+ */
7
+ import type { Action } from '@elizaos/core';
8
+ export declare const inferAction: Action;
@@ -0,0 +1,41 @@
1
+ import { getWzrdClient } from '../client-factory.js';
2
+ export const inferAction = {
3
+ name: 'WZRD_INFER',
4
+ similes: ['WZRD_RUN_INFERENCE', 'ASK_MODEL', 'RUN_MODEL'],
5
+ description: 'Run inference through WZRD. The server calls the AI provider, grades quality, ' +
6
+ 'and returns an execution receipt. Use the execution_id with WZRD_REPORT to earn CCM.',
7
+ examples: [
8
+ [
9
+ { name: '{{user1}}', content: { text: 'Run inference through WZRD: explain quicksort in Python' } },
10
+ { name: '{{agentName}}', content: { text: 'Inference complete. Model: gemini-2.5-flash, quality: 0.85. execution_id: abc-123...' } },
11
+ ],
12
+ ],
13
+ validate: async () => true,
14
+ handler: async (runtime, message, _state, _opt, callback) => {
15
+ const content = message.content;
16
+ const prompt = content.prompt || content.text || '';
17
+ if (!prompt) {
18
+ await callback?.({ text: 'No prompt provided. Include a prompt or text to run inference.' });
19
+ return { success: false, error: 'No prompt' };
20
+ }
21
+ const taskType = content.task_type || 'chat';
22
+ const model = content.model;
23
+ const client = getWzrdClient(runtime);
24
+ try {
25
+ const result = await client.infer(prompt, model, taskType);
26
+ const text = `Inference complete.\n` +
27
+ `Model: ${result.executed_model} (${result.provider})\n` +
28
+ `Quality: ${result.quality_score.toFixed(2)}\n` +
29
+ `Latency: ${result.latency_ms}ms\n` +
30
+ `execution_id: ${result.execution_id}\n\n` +
31
+ `Response: ${result.response_preview}`;
32
+ await callback?.({ text });
33
+ return { success: true, data: result };
34
+ }
35
+ catch (err) {
36
+ const msg = err instanceof Error ? err.message : String(err);
37
+ await callback?.({ text: `Inference failed: ${msg}` });
38
+ return { success: false, error: msg };
39
+ }
40
+ },
41
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * WZRD_INTEL_PREFLIGHT — Free ReadinessCard before any x402 spend.
3
+ */
4
+ import type { Action } from '@elizaos/core';
5
+ export declare const intelPreflightAction: Action;
@@ -0,0 +1,97 @@
1
+ import { intelPreflight } from '@wzrd_sol/sdk';
2
+ import { getIntelBase, parsePreflightInput, withTimeout } from '../intel-helpers.js';
3
+ function isValidBase58Wallet(s) {
4
+ if (!s)
5
+ return false;
6
+ return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(s);
7
+ }
8
+ function validatePreflight(input) {
9
+ if (input.seller_wallet && !isValidBase58Wallet(input.seller_wallet))
10
+ return 'seller_wallet must be 32-44 char base58';
11
+ if (input.price_usdc != null && (input.price_usdc < 0 || !Number.isFinite(input.price_usdc)))
12
+ return 'price_usdc must be non-negative finite number';
13
+ if (input.resource_name && typeof input.resource_name !== 'string')
14
+ return 'resource_name must be string';
15
+ return null;
16
+ }
17
+ function formatCard(card, preflightId) {
18
+ const lines = [
19
+ `ReadinessCard v${card.version}`,
20
+ `Decision: ${card.decision}`,
21
+ `Trust score: ${card.trust_score ?? 'n/a'}`,
22
+ `Can spend: ${card.can_spend ? 'yes' : 'no'}`,
23
+ ];
24
+ if (preflightId)
25
+ lines.push(`Preflight ID: ${preflightId}`);
26
+ if (card.resource_name)
27
+ lines.push(`Resource: ${card.resource_name}`);
28
+ if (card.seller_wallet)
29
+ lines.push(`Seller: ${card.seller_wallet}`);
30
+ if (card.price_usdc != null)
31
+ lines.push(`Price: ${card.price_usdc} USDC`);
32
+ if (card.caveats?.length)
33
+ lines.push(`Caveats: ${card.caveats.join('; ')}`);
34
+ if (card.next_fixes?.length)
35
+ lines.push(`Next fixes: ${card.next_fixes.join('; ')}`);
36
+ if (card.paid_deep_dive) {
37
+ lines.push(`Paid deep dive available (${card.paid_price_usdc ?? 0.05} USDC) — use WZRD_INTEL_TRUST`);
38
+ }
39
+ return lines.join('\n');
40
+ }
41
+ export const intelPreflightAction = {
42
+ name: 'WZRD_INTEL_PREFLIGHT',
43
+ similes: ['WZRD_PREFLIGHT', 'INTEL_PREFLIGHT', 'READINESS_CARD'],
44
+ description: 'Free pre-spend ReadinessCard for a seller/resource/price/intent. Returns decision (allow/warn/block), ' +
45
+ 'trust_score, can_spend, caveats, paid_deep_dive upsell, and root_provenance when applicable. ' +
46
+ 'Run this before any x402 payment.',
47
+ examples: [
48
+ [
49
+ {
50
+ name: '{{user1}}',
51
+ content: {
52
+ text: 'Preflight Jupiter Quote Preview before I pay 0.25 USDC to 6EF8rrect...',
53
+ },
54
+ },
55
+ {
56
+ name: '{{agentName}}',
57
+ content: { text: 'ReadinessCard: decision ALLOW, trust_score 72, can_spend yes.' },
58
+ },
59
+ ],
60
+ ],
61
+ validate: async () => true,
62
+ handler: async (runtime, message, _state, _opt, callback) => {
63
+ const content = (message.content ?? {});
64
+ const input = parsePreflightInput(content);
65
+ if (!input.seller_wallet && !input.resource_name && !input.resource_url && !input.agent_intent) {
66
+ await callback?.({
67
+ text: 'Provide seller_wallet, resource_name, resource_url, or agent_intent for preflight. ' +
68
+ 'Example: "Preflight seller JUP6Lkb... at 0.25 USDC"',
69
+ });
70
+ return { success: false, error: 'Missing preflight input' };
71
+ }
72
+ const vErr = validatePreflight(input);
73
+ if (vErr) {
74
+ await callback?.({ text: `Invalid preflight input: ${vErr}` });
75
+ return { success: false, error: vErr };
76
+ }
77
+ const apiBase = getIntelBase(runtime);
78
+ try {
79
+ const res = await withTimeout(() => intelPreflight(input, apiBase));
80
+ const card = res.readiness_card;
81
+ if (!card) {
82
+ const text = `Preflight OK (legacy). decision=${res.decision ?? 'unknown'}, score=${res.trust_score ?? 'n/a'}`;
83
+ await callback?.({ text });
84
+ return { success: true, data: res };
85
+ }
86
+ const preflightId = res.preflight_id;
87
+ const text = formatCard(card, preflightId);
88
+ await callback?.({ text });
89
+ return { success: true, data: { ...res, readiness_card: card } };
90
+ }
91
+ catch (err) {
92
+ const msg = err instanceof Error ? err.message : String(err);
93
+ await callback?.({ text: `Preflight failed: ${msg}` });
94
+ return { success: false, error: msg };
95
+ }
96
+ },
97
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * WZRD_INTEL_TRUST — Paid trust payload + signed receipt (V5/V6) via x402-capable
3
+ * fetch. Preflight-gated: the free ReadinessCard runs BEFORE the payment and a
4
+ * decision=block aborts before any spend (the protocol's preflight-before-pay rule).
5
+ */
6
+ import type { Action } from '@elizaos/core';
7
+ export declare const intelTrustAction: Action;
@@ -0,0 +1,82 @@
1
+ import { fetchIntelTrust, preSpendGate, IntelPaymentRequiredError } from '@wzrd_sol/sdk';
2
+ import { extractPubkey, formatPaymentRequired, getIntelBase, withTimeout } from '../intel-helpers.js';
3
+ import { resolvePayingFetch } from '../paying-fetch.js';
4
+ export const intelTrustAction = {
5
+ name: 'WZRD_INTEL_TRUST',
6
+ similes: ['WZRD_TRUST_RECEIPT', 'INTEL_TRUST', 'GET_TRUST_RECEIPT'],
7
+ description: 'Paid GET /v1/intel/trust/{pubkey} (~0.05 USDC). Returns trust score + signed twzrd_receipt (V5/V6). ' +
8
+ 'Runs the free preflight first and aborts on decision=block before spending. ' +
9
+ 'Requires an x402-capable fetchImpl (setPayingFetch or host service). ' +
10
+ 'Surfaces payment requirements if no payer is configured.',
11
+ examples: [
12
+ [
13
+ { name: '{{user1}}', content: { text: 'Get the trust receipt for seller JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4' } },
14
+ { name: '{{agentName}}', content: { text: 'Trust receipt received. score=42, receipt leaf=0x...' } },
15
+ ],
16
+ ],
17
+ validate: async () => true,
18
+ handler: async (runtime, message, _state, _opt, callback) => {
19
+ const content = (message.content ?? {});
20
+ const pubkey = extractPubkey(content);
21
+ if (!pubkey) {
22
+ await callback?.({ text: 'Provide a seller pubkey (32-44 char base58) for trust lookup.' });
23
+ return { success: false, error: 'Missing pubkey' };
24
+ }
25
+ const apiBase = getIntelBase(runtime);
26
+ const baseFetchImpl = resolvePayingFetch(runtime);
27
+ // preflight-before-pay: run the FREE ReadinessCard on the counterparty and
28
+ // abort on decision=block BEFORE any payment is signed/sent. failOpen=false so
29
+ // the block-on-block guarantee holds even if the gate errors — a reference
30
+ // plugin must demonstrate the safe posture, not bypass it. The preflight call
31
+ // is free (the gate only ever reads), so this adds no spend.
32
+ try {
33
+ const gate = await preSpendGate({ seller_wallet: pubkey }, { apiBase, failOpen: false, fetchImpl: baseFetchImpl });
34
+ if (!gate.allow) {
35
+ await callback?.({
36
+ text: `Preflight blocked the trust purchase for ${pubkey}.\n` +
37
+ `Decision: ${gate.decision}${gate.trustScore != null ? `, trust_score=${gate.trustScore}` : ''}\n` +
38
+ `Reason: ${gate.reason}\n` +
39
+ `No payment was sent.`,
40
+ });
41
+ return {
42
+ success: false,
43
+ error: 'preflight_block',
44
+ data: { decision: gate.decision, trustScore: gate.trustScore, reason: gate.reason },
45
+ };
46
+ }
47
+ }
48
+ catch (gateErr) {
49
+ // failOpen=false means a gate error should NOT silently pay. Surface it and stop.
50
+ const msg = gateErr instanceof Error ? gateErr.message : String(gateErr);
51
+ await callback?.({ text: `Preflight gate unavailable (${msg}); not spending. Try again shortly.` });
52
+ return { success: false, error: 'preflight_unavailable', data: { detail: msg } };
53
+ }
54
+ try {
55
+ const res = await withTimeout((signal) => {
56
+ const abortingFetch = ((input, init) => baseFetchImpl(input, { ...(init || {}), signal }));
57
+ return fetchIntelTrust(pubkey, { apiBase, fetchImpl: abortingFetch });
58
+ });
59
+ const receipt = res.twzrd_receipt;
60
+ const text = `Trust payload for ${pubkey}\n` +
61
+ `Score: ${res.trust?.score ?? 'n/a'}\n` +
62
+ `Paid: ${res.paid ? 'yes' : 'no'}\n` +
63
+ (res.tx ? `Settlement tx: ${res.tx}\n` : '') +
64
+ (receipt
65
+ ? `Receipt v${receipt.version}, leaf: ${receipt.leaf}\n` +
66
+ `Use WZRD_VERIFY_RECEIPT to verify offline.`
67
+ : 'No twzrd_receipt in response.');
68
+ await callback?.({ text });
69
+ return { success: true, data: res };
70
+ }
71
+ catch (err) {
72
+ if (err instanceof IntelPaymentRequiredError) {
73
+ const text = formatPaymentRequired(err, apiBase, pubkey);
74
+ await callback?.({ text });
75
+ return { success: false, error: 'payment_required', data: { paymentRequirements: err.paymentRequirements } };
76
+ }
77
+ const msg = err instanceof Error ? err.message : String(err);
78
+ await callback?.({ text: `Intel trust failed: ${msg}` });
79
+ return { success: false, error: msg };
80
+ }
81
+ },
82
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * WZRD_REPORT — Report a model pick with execution receipt for verified CCM rewards.
3
+ *
4
+ * Must be called after WZRD_INFER. Pass the execution_id from the infer result
5
+ * to get server-verified status and quality-weighted rewards.
6
+ */
7
+ import type { Action } from '@elizaos/core';
8
+ export declare const reportAction: Action;
@@ -0,0 +1,45 @@
1
+ import { getWzrdClient } from '../client-factory.js';
2
+ export const reportAction = {
3
+ name: 'WZRD_REPORT',
4
+ similes: ['WZRD_REPORT_OUTCOME', 'REPORT_MODEL_PICK', 'SUBMIT_SIGNAL'],
5
+ description: 'Report a model pick to WZRD with an execution_id from WZRD_INFER. ' +
6
+ 'Verified reports earn CCM rewards with quality multiplier.',
7
+ examples: [
8
+ [
9
+ { name: '{{user1}}', content: { text: 'Report the inference result to earn CCM' } },
10
+ { name: '{{agentName}}', content: { text: 'Reported. Verification: verified, contribution #4521.' } },
11
+ ],
12
+ ],
13
+ validate: async () => true,
14
+ handler: async (runtime, message, _state, _opt, callback) => {
15
+ const content = message.content;
16
+ if (!content.execution_id || !content.model_id) {
17
+ await callback?.({
18
+ text: 'Missing required: execution_id and model_id. Run WZRD_INFER first to get an execution receipt.',
19
+ });
20
+ return { success: false, error: 'Missing execution_id or model_id' };
21
+ }
22
+ const client = getWzrdClient(runtime);
23
+ try {
24
+ const result = await client.report({
25
+ model_id: content.model_id,
26
+ execution_id: content.execution_id,
27
+ task_type: content.task_type,
28
+ quality_score: content.quality_score,
29
+ latency_ms: content.latency_ms,
30
+ });
31
+ const text = `Reported to WZRD.\n` +
32
+ `Verification: ${result.verification_state}\n` +
33
+ `Contribution: #${result.contribution_id}\n` +
34
+ `Pending CCM: ${(result.pending_ccm / 1e9).toFixed(2)}\n` +
35
+ `Pipeline: ${result.pipeline_state}`;
36
+ await callback?.({ text });
37
+ return { success: true, data: result };
38
+ }
39
+ catch (err) {
40
+ const msg = err instanceof Error ? err.message : String(err);
41
+ await callback?.({ text: `Report failed: ${msg}` });
42
+ return { success: false, error: msg };
43
+ }
44
+ },
45
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * WZRD_REWARDS — Check pending and lifetime CCM rewards.
3
+ */
4
+ import type { Action } from '@elizaos/core';
5
+ export declare const rewardsAction: Action;