@wzrd_sol/eliza-plugin 0.3.1 → 0.3.3
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 +165 -56
- package/dist/actions/intel-preflight.js +2 -2
- package/dist/actions/intel-trust.d.ts +2 -2
- package/dist/actions/intel-trust.js +31 -16
- package/dist/actions/merchant-card.d.ts +6 -0
- package/dist/actions/merchant-card.js +85 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +5 -7
- package/dist/index.d.ts +6 -4
- package/dist/index.js +7 -5
- package/dist/intel-helpers.js +7 -3
- package/dist/test/plugin-registration.intel.js +94 -13
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# @wzrd_sol/eliza-plugin
|
|
2
2
|
|
|
3
|
-
ElizaOS plugin for WZRD Agent Intel
|
|
3
|
+
ElizaOS plugin for WZRD Agent Intel — x402 firewall, free preflight checks before spends,
|
|
4
|
+
paid trust receipts (V6 + ERC-8004), and the earn loop on Solana.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
## 3-line quickstart
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
import wzrdPlugin from '@wzrd_sol/eliza-plugin';
|
|
10
|
+
const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
11
|
+
// "Preflight seller JUP6Lkb... at 0.25 USDC" → allow/warn/block, free, no wallet
|
|
12
|
+
```
|
|
6
13
|
|
|
7
14
|
## Install
|
|
8
15
|
|
|
@@ -15,93 +22,194 @@ npm install @wzrd_sol/eliza-plugin
|
|
|
15
22
|
| Variable | Required | Default | Description |
|
|
16
23
|
|----------|----------|---------|-------------|
|
|
17
24
|
| `WZRD_INTEL_URL` | No | `https://intel.twzrd.xyz` | Agent Intel API (preflight, trust, verify) |
|
|
18
|
-
| `WZRD_API_URL` | No | `https://api.twzrd.xyz` |
|
|
25
|
+
| `WZRD_API_URL` | No | `https://api.twzrd.xyz` | Earn API (infer/report/claim) |
|
|
19
26
|
| `SOLANA_PRIVATE_KEY` | Earn lane only | — | JSON array of secret key bytes for agent Ed25519 auth |
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
## Intel actions (primary)
|
|
22
29
|
|
|
23
|
-
|
|
30
|
+
| Action | Auth/Pay | Description |
|
|
31
|
+
|--------|----------|-------------|
|
|
32
|
+
| `WZRD_INTEL_PREFLIGHT` | Free | ReadinessCard: `decision`, `trust_score`, `can_spend`, `caveats`, `preflight_id` |
|
|
33
|
+
| `WZRD_MERCHANT_CARD` | Free | Graph card: `wash_flagged`, tier, catalog join; default refuse if wash |
|
|
34
|
+
| `WZRD_INTEL_TRUST` | x402 (~0.05 USDC) | Paid trust payload + V6 signed receipt + ERC-8004 `reputation_credential` |
|
|
35
|
+
| `WZRD_VERIFY_RECEIPT` | Free (offline) | Recompute leaf + Ed25519 verify; no network when pubkey is known |
|
|
24
36
|
|
|
25
|
-
|
|
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.
|
|
37
|
+
### Preflight (free, no wallet)
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
```typescript
|
|
40
|
+
import { intelPreflightAction } from '@wzrd_sol/eliza-plugin';
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
// Reads seller_wallet / price_usdc / agent_intent from message content.
|
|
43
|
+
await intelPreflightAction.handler(runtime, {
|
|
44
|
+
content: {
|
|
45
|
+
seller_wallet: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
|
|
46
|
+
price_usdc: 0.25,
|
|
47
|
+
agent_intent: 'quote preview',
|
|
37
48
|
},
|
|
38
|
-
});
|
|
49
|
+
}, state, opts, callback);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Response (formatted text returned to agent):
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
ReadinessCard v1
|
|
56
|
+
Decision: allow
|
|
57
|
+
Trust score: 72
|
|
58
|
+
Can spend: yes
|
|
59
|
+
Preflight ID: pf_abc123
|
|
60
|
+
Paid deep dive available (0.05 USDC) — use WZRD_INTEL_TRUST
|
|
39
61
|
```
|
|
40
62
|
|
|
41
|
-
|
|
63
|
+
### Guard pattern: fire-before-pay with `withTwzrdGuard`
|
|
42
64
|
|
|
43
|
-
|
|
65
|
+
For agents that call x402-gated URLs directly (not via pre-known seller wallet), pair this
|
|
66
|
+
plugin with `twzrd-x402-gate` to intercept 402s before any spend:
|
|
44
67
|
|
|
45
68
|
```typescript
|
|
46
|
-
import
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
69
|
+
import wzrdPlugin from '@wzrd_sol/eliza-plugin';
|
|
70
|
+
import { withTwzrdGuard } from 'twzrd-x402-gate';
|
|
71
|
+
import { createAgentcashFetch } from 'agentcash';
|
|
72
|
+
|
|
73
|
+
// Wrap the paying fetch — guard runs preflight on every 402 before USDC moves.
|
|
74
|
+
const x402Fetch = createAgentcashFetch({ apiKey: process.env.AGENTCASH_API_KEY });
|
|
75
|
+
const safeFetch = withTwzrdGuard(x402Fetch, {
|
|
76
|
+
autoReceipt: true, // auto-buy $0.05 TWZRD receipt on warn/allow
|
|
77
|
+
x402Fetch,
|
|
50
78
|
});
|
|
79
|
+
|
|
80
|
+
// Wire safeFetch into any tool or skill that calls paid resources:
|
|
81
|
+
const response = await safeFetch('https://api.exa.ai/search');
|
|
82
|
+
// → decision=block throws before payment
|
|
83
|
+
// → decision=warn/allow: payment proceeds, TWZRD receipt captured
|
|
51
84
|
```
|
|
52
85
|
|
|
53
|
-
|
|
86
|
+
Guard flow:
|
|
87
|
+
1. `safeFetch` hits the resource, gets HTTP 402.
|
|
88
|
+
2. `withTwzrdGuard` reads `accepts[0].payTo` (seller wallet).
|
|
89
|
+
3. Calls `POST /v1/intel/preflight` — free, no auth.
|
|
90
|
+
4. `block` - throws, no payment made.
|
|
91
|
+
5. `warn/allow` - returns the 402 for the x402 client to pay.
|
|
92
|
+
|
|
93
|
+
### Pre-spend gate (programmatic)
|
|
54
94
|
|
|
55
95
|
```typescript
|
|
56
|
-
import {
|
|
96
|
+
import { preSpendGate, fetchIntelTrust, fetchMerchantCard } from '@wzrd_sol/eliza-plugin';
|
|
97
|
+
|
|
98
|
+
// Gate before paying (free preflight + free merchant_card wash refuse, default on):
|
|
99
|
+
const gate = await preSpendGate({ seller_wallet: sellerPubkey, price_usdc: 0.25 });
|
|
100
|
+
if (!gate.allow) return `Blocked (${gate.decision}): ${gate.reason}`;
|
|
101
|
+
// gate.washFlagged === true was refuse default; null = card gap (fail-open)
|
|
102
|
+
|
|
103
|
+
// Or inspect the card alone:
|
|
104
|
+
const card = await fetchMerchantCard(sellerPubkey);
|
|
105
|
+
if (card?.wash_flagged) return 'refuse dirty pay_to';
|
|
106
|
+
|
|
107
|
+
// Then pay and get the receipt:
|
|
108
|
+
const trust = await fetchIntelTrust(sellerPubkey, { fetchImpl: myX402Fetch });
|
|
57
109
|
```
|
|
58
110
|
|
|
59
|
-
|
|
111
|
+
**Default:** `refuseWashFlagged: true` — if free `merchant_card.wash_flagged`, do not pay.
|
|
112
|
+
Soft cap: `{ washMaxUsdc: 0.05 }`. Opt out: `{ refuseWashFlagged: false }`.
|
|
60
113
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
114
|
+
### Paid trust receipt (agentcash)
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import wzrdPlugin, { setPayingFetch } from '@wzrd_sol/eliza-plugin';
|
|
118
|
+
import { createAgentcashFetch } from 'agentcash';
|
|
66
119
|
|
|
67
|
-
|
|
120
|
+
setPayingFetch(createAgentcashFetch({ apiKey: process.env.AGENTCASH_API_KEY }));
|
|
68
121
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
122
|
+
const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
123
|
+
// "Get the trust receipt for seller JUP6LkbZ..."
|
|
124
|
+
// → WZRD_INTEL_TRUST: runs free preflight, pays $0.05 USDC, returns VC
|
|
125
|
+
```
|
|
73
126
|
|
|
74
|
-
###
|
|
127
|
+
### Paid trust receipt (PayAI)
|
|
75
128
|
|
|
76
129
|
```typescript
|
|
77
|
-
import {
|
|
130
|
+
import wzrdPlugin, { setPayingFetch } from '@wzrd_sol/eliza-plugin';
|
|
131
|
+
import { PayAIClient } from '@payai/client';
|
|
78
132
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
133
|
+
const payai = new PayAIClient({ keypairPath: '~/.config/solana/id.json' });
|
|
134
|
+
setPayingFetch((url, init) => payai.fetch(url, init));
|
|
135
|
+
|
|
136
|
+
const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Without a paying fetch, `WZRD_INTEL_TRUST` returns the HTTP 402 requirements and an
|
|
140
|
+
`npx agentcash@latest fetch ...` one-liner to pay manually.
|
|
141
|
+
|
|
142
|
+
**`WZRD_INTEL_TRUST` response fields:**
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
Trust payload for JUP6Lkb...
|
|
146
|
+
Score: 61.8 Paid: yes
|
|
147
|
+
Settlement tx: 4xK3n...
|
|
148
|
+
Reputation credential (ERC-8004 AgentReputationCredential):
|
|
149
|
+
effectiveTrustScore: 62 <- route on this (wash-adjusted)
|
|
150
|
+
trustScore: 72 washFactor: 0.86
|
|
151
|
+
distinctCounterparties: 14 <- cross-facilitator breadth
|
|
152
|
+
corpusScope: cross-facilitator
|
|
153
|
+
version: intel_renorm_v1
|
|
154
|
+
Routing gate: effectiveTrustScore < 30 -> block, 30-60 -> warn, > 60 -> allow
|
|
155
|
+
Receipt v6, leaf: 0x3a4f...
|
|
156
|
+
Use WZRD_VERIFY_RECEIPT to verify offline.
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Routing logic:**
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const vc = trust.reputation_credential.credentialSubject;
|
|
163
|
+
if (vc.effectiveTrustScore < 30) return 'block';
|
|
164
|
+
if (vc.distinctCounterparties < 3) return 'warn'; // thin history
|
|
165
|
+
if (vc.washFactor < 0.5) return 'warn'; // suspicious ring
|
|
87
166
|
```
|
|
88
167
|
|
|
168
|
+
`effectiveTrustScore` is the cross-facilitator wash-adjusted score — computed across all known
|
|
169
|
+
x402 facilitators, not just one settlement path.
|
|
170
|
+
|
|
171
|
+
### Example agent prompts (trust)
|
|
172
|
+
|
|
173
|
+
- `"Preflight Jupiter Quote Preview before I pay 0.25 USDC to 6EF8rrect..."`
|
|
174
|
+
- `"Get the trust receipt for seller JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"`
|
|
175
|
+
- `"Is it safe to call the paid intel endpoint on this seller?"`
|
|
176
|
+
- `"Verify this receipt: {leaf, preimage, signature...}"`
|
|
177
|
+
|
|
89
178
|
## Legacy earn actions
|
|
90
179
|
|
|
91
180
|
| Action | Auth | Description |
|
|
92
181
|
|--------|------|-------------|
|
|
93
182
|
| `WZRD_INFER` | Agent Ed25519 | Server-witnessed inference; returns `execution_id` |
|
|
94
183
|
| `WZRD_REPORT` | Agent Ed25519 | Report outcome with `execution_id` for verified rewards |
|
|
95
|
-
| `WZRD_EARN` | Agent Ed25519 | Full infer
|
|
184
|
+
| `WZRD_EARN` | Agent Ed25519 | Full infer -> report -> rewards check in one action |
|
|
96
185
|
| `WZRD_CLAIM` | Agent Ed25519 | Gasless CCM claim via relay |
|
|
97
186
|
| `WZRD_REWARDS` | Agent Ed25519 | Pending and lifetime CCM balance |
|
|
98
187
|
|
|
99
188
|
### Example prompts (earn)
|
|
100
189
|
|
|
101
|
-
- "Run inference through WZRD: explain quicksort in Python"
|
|
102
|
-
- "Earn some CCM on WZRD"
|
|
103
|
-
- "Check my WZRD rewards"
|
|
104
|
-
- "Claim my CCM"
|
|
190
|
+
- `"Run inference through WZRD: explain quicksort in Python"`
|
|
191
|
+
- `"Earn some CCM on WZRD"`
|
|
192
|
+
- `"Check my WZRD rewards"`
|
|
193
|
+
- `"Claim my CCM"`
|
|
194
|
+
|
|
195
|
+
## Programmatic SDK usage
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import {
|
|
199
|
+
intelPreflight,
|
|
200
|
+
fetchIntelTrust,
|
|
201
|
+
verifyReceipt,
|
|
202
|
+
preSpendGate,
|
|
203
|
+
IntelPaymentRequiredError,
|
|
204
|
+
} from '@wzrd_sol/eliza-plugin';
|
|
205
|
+
|
|
206
|
+
import type {
|
|
207
|
+
ReadinessCard,
|
|
208
|
+
PreflightResponse,
|
|
209
|
+
IntelTrustResponse,
|
|
210
|
+
TwzrdReceipt,
|
|
211
|
+
} from '@wzrd_sol/eliza-plugin';
|
|
212
|
+
```
|
|
105
213
|
|
|
106
214
|
## Test
|
|
107
215
|
|
|
@@ -112,7 +220,8 @@ npm run build
|
|
|
112
220
|
npm test
|
|
113
221
|
```
|
|
114
222
|
|
|
115
|
-
`npm test`
|
|
223
|
+
`npm test` runs live free preflight against `intel.twzrd.xyz`, offline receipt verify, and a
|
|
224
|
+
mocked paid trust path.
|
|
116
225
|
|
|
117
226
|
Manual earn smoke (requires `SOLANA_PRIVATE_KEY`):
|
|
118
227
|
|
|
@@ -123,11 +232,11 @@ npx tsx test/earn-e2e.ts
|
|
|
123
232
|
## Links
|
|
124
233
|
|
|
125
234
|
- [Agent Intel API](https://intel.twzrd.xyz)
|
|
126
|
-
- [
|
|
127
|
-
- [
|
|
128
|
-
- [
|
|
129
|
-
- [
|
|
235
|
+
- [API docs / llms.txt](https://intel.twzrd.xyz/llms.txt)
|
|
236
|
+
- [x402 gate (standalone firewall)](https://www.npmjs.com/package/twzrd-x402-gate)
|
|
237
|
+
- [GOAT plugin](https://www.npmjs.com/package/@wzrd_sol/goat-plugin)
|
|
238
|
+
- [TWZRD trust quickstart](https://intel.twzrd.xyz/docs/QUICKSTART.md)
|
|
130
239
|
|
|
131
240
|
## License
|
|
132
241
|
|
|
133
|
-
MIT
|
|
242
|
+
MIT
|
|
@@ -62,9 +62,9 @@ export const intelPreflightAction = {
|
|
|
62
62
|
handler: async (runtime, message, _state, _opt, callback) => {
|
|
63
63
|
const content = (message.content ?? {});
|
|
64
64
|
const input = parsePreflightInput(content);
|
|
65
|
-
if (!input.seller_wallet && !input.resource_name && !input.resource_url
|
|
65
|
+
if (!input.seller_wallet && !input.resource_name && !input.resource_url) {
|
|
66
66
|
await callback?.({
|
|
67
|
-
text: 'Provide seller_wallet, resource_name,
|
|
67
|
+
text: 'Provide seller_wallet, resource_name, or resource_url for preflight. ' +
|
|
68
68
|
'Example: "Preflight seller JUP6Lkb... at 0.25 USDC"',
|
|
69
69
|
});
|
|
70
70
|
return { success: false, error: 'Missing preflight input' };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WZRD_INTEL_TRUST — Paid trust payload + signed receipt (V5/V6) via x402-capable
|
|
3
|
-
* fetch. Preflight-gated:
|
|
4
|
-
* decision=block aborts before any spend
|
|
3
|
+
* fetch. Preflight-gated: free ReadinessCard + free merchant_card wash check run
|
|
4
|
+
* BEFORE payment; decision=block or wash_flagged aborts before any spend.
|
|
5
5
|
*/
|
|
6
6
|
import type { Action } from '@elizaos/core';
|
|
7
7
|
export declare const intelTrustAction: Action;
|
|
@@ -5,7 +5,7 @@ export const intelTrustAction = {
|
|
|
5
5
|
name: 'WZRD_INTEL_TRUST',
|
|
6
6
|
similes: ['WZRD_TRUST_RECEIPT', 'INTEL_TRUST', 'GET_TRUST_RECEIPT'],
|
|
7
7
|
description: 'Paid GET /v1/intel/trust/{pubkey} (~0.05 USDC). Returns trust score + signed twzrd_receipt (V5/V6). ' +
|
|
8
|
-
'Runs
|
|
8
|
+
'Runs free preflight + merchant_card wash check first; aborts on decision=block or wash_flagged. ' +
|
|
9
9
|
'Requires an x402-capable fetchImpl (setPayingFetch or host service). ' +
|
|
10
10
|
'Surfaces payment requirements if no payer is configured.',
|
|
11
11
|
examples: [
|
|
@@ -24,24 +24,32 @@ export const intelTrustAction = {
|
|
|
24
24
|
}
|
|
25
25
|
const apiBase = getIntelBase(runtime);
|
|
26
26
|
const baseFetchImpl = resolvePayingFetch(runtime);
|
|
27
|
-
// preflight-before-pay
|
|
28
|
-
//
|
|
27
|
+
// preflight-before-pay + wash refuse: FREE ReadinessCard + free merchant_card.
|
|
28
|
+
// Abort on decision=block or wash_flagged before any payment. failOpen=false so
|
|
29
29
|
// the block-on-block guarantee holds even if the gate errors — a reference
|
|
30
|
-
// plugin must demonstrate the safe posture, not bypass it.
|
|
31
|
-
// is free (the gate only ever reads), so this adds no spend.
|
|
30
|
+
// plugin must demonstrate the safe posture, not bypass it. Free reads only.
|
|
32
31
|
try {
|
|
33
|
-
const gate = await preSpendGate({ seller_wallet: pubkey }, { apiBase, failOpen: false, fetchImpl: baseFetchImpl });
|
|
32
|
+
const gate = await preSpendGate({ seller_wallet: pubkey }, { apiBase, failOpen: false, refuseWashFlagged: true, fetchImpl: baseFetchImpl });
|
|
34
33
|
if (!gate.allow) {
|
|
34
|
+
const washLine = gate.washFlagged === true
|
|
35
|
+
? `Wash flagged: yes (merchant_card refuse default)\n`
|
|
36
|
+
: '';
|
|
35
37
|
await callback?.({
|
|
36
38
|
text: `Preflight blocked the trust purchase for ${pubkey}.\n` +
|
|
37
39
|
`Decision: ${gate.decision}${gate.trustScore != null ? `, trust_score=${gate.trustScore}` : ''}\n` +
|
|
40
|
+
washLine +
|
|
38
41
|
`Reason: ${gate.reason}\n` +
|
|
39
42
|
`No payment was sent.`,
|
|
40
43
|
});
|
|
41
44
|
return {
|
|
42
45
|
success: false,
|
|
43
|
-
error: 'preflight_block',
|
|
44
|
-
data: {
|
|
46
|
+
error: gate.washFlagged === true ? 'wash_flagged' : 'preflight_block',
|
|
47
|
+
data: {
|
|
48
|
+
decision: gate.decision,
|
|
49
|
+
trustScore: gate.trustScore,
|
|
50
|
+
reason: gate.reason,
|
|
51
|
+
washFlagged: gate.washFlagged ?? null,
|
|
52
|
+
},
|
|
45
53
|
};
|
|
46
54
|
}
|
|
47
55
|
}
|
|
@@ -57,14 +65,21 @@ export const intelTrustAction = {
|
|
|
57
65
|
return fetchIntelTrust(pubkey, { apiBase, fetchImpl: abortingFetch });
|
|
58
66
|
});
|
|
59
67
|
const receipt = res.twzrd_receipt;
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
`
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
const vc = res.reputation_credential?.credentialSubject;
|
|
69
|
+
const lines = [
|
|
70
|
+
`Trust payload for ${pubkey}`,
|
|
71
|
+
`Score: ${res.trust?.score ?? 'n/a'} Paid: ${res.paid ? 'yes' : 'no'}`,
|
|
72
|
+
];
|
|
73
|
+
const settleTx = res.tx ?? res.tx_pending;
|
|
74
|
+
if (settleTx)
|
|
75
|
+
lines.push(`Settlement tx${res.tx ? '' : ' (pending)'}: ${settleTx}`);
|
|
76
|
+
if (vc) {
|
|
77
|
+
lines.push(`Reputation credential (ERC-8004 AgentReputationCredential):`, ` effectiveTrustScore: ${vc.effectiveTrustScore ?? 'n/a'}`, ` trustScore: ${vc.trustScore ?? 'n/a'} washFactor: ${vc.washFactor ?? 'n/a'}`, ` distinctCounterparties: ${vc.distinctCounterparties ?? 'n/a'}`, ` corpusScope: ${vc.corpusScope ?? 'n/a'}`, ` version: ${vc.trustScoreVersion ?? 'n/a'}`, `Routing gate: effectiveTrustScore < 30 → block, 30-60 → warn, > 60 → allow`);
|
|
78
|
+
}
|
|
79
|
+
lines.push(receipt
|
|
80
|
+
? `Receipt v${receipt.version}, leaf: ${receipt.leaf}\nUse WZRD_VERIFY_RECEIPT to verify offline.`
|
|
81
|
+
: 'No twzrd_receipt in response.');
|
|
82
|
+
const text = lines.join('\n');
|
|
68
83
|
await callback?.({ text });
|
|
69
84
|
return { success: true, data: res };
|
|
70
85
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { fetchMerchantCard } from '@wzrd_sol/sdk';
|
|
2
|
+
import { extractPubkey, getIntelBase, withTimeout } from '../intel-helpers.js';
|
|
3
|
+
function formatMerchantCard(card) {
|
|
4
|
+
const lines = [
|
|
5
|
+
`Merchant card for ${card.merchant ?? 'unknown'}`,
|
|
6
|
+
`In corpus: ${card.in_corpus ? 'yes' : 'no'}`,
|
|
7
|
+
`Wash flagged: ${card.wash_flagged === true ? 'YES — default refuse pay' : card.wash_flagged === false ? 'no' : 'unknown'}`,
|
|
8
|
+
];
|
|
9
|
+
if (card.wash_label)
|
|
10
|
+
lines.push(`Wash label: ${card.wash_label}`);
|
|
11
|
+
if (card.provider_reputation_tier)
|
|
12
|
+
lines.push(`Tier: ${card.provider_reputation_tier}`);
|
|
13
|
+
if (card.unique_payers_90d != null)
|
|
14
|
+
lines.push(`Unique payers (90d): ${card.unique_payers_90d}`);
|
|
15
|
+
if (card.offering_status)
|
|
16
|
+
lines.push(`Offering: ${card.offering_status}`);
|
|
17
|
+
if (card.catalog_enriched) {
|
|
18
|
+
const name = card.catalog && typeof card.catalog === 'object' && 'name' in card.catalog
|
|
19
|
+
? String(card.catalog.name ?? '')
|
|
20
|
+
: '';
|
|
21
|
+
lines.push(`Catalog enriched: yes${name ? ` (${name})` : ''} — listing only, not quality proof`);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
lines.push('Catalog enriched: no (graph only)');
|
|
25
|
+
}
|
|
26
|
+
if (card.wash_flagged === true) {
|
|
27
|
+
lines.push('Policy: do not pay this pay_to (trustless default). Cap only if operator set washMaxUsdc.');
|
|
28
|
+
}
|
|
29
|
+
return lines.join('\n');
|
|
30
|
+
}
|
|
31
|
+
export const merchantCardAction = {
|
|
32
|
+
name: 'WZRD_MERCHANT_CARD',
|
|
33
|
+
similes: ['WZRD_MERCHANT', 'MERCHANT_CARD', 'INTEL_MERCHANT_CARD', 'CHECK_WASH'],
|
|
34
|
+
description: 'Free GET merchant demand-quality card for a Solana receive wallet (no auth). ' +
|
|
35
|
+
'Returns wash_flagged, tier, unique payers, catalog join when listed. ' +
|
|
36
|
+
'Default: if wash_flagged is true, do not pay that pay_to.',
|
|
37
|
+
examples: [
|
|
38
|
+
[
|
|
39
|
+
{
|
|
40
|
+
name: '{{user1}}',
|
|
41
|
+
content: { text: 'Merchant card for 7G73dUxj8Qn4yH4x9zXkKqZ8oKqZ8oKqZ8o' },
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: '{{agentName}}',
|
|
45
|
+
content: { text: 'Merchant card: wash_flagged YES — default refuse pay' },
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
],
|
|
49
|
+
validate: async () => true,
|
|
50
|
+
handler: async (runtime, message, _state, _opt, callback) => {
|
|
51
|
+
const content = (message.content ?? {});
|
|
52
|
+
const pubkey = extractPubkey(content);
|
|
53
|
+
if (!pubkey) {
|
|
54
|
+
await callback?.({
|
|
55
|
+
text: 'Provide a merchant/seller wallet (32-44 char base58) for merchant_card.',
|
|
56
|
+
});
|
|
57
|
+
return { success: false, error: 'Missing pubkey' };
|
|
58
|
+
}
|
|
59
|
+
const apiBase = getIntelBase(runtime);
|
|
60
|
+
try {
|
|
61
|
+
const card = await withTimeout(() => fetchMerchantCard(pubkey, { apiBase }));
|
|
62
|
+
if (!card) {
|
|
63
|
+
await callback?.({
|
|
64
|
+
text: `Merchant card unavailable for ${pubkey} (network or invalid). ` +
|
|
65
|
+
`Fail-open: do not invent wash_flagged; use WZRD_INTEL_PREFLIGHT decision only.`,
|
|
66
|
+
});
|
|
67
|
+
return { success: false, error: 'merchant_card_unavailable' };
|
|
68
|
+
}
|
|
69
|
+
const text = formatMerchantCard(card);
|
|
70
|
+
await callback?.({ text });
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
data: {
|
|
74
|
+
...card,
|
|
75
|
+
refuse_pay: card.wash_flagged === true,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
81
|
+
await callback?.({ text: `Merchant card failed: ${msg}` });
|
|
82
|
+
return { success: false, error: msg };
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
};
|
package/dist/client.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export declare class WzrdClient {
|
|
|
75
75
|
quality_score?: number;
|
|
76
76
|
latency_ms?: number;
|
|
77
77
|
}): Promise<ReportResult>;
|
|
78
|
-
/** Check pending + total rewards (
|
|
78
|
+
/** Check pending + total rewards (reads flat /v1/agent/earned response) */
|
|
79
79
|
getRewards(): Promise<RewardsBalance>;
|
|
80
80
|
/** Gasless CCM claim via server relay */
|
|
81
81
|
claimRelay(): Promise<ClaimResult>;
|
package/dist/client.js
CHANGED
|
@@ -87,19 +87,17 @@ export class WzrdClient {
|
|
|
87
87
|
}
|
|
88
88
|
return res.json();
|
|
89
89
|
}
|
|
90
|
-
/** Check pending + total rewards (
|
|
90
|
+
/** Check pending + total rewards (reads flat /v1/agent/earned response) */
|
|
91
91
|
async getRewards() {
|
|
92
92
|
const res = await this.authedFetch('/v1/agent/earned');
|
|
93
93
|
if (!res.ok)
|
|
94
94
|
throw new Error(`Rewards check failed: ${res.status}`);
|
|
95
95
|
const data = await res.json();
|
|
96
|
-
const economy = data.economy;
|
|
97
|
-
const routing = data.routing;
|
|
98
96
|
return {
|
|
99
|
-
pending_ccm: Number(
|
|
100
|
-
total_rewarded_ccm: Number(
|
|
101
|
-
rank:
|
|
102
|
-
contribution_count: Number(
|
|
97
|
+
pending_ccm: Number(data.pending_ccm ?? 0),
|
|
98
|
+
total_rewarded_ccm: Number(data.total_earned_ccm ?? 0),
|
|
99
|
+
rank: data.rank == null ? null : Number(data.rank),
|
|
100
|
+
contribution_count: Number(data.lifetime_contributions ?? 0),
|
|
103
101
|
};
|
|
104
102
|
}
|
|
105
103
|
/** Gasless CCM claim via server relay */
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* @wzrd_sol/eliza-plugin — WZRD Agent Intel + Earn Loop for ElizaOS
|
|
3
3
|
*
|
|
4
4
|
* Intel lane (default https://intel.twzrd.xyz):
|
|
5
|
-
* WZRD_INTEL_PREFLIGHT → WZRD_INTEL_TRUST → WZRD_VERIFY_RECEIPT
|
|
5
|
+
* WZRD_INTEL_PREFLIGHT → WZRD_MERCHANT_CARD → WZRD_INTEL_TRUST → WZRD_VERIFY_RECEIPT
|
|
6
6
|
* Paid intel requires caller-supplied x402 fetch via setPayingFetch().
|
|
7
|
+
* Default: preSpendGate refuses wash_flagged pay_to (free merchant_card).
|
|
7
8
|
*
|
|
8
9
|
* Earn lane (default https://api.twzrd.xyz):
|
|
9
10
|
* WZRD_INFER → WZRD_REPORT → WZRD_EARN → WZRD_CLAIM / WZRD_REWARDS
|
|
@@ -20,14 +21,15 @@ import { earnAction } from './actions/earn.js';
|
|
|
20
21
|
import { claimAction } from './actions/claim.js';
|
|
21
22
|
import { rewardsAction } from './actions/rewards.js';
|
|
22
23
|
import { intelPreflightAction } from './actions/intel-preflight.js';
|
|
24
|
+
import { merchantCardAction } from './actions/merchant-card.js';
|
|
23
25
|
import { intelTrustAction } from './actions/intel-trust.js';
|
|
24
26
|
import { verifyReceiptAction } from './actions/verify-receipt.js';
|
|
25
27
|
export declare const wzrdPlugin: Plugin;
|
|
26
28
|
export default wzrdPlugin;
|
|
27
|
-
export { intelPreflightAction, intelTrustAction, verifyReceiptAction, earnAction, inferAction, reportAction, claimAction, rewardsAction, };
|
|
29
|
+
export { intelPreflightAction, merchantCardAction, intelTrustAction, verifyReceiptAction, earnAction, inferAction, reportAction, claimAction, rewardsAction, };
|
|
28
30
|
export { getWzrdClient, clearClientCache, getIntelApiBase, getIntelClient } from './client-factory.js';
|
|
29
31
|
export { setPayingFetch, clearPayingFetch, resolvePayingFetch } from './paying-fetch.js';
|
|
30
32
|
export { WzrdClient } from './client.js';
|
|
31
33
|
export type { InferResult, ReportResult, RewardsBalance, ClaimResult } from './client.js';
|
|
32
|
-
export { IntelPaymentRequiredError, intelPreflight, fetchIntelTrust, verifyReceipt, preSpendGate, intelTrustUrl, TRUSTED_RECEIPT_PUBKEY, INTEL_TRUST_PRICE_USDC, } from '@wzrd_sol/sdk';
|
|
33
|
-
export type { ReadinessCard, PreflightInput, PreflightResponse, TwzrdReceipt, IntelTrustResponse, VerifyReceiptResult, X402PaymentRequired, } from '@wzrd_sol/sdk';
|
|
34
|
+
export { IntelPaymentRequiredError, intelPreflight, fetchIntelTrust, fetchMerchantCard, verifyReceipt, preSpendGate, intelTrustUrl, TRUSTED_RECEIPT_PUBKEY, INTEL_TRUST_PRICE_USDC, } from '@wzrd_sol/sdk';
|
|
35
|
+
export type { ReadinessCard, PreflightInput, PreflightResponse, MerchantCard, TwzrdReceipt, IntelTrustResponse, VerifyReceiptResult, X402PaymentRequired, } from '@wzrd_sol/sdk';
|
package/dist/index.js
CHANGED
|
@@ -4,15 +4,17 @@ import { earnAction } from './actions/earn.js';
|
|
|
4
4
|
import { claimAction } from './actions/claim.js';
|
|
5
5
|
import { rewardsAction } from './actions/rewards.js';
|
|
6
6
|
import { intelPreflightAction } from './actions/intel-preflight.js';
|
|
7
|
+
import { merchantCardAction } from './actions/merchant-card.js';
|
|
7
8
|
import { intelTrustAction } from './actions/intel-trust.js';
|
|
8
9
|
import { verifyReceiptAction } from './actions/verify-receipt.js';
|
|
9
10
|
export const wzrdPlugin = {
|
|
10
11
|
name: 'wzrd',
|
|
11
|
-
description: 'WZRD Agent Intel — free ReadinessCard preflight
|
|
12
|
-
'(V5/V6), offline verification on intel.twzrd.xyz.
|
|
13
|
-
'on api.twzrd.xyz.',
|
|
12
|
+
description: 'WZRD Agent Intel — free ReadinessCard preflight + merchant_card wash refuse (default), ' +
|
|
13
|
+
'x402-paid trust receipts (V5/V6), offline verification on intel.twzrd.xyz. ' +
|
|
14
|
+
'Also ships the legacy earn loop (infer/report/claim) on api.twzrd.xyz.',
|
|
14
15
|
actions: [
|
|
15
16
|
intelPreflightAction,
|
|
17
|
+
merchantCardAction,
|
|
16
18
|
intelTrustAction,
|
|
17
19
|
verifyReceiptAction,
|
|
18
20
|
earnAction,
|
|
@@ -23,8 +25,8 @@ export const wzrdPlugin = {
|
|
|
23
25
|
],
|
|
24
26
|
};
|
|
25
27
|
export default wzrdPlugin;
|
|
26
|
-
export { intelPreflightAction, intelTrustAction, verifyReceiptAction, earnAction, inferAction, reportAction, claimAction, rewardsAction, };
|
|
28
|
+
export { intelPreflightAction, merchantCardAction, intelTrustAction, verifyReceiptAction, earnAction, inferAction, reportAction, claimAction, rewardsAction, };
|
|
27
29
|
export { getWzrdClient, clearClientCache, getIntelApiBase, getIntelClient } from './client-factory.js';
|
|
28
30
|
export { setPayingFetch, clearPayingFetch, resolvePayingFetch } from './paying-fetch.js';
|
|
29
31
|
export { WzrdClient } from './client.js';
|
|
30
|
-
export { IntelPaymentRequiredError, intelPreflight, fetchIntelTrust, verifyReceipt, preSpendGate, intelTrustUrl, TRUSTED_RECEIPT_PUBKEY, INTEL_TRUST_PRICE_USDC, } from '@wzrd_sol/sdk';
|
|
32
|
+
export { IntelPaymentRequiredError, intelPreflight, fetchIntelTrust, fetchMerchantCard, verifyReceipt, preSpendGate, intelTrustUrl, TRUSTED_RECEIPT_PUBKEY, INTEL_TRUST_PRICE_USDC, } from '@wzrd_sol/sdk';
|
package/dist/intel-helpers.js
CHANGED
|
@@ -41,9 +41,10 @@ export function parseReceipt(content) {
|
|
|
41
41
|
}
|
|
42
42
|
return null;
|
|
43
43
|
}
|
|
44
|
+
const SOLANA_PUBKEY_RE = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
|
|
44
45
|
export function extractPubkey(content) {
|
|
45
46
|
const direct = str(content.pubkey ?? content.seller_wallet ?? content.wallet);
|
|
46
|
-
if (direct)
|
|
47
|
+
if (direct && SOLANA_PUBKEY_RE.test(direct))
|
|
47
48
|
return direct;
|
|
48
49
|
const text = str(content.text);
|
|
49
50
|
if (!text)
|
|
@@ -51,7 +52,7 @@ export function extractPubkey(content) {
|
|
|
51
52
|
const fromJson = tryParseJson(text);
|
|
52
53
|
if (fromJson) {
|
|
53
54
|
const w = str(fromJson.pubkey ?? fromJson.seller_wallet ?? fromJson.wallet);
|
|
54
|
-
if (w)
|
|
55
|
+
if (w && SOLANA_PUBKEY_RE.test(w))
|
|
55
56
|
return w;
|
|
56
57
|
}
|
|
57
58
|
return extractWallet(text);
|
|
@@ -71,7 +72,10 @@ export function formatPaymentRequired(err, apiBase, pubkey) {
|
|
|
71
72
|
`No paying fetch configured. Wire one before runtime creation:\n` +
|
|
72
73
|
` import { setPayingFetch } from '@wzrd_sol/eliza-plugin';\n` +
|
|
73
74
|
` setPayingFetch(myAgentcashFetch);\n\n` +
|
|
74
|
-
`
|
|
75
|
+
`Pay out of band only with an x402 client that preserves the sponsored fee-payer slot.\n` +
|
|
76
|
+
`Caveat: npx agentcash@latest fetch is not currently a green TWZRD repro; ` +
|
|
77
|
+
`it failed closed with payment_invalid / fee_payer_slot_already_signed on 2026-06-23.\n` +
|
|
78
|
+
`Known-bad compatibility command:\n` +
|
|
75
79
|
` npx agentcash@latest fetch ${url}`);
|
|
76
80
|
}
|
|
77
81
|
function str(v) {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import assert from 'node:assert/strict';
|
|
11
11
|
import { describe, it, before, after } from 'node:test';
|
|
12
12
|
import { AgentRuntime } from '@elizaos/core';
|
|
13
|
-
import wzrdPlugin, { intelPreflightAction, intelTrustAction, verifyReceiptAction, setPayingFetch, clearPayingFetch, getIntelClient, resolvePayingFetch, } from '@wzrd_sol/eliza-plugin';
|
|
13
|
+
import wzrdPlugin, { intelPreflightAction, merchantCardAction, intelTrustAction, verifyReceiptAction, setPayingFetch, clearPayingFetch, getIntelClient, resolvePayingFetch, } from '@wzrd_sol/eliza-plugin';
|
|
14
14
|
function mockMemory(content) {
|
|
15
15
|
return {
|
|
16
16
|
id: '00000000-0000-0000-0000-000000000001',
|
|
@@ -43,6 +43,7 @@ describe('wzrdPlugin intel registration + E2E (real runtime load)', () => {
|
|
|
43
43
|
it('constructs runtime with plugins and registers intel actions', () => {
|
|
44
44
|
const names = runtime.actions.map((a) => a.name);
|
|
45
45
|
assert.ok(names.includes('WZRD_INTEL_PREFLIGHT'), 'preflight must be registered');
|
|
46
|
+
assert.ok(names.includes('WZRD_MERCHANT_CARD'), 'merchant card must be registered');
|
|
46
47
|
assert.ok(names.includes('WZRD_INTEL_TRUST'), 'trust must be registered');
|
|
47
48
|
assert.ok(names.includes('WZRD_VERIFY_RECEIPT'), 'verify must be registered');
|
|
48
49
|
});
|
|
@@ -121,35 +122,115 @@ describe('wzrdPlugin intel registration + E2E (real runtime load)', () => {
|
|
|
121
122
|
assert.ok(result.data);
|
|
122
123
|
});
|
|
123
124
|
it('PREFLIGHT-BEFORE-PAY: decision=block aborts the trust purchase before any payment', async () => {
|
|
124
|
-
// preSpendGate runs
|
|
125
|
-
//
|
|
126
|
-
// paid leg). So we stub global fetch to return a block ReadinessCard, and put a
|
|
127
|
-
// tripwire on the injected paying fetch: if the pay leg runs after a block, the
|
|
128
|
-
// tripwire fires and the test fails.
|
|
125
|
+
// preSpendGate runs FREE preflight + merchant_card via global fetch (not the
|
|
126
|
+
// injected paying fetch). Stub both; tripwire on pay leg.
|
|
129
127
|
const realFetch = globalThis.fetch;
|
|
130
128
|
let payAttempted = false;
|
|
131
129
|
setPayingFetch(async () => {
|
|
132
130
|
payAttempted = true;
|
|
133
131
|
return { ok: true, status: 200, json: async () => ({}) };
|
|
134
132
|
});
|
|
133
|
+
globalThis.fetch = (async (input) => {
|
|
134
|
+
const url = String(input);
|
|
135
|
+
if (url.includes('/merchant_card/')) {
|
|
136
|
+
return {
|
|
137
|
+
ok: true,
|
|
138
|
+
status: 200,
|
|
139
|
+
json: async () => ({ wash_flagged: false }),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
ok: true,
|
|
144
|
+
status: 200,
|
|
145
|
+
json: async () => ({
|
|
146
|
+
readiness_card: { decision: 'block', trust_score: 5, can_spend: false },
|
|
147
|
+
reason: 'seller flagged by corpus',
|
|
148
|
+
}),
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
try {
|
|
152
|
+
const callbacks = [];
|
|
153
|
+
const result = await intelTrustAction.handler(mockRuntime(), mockMemory({ pubkey: '4LkEFjJdXARkKx8FBx4LBFa2SvJNmjQpgGDLoJcypZUE' }), undefined, undefined, async (r) => {
|
|
154
|
+
callbacks.push(r.text ?? '');
|
|
155
|
+
return [];
|
|
156
|
+
});
|
|
157
|
+
assert.equal(result?.success, false);
|
|
158
|
+
assert.equal(result?.error, 'preflight_block');
|
|
159
|
+
assert.equal(payAttempted, false, 'payment must NOT be attempted after a block decision');
|
|
160
|
+
assert.match(callbacks.join('\n'), /blocked|No payment was sent/i);
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
globalThis.fetch = realFetch;
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
it('WASH REFUSE: wash_flagged aborts trust purchase even when preflight allows', async () => {
|
|
167
|
+
const realFetch = globalThis.fetch;
|
|
168
|
+
let payAttempted = false;
|
|
169
|
+
setPayingFetch(async () => {
|
|
170
|
+
payAttempted = true;
|
|
171
|
+
return { ok: true, status: 200, json: async () => ({}) };
|
|
172
|
+
});
|
|
173
|
+
globalThis.fetch = (async (input) => {
|
|
174
|
+
const url = String(input);
|
|
175
|
+
if (url.includes('/merchant_card/')) {
|
|
176
|
+
return {
|
|
177
|
+
ok: true,
|
|
178
|
+
status: 200,
|
|
179
|
+
json: async () => ({
|
|
180
|
+
merchant: '4LkEFjJdXARkKx8FBx4LBFa2SvJNmjQpgGDLoJcypZUE',
|
|
181
|
+
wash_flagged: true,
|
|
182
|
+
wash_label: 'fleet_dominated',
|
|
183
|
+
}),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
ok: true,
|
|
188
|
+
status: 200,
|
|
189
|
+
json: async () => ({
|
|
190
|
+
readiness_card: { decision: 'allow', trust_score: 80, can_spend: true },
|
|
191
|
+
reason: 'preflight decision=allow',
|
|
192
|
+
}),
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
try {
|
|
196
|
+
const callbacks = [];
|
|
197
|
+
const result = await intelTrustAction.handler(mockRuntime(), mockMemory({ pubkey: '4LkEFjJdXARkKx8FBx4LBFa2SvJNmjQpgGDLoJcypZUE' }), undefined, undefined, async (r) => {
|
|
198
|
+
callbacks.push(r.text ?? '');
|
|
199
|
+
return [];
|
|
200
|
+
});
|
|
201
|
+
assert.equal(result?.success, false);
|
|
202
|
+
assert.equal(result?.error, 'wash_flagged');
|
|
203
|
+
assert.equal(payAttempted, false, 'payment must NOT run after wash refuse');
|
|
204
|
+
assert.match(callbacks.join('\n'), /wash|No payment was sent/i);
|
|
205
|
+
}
|
|
206
|
+
finally {
|
|
207
|
+
globalThis.fetch = realFetch;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
it('merchant card handler returns wash / catalog fields (mocked)', async () => {
|
|
211
|
+
const realFetch = globalThis.fetch;
|
|
135
212
|
globalThis.fetch = (async () => ({
|
|
136
213
|
ok: true,
|
|
137
214
|
status: 200,
|
|
138
215
|
json: async () => ({
|
|
139
|
-
|
|
140
|
-
|
|
216
|
+
merchant: '4LkEFjJdXARkKx8FBx4LBFa2SvJNmjQpgGDLoJcypZUE',
|
|
217
|
+
in_corpus: true,
|
|
218
|
+
wash_flagged: false,
|
|
219
|
+
wash_label: 'provider_organic_broad',
|
|
220
|
+
catalog_enriched: false,
|
|
221
|
+
offering_status: 'Offering unknown — graph only',
|
|
222
|
+
unique_payers_90d: 12,
|
|
141
223
|
}),
|
|
142
224
|
}));
|
|
143
225
|
try {
|
|
144
226
|
const callbacks = [];
|
|
145
|
-
const result = await
|
|
227
|
+
const result = await merchantCardAction.handler(mockRuntime(), mockMemory({ pubkey: '4LkEFjJdXARkKx8FBx4LBFa2SvJNmjQpgGDLoJcypZUE' }), undefined, undefined, async (r) => {
|
|
146
228
|
callbacks.push(r.text ?? '');
|
|
147
229
|
return [];
|
|
148
230
|
});
|
|
149
|
-
assert.equal(result?.success,
|
|
150
|
-
assert.
|
|
151
|
-
assert.
|
|
152
|
-
assert.match(callbacks.join('\n'), /blocked|No payment was sent/i);
|
|
231
|
+
assert.equal(result?.success, true);
|
|
232
|
+
assert.match(callbacks.join('\n'), /Wash flagged: no/i);
|
|
233
|
+
assert.match(callbacks.join('\n'), /graph only/i);
|
|
153
234
|
}
|
|
154
235
|
finally {
|
|
155
236
|
globalThis.fetch = realFetch;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wzrd_sol/eliza-plugin",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "WZRD Agent Intel for ElizaOS — preflight ReadinessCards, x402-paid signed trust receipts (V6 reputation leaf), offline verification on intel.twzrd.xyz. Also ships the legacy earn loop.",
|
|
3
|
+
"version": "0.3.3",
|
|
4
|
+
"description": "WZRD Agent Intel for ElizaOS — preflight ReadinessCards, free merchant_card wash refuse default, x402-paid signed trust receipts (V6 reputation leaf), offline verification on intel.twzrd.xyz. Also ships the legacy earn loop.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@solana/web3.js": "^1.95.0",
|
|
22
|
-
"@wzrd_sol/sdk": "^0.4.
|
|
22
|
+
"@wzrd_sol/sdk": "^0.4.7",
|
|
23
23
|
"bs58": "^5.0.0",
|
|
24
24
|
"tweetnacl": "^1.0.3"
|
|
25
25
|
},
|