@wzrd_sol/eliza-plugin 0.3.2 → 0.5.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 +104 -44
- package/dist/actions/intel-preflight.js +2 -1
- package/dist/actions/intel-trust.d.ts +3 -3
- package/dist/actions/intel-trust.js +18 -9
- package/dist/actions/merchant-card.d.ts +6 -0
- package/dist/actions/merchant-card.js +85 -0
- package/dist/actions/verify-receipt.d.ts +2 -2
- package/dist/actions/verify-receipt.js +3 -3
- package/dist/index.d.ts +10 -6
- package/dist/index.js +9 -6
- package/dist/paying-fetch.d.ts +17 -0
- package/dist/paying-fetch.js +19 -0
- package/dist/test/plugin-registration.intel.js +94 -13
- package/package.json +10 -6
package/README.md
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
# @wzrd_sol/eliza-plugin
|
|
2
2
|
|
|
3
|
-
ElizaOS plugin for WZRD Agent Intel
|
|
4
|
-
|
|
3
|
+
ElizaOS plugin for **WZRD Agent Intel** on the Solana x402 marketplace:
|
|
4
|
+
free pre-spend checks, free merchant graph card, paid V6 trust receipt, offline verify.
|
|
5
|
+
Also ships the **legacy** AO/CCM earn loop against `api.twzrd.xyz`.
|
|
6
|
+
|
|
7
|
+
## Buyer sequence (marketplace default)
|
|
8
|
+
|
|
9
|
+
Before any x402 spend:
|
|
10
|
+
|
|
11
|
+
1. **Free preflight** - `WZRD_INTEL_PREFLIGHT` / `preSpendGate` - ReadinessCard `allow` / `warn` / `block`
|
|
12
|
+
2. **Free merchant_card** - `WZRD_MERCHANT_CARD` (or inside `preSpendGate`) - if `wash_flagged: true`, **do not pay** (default)
|
|
13
|
+
3. **Optional paid trust** - `WZRD_INTEL_TRUST` (~0.05 USDC) - full score + **signed V6 receipt**
|
|
14
|
+
4. **Offline verify** - `WZRD_VERIFY_RECEIPT`
|
|
15
|
+
|
|
16
|
+
This plugin exposes **actions + SDK helpers**. It does **not** auto-intercept every wallet signature.
|
|
17
|
+
Wire `preSpendGate` / actions into your spend path, or compose with standalone `twzrd-x402-gate` on a paying fetch.
|
|
5
18
|
|
|
6
19
|
## 3-line quickstart
|
|
7
20
|
|
|
8
21
|
```typescript
|
|
9
22
|
import wzrdPlugin from '@wzrd_sol/eliza-plugin';
|
|
10
23
|
const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
11
|
-
// "Preflight seller JUP6Lkb... at 0.25 USDC"
|
|
24
|
+
// "Preflight seller JUP6Lkb... at 0.25 USDC" -> allow/warn/block, free, no wallet
|
|
25
|
+
// "Merchant card for GFpLvoc..." -> wash_flagged refuse default
|
|
12
26
|
```
|
|
13
27
|
|
|
14
28
|
## Install
|
|
@@ -17,21 +31,30 @@ const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
|
17
31
|
npm install @wzrd_sol/eliza-plugin
|
|
18
32
|
```
|
|
19
33
|
|
|
34
|
+
## Which package?
|
|
35
|
+
|
|
36
|
+
| Package | Role | Auto-gates every payment? |
|
|
37
|
+
|---------|------|---------------------------|
|
|
38
|
+
| **`@wzrd_sol/eliza-plugin`** (this) | Eliza actions: preflight, merchant_card, paid trust, verify; re-exports SDK `preSpendGate` | No - call-site / LLM actions |
|
|
39
|
+
| **`@wzrd_sol/plugin-trustgate`** | Smaller Eliza provider + `canSpendSafely` (preflight only) | No - opt-in `canSpendSafely` |
|
|
40
|
+
| **`twzrd-x402-gate`** | Framework-agnostic fetch wrapper (preflight + wash refuse on 402) | Only if you wrap fetch |
|
|
41
|
+
|
|
20
42
|
## Configuration
|
|
21
43
|
|
|
22
44
|
| Variable | Required | Default | Description |
|
|
23
45
|
|----------|----------|---------|-------------|
|
|
24
|
-
| `WZRD_INTEL_URL` | No | `https://intel.twzrd.xyz` | Agent Intel API (preflight, trust, verify) |
|
|
25
|
-
| `WZRD_API_URL` | No | `https://api.twzrd.xyz` | Earn API (infer/report/claim) |
|
|
26
|
-
| `SOLANA_PRIVATE_KEY` | Earn lane only |
|
|
46
|
+
| `WZRD_INTEL_URL` | No | `https://intel.twzrd.xyz` | Agent Intel API (preflight, merchant_card, trust, verify) |
|
|
47
|
+
| `WZRD_API_URL` | No | `https://api.twzrd.xyz` | Earn API (infer/report/claim) - legacy lane |
|
|
48
|
+
| `SOLANA_PRIVATE_KEY` | Earn lane only | - | JSON array of secret key bytes for agent Ed25519 auth |
|
|
27
49
|
|
|
28
50
|
## Intel actions (primary)
|
|
29
51
|
|
|
30
52
|
| Action | Auth/Pay | Description |
|
|
31
53
|
|--------|----------|-------------|
|
|
32
54
|
| `WZRD_INTEL_PREFLIGHT` | Free | ReadinessCard: `decision`, `trust_score`, `can_spend`, `caveats`, `preflight_id` |
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
55
|
+
| `WZRD_MERCHANT_CARD` | Free | Graph card: `wash_flagged`, tier, catalog join; **default refuse if wash** |
|
|
56
|
+
| `WZRD_INTEL_TRUST` | x402 (~0.05 USDC) | Paid trust payload + **V6** signed receipt + ERC-8004 `reputation_credential` |
|
|
57
|
+
| `WZRD_VERIFY_RECEIPT` | Free (offline) | Recompute leaf + Ed25519 verify; V6 primary (older V5 still accepted) |
|
|
35
58
|
|
|
36
59
|
### Preflight (free, no wallet)
|
|
37
60
|
|
|
@@ -56,52 +79,78 @@ Decision: allow
|
|
|
56
79
|
Trust score: 72
|
|
57
80
|
Can spend: yes
|
|
58
81
|
Preflight ID: pf_abc123
|
|
59
|
-
Paid deep dive available (0.05 USDC)
|
|
82
|
+
Paid deep dive available (0.05 USDC) - use WZRD_INTEL_TRUST
|
|
60
83
|
```
|
|
61
84
|
|
|
62
|
-
###
|
|
63
|
-
|
|
64
|
-
For agents that call x402-gated URLs directly (not via pre-known seller wallet), pair this
|
|
65
|
-
plugin with `twzrd-x402-gate` to intercept 402s before any spend:
|
|
85
|
+
### Merchant card (free wash / demand-quality gate)
|
|
66
86
|
|
|
67
87
|
```typescript
|
|
68
|
-
import
|
|
69
|
-
import { withTwzrdGuard } from 'twzrd-x402-gate';
|
|
70
|
-
import { createAgentcashFetch } from 'agentcash';
|
|
88
|
+
import { merchantCardAction, fetchMerchantCard } from '@wzrd_sol/eliza-plugin';
|
|
71
89
|
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
const safeFetch = withTwzrdGuard(x402Fetch, {
|
|
75
|
-
autoReceipt: true, // auto-buy $0.05 TWZRD receipt on warn/allow
|
|
76
|
-
x402Fetch,
|
|
77
|
-
});
|
|
90
|
+
// Action (LLM-callable):
|
|
91
|
+
// "Merchant card for GFpLvocNdEjnSsLH3VJQL6wGcjGxTbUBrj6fqN3Qe1Gs"
|
|
78
92
|
|
|
79
|
-
//
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
//
|
|
93
|
+
// Programmatic:
|
|
94
|
+
const card = await fetchMerchantCard(sellerPubkey);
|
|
95
|
+
if (card?.wash_flagged) return 'refuse dirty pay_to';
|
|
96
|
+
// card unreachable -> fail-open (do not invent wash); use preflight decision only
|
|
83
97
|
```
|
|
84
98
|
|
|
85
|
-
|
|
86
|
-
1. `safeFetch` hits the resource, gets HTTP 402.
|
|
87
|
-
2. `withTwzrdGuard` reads `accepts[0].payTo` (seller wallet).
|
|
88
|
-
3. Calls `POST /v1/intel/preflight` — free, no auth.
|
|
89
|
-
4. `block` - throws, no payment made.
|
|
90
|
-
5. `warn/allow` - returns the 402 for the x402 client to pay.
|
|
99
|
+
Catalog enrichment is listing metadata only - never overrides wash.
|
|
91
100
|
|
|
92
|
-
### Pre-spend gate (programmatic)
|
|
101
|
+
### Pre-spend gate (programmatic - both free checks)
|
|
93
102
|
|
|
94
103
|
```typescript
|
|
95
|
-
import { preSpendGate, fetchIntelTrust } from '@wzrd_sol/eliza-plugin';
|
|
104
|
+
import { preSpendGate, fetchIntelTrust, fetchMerchantCard } from '@wzrd_sol/eliza-plugin';
|
|
96
105
|
|
|
97
|
-
//
|
|
98
|
-
const gate = await preSpendGate({ seller_wallet: sellerPubkey });
|
|
106
|
+
// Free preflight + free merchant_card wash refuse (default on):
|
|
107
|
+
const gate = await preSpendGate({ seller_wallet: sellerPubkey, price_usdc: 0.25 });
|
|
99
108
|
if (!gate.allow) return `Blocked (${gate.decision}): ${gate.reason}`;
|
|
109
|
+
// gate.washFlagged === true was refuse default; null = card gap (fail-open)
|
|
100
110
|
|
|
101
111
|
// Then pay and get the receipt:
|
|
102
112
|
const trust = await fetchIntelTrust(sellerPubkey, { fetchImpl: myX402Fetch });
|
|
103
113
|
```
|
|
104
114
|
|
|
115
|
+
**Default:** `refuseWashFlagged: true` - if free `merchant_card.wash_flagged`, do not pay.
|
|
116
|
+
Soft cap: `{ washMaxUsdc: 0.05 }`. Opt out: `{ refuseWashFlagged: false }`.
|
|
117
|
+
|
|
118
|
+
### Guard pattern: fire-before-pay with `installTwzrdAutoGate` (default-on)
|
|
119
|
+
|
|
120
|
+
For agents that call x402-gated URLs directly (not via a pre-known seller wallet), pair this
|
|
121
|
+
plugin with standalone **`twzrd-x402-gate`** (separate package - not bundled here) to intercept
|
|
122
|
+
402s before any spend — and register the result as the plugin's paying fetch in one call:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import wzrdPlugin, { installTwzrdAutoGate } from '@wzrd_sol/eliza-plugin';
|
|
126
|
+
import { wrapFetchWithPayment } from '@x402/svm';
|
|
127
|
+
|
|
128
|
+
// Guards the raw fetch (free preflight + free merchant_card wash refuse), hands the guarded
|
|
129
|
+
// fetch to your x402 client, registers the result as the module paying fetch — a blocked or
|
|
130
|
+
// wash-flagged seller throws before your client ever signs.
|
|
131
|
+
installTwzrdAutoGate((guarded) => wrapFetchWithPayment(guarded, buyerWallet));
|
|
132
|
+
|
|
133
|
+
const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
134
|
+
// WZRD_INTEL_TRUST and any tool/skill using resolvePayingFetch() now goes through the guard.
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`payWrap` (the function you pass in) receives the **guarded** fetch — the guard has already
|
|
138
|
+
run by the time your client sees a 402. Building the composition the other way round (guarding
|
|
139
|
+
an already-paying client, e.g. one that resolves 402s internally and returns 200) is a no-op;
|
|
140
|
+
see `twzrd-x402-gate`'s Compatibility note. Opt out with `TWZRD_AUTO_GATE=0` (env) or
|
|
141
|
+
`{ disabled: true }`.
|
|
142
|
+
|
|
143
|
+
Guard flow (in `twzrd-x402-gate`, not inside this plugin):
|
|
144
|
+
1. The raw fetch hits the resource, gets HTTP 402.
|
|
145
|
+
2. The guard reads `accepts[0].payTo` (seller wallet).
|
|
146
|
+
3. Free `POST /v1/intel/preflight` — `decision=block` / score floor throws, `payWrap`'s client never signs.
|
|
147
|
+
4. Free `GET /v1/intel/merchant_card/{payTo}` — `wash_flagged:true` refuses by default (only tightens step 3).
|
|
148
|
+
5. Otherwise returns the 402 to `payWrap`'s client, which pays normally.
|
|
149
|
+
|
|
150
|
+
For manual composition (managing the raw/paying split yourself) or `autoReceipt`/`escalateOnWarn`
|
|
151
|
+
options, use `withTwzrdGuard` from `twzrd-x402-gate` directly and pass the result to `setPayingFetch`
|
|
152
|
+
— see that package's README.
|
|
153
|
+
|
|
105
154
|
### Paid trust receipt (agentcash)
|
|
106
155
|
|
|
107
156
|
```typescript
|
|
@@ -112,7 +161,7 @@ setPayingFetch(createAgentcashFetch({ apiKey: process.env.AGENTCASH_API_KEY }));
|
|
|
112
161
|
|
|
113
162
|
const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
114
163
|
// "Get the trust receipt for seller JUP6LkbZ..."
|
|
115
|
-
//
|
|
164
|
+
// -> WZRD_INTEL_TRUST: free preflight + merchant_card, then pays $0.05 USDC, returns VC + V6 receipt
|
|
116
165
|
```
|
|
117
166
|
|
|
118
167
|
### Paid trust receipt (PayAI)
|
|
@@ -127,8 +176,9 @@ setPayingFetch((url, init) => payai.fetch(url, init));
|
|
|
127
176
|
const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
128
177
|
```
|
|
129
178
|
|
|
130
|
-
Without a paying fetch, `WZRD_INTEL_TRUST` returns the HTTP 402 requirements and
|
|
131
|
-
`npx agentcash@latest fetch
|
|
179
|
+
Without a paying fetch, `WZRD_INTEL_TRUST` returns the HTTP 402 requirements and a
|
|
180
|
+
manual pay one-liner. Caveat: `npx agentcash@latest fetch` has been a known-bad path
|
|
181
|
+
for TWZRD paid trust (fee_payer slot); prefer a wired `setPayingFetch` client.
|
|
132
182
|
|
|
133
183
|
**`WZRD_INTEL_TRUST` response fields:**
|
|
134
184
|
|
|
@@ -156,12 +206,20 @@ if (vc.distinctCounterparties < 3) return 'warn'; // thin history
|
|
|
156
206
|
if (vc.washFactor < 0.5) return 'warn'; // suspicious ring
|
|
157
207
|
```
|
|
158
208
|
|
|
159
|
-
`effectiveTrustScore` is the cross-facilitator wash-adjusted score
|
|
209
|
+
`effectiveTrustScore` is the cross-facilitator wash-adjusted score - computed across all known
|
|
160
210
|
x402 facilitators, not just one settlement path.
|
|
161
211
|
|
|
212
|
+
### Facilitator settle attach (optional host pattern - not an Eliza action)
|
|
213
|
+
|
|
214
|
+
If your x402 client uses TWZRD as facilitator (`https://intel.twzrd.xyz`), successful
|
|
215
|
+
`POST /settle` may return `merchant_attach` + `twzrd_receipt` for the requirements `payTo`
|
|
216
|
+
(best-effort; never voids on-chain settle). Discover via `GET /supported` (`twzrd.merchant_attach`).
|
|
217
|
+
This plugin does not register a settle action - wire facilitator URL in the host payer.
|
|
218
|
+
|
|
162
219
|
### Example agent prompts (trust)
|
|
163
220
|
|
|
164
221
|
- `"Preflight Jupiter Quote Preview before I pay 0.25 USDC to 6EF8rrect..."`
|
|
222
|
+
- `"Merchant card for GFpLvocNdEjnSsLH3VJQL6wGcjGxTbUBrj6fqN3Qe1Gs"`
|
|
165
223
|
- `"Get the trust receipt for seller JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"`
|
|
166
224
|
- `"Is it safe to call the paid intel endpoint on this seller?"`
|
|
167
225
|
- `"Verify this receipt: {leaf, preimage, signature...}"`
|
|
@@ -189,6 +247,7 @@ x402 facilitators, not just one settlement path.
|
|
|
189
247
|
import {
|
|
190
248
|
intelPreflight,
|
|
191
249
|
fetchIntelTrust,
|
|
250
|
+
fetchMerchantCard,
|
|
192
251
|
verifyReceipt,
|
|
193
252
|
preSpendGate,
|
|
194
253
|
IntelPaymentRequiredError,
|
|
@@ -197,6 +256,7 @@ import {
|
|
|
197
256
|
import type {
|
|
198
257
|
ReadinessCard,
|
|
199
258
|
PreflightResponse,
|
|
259
|
+
MerchantCard,
|
|
200
260
|
IntelTrustResponse,
|
|
201
261
|
TwzrdReceipt,
|
|
202
262
|
} from '@wzrd_sol/eliza-plugin';
|
|
@@ -211,8 +271,8 @@ npm run build
|
|
|
211
271
|
npm test
|
|
212
272
|
```
|
|
213
273
|
|
|
214
|
-
`npm test` runs live free preflight against `intel.twzrd.xyz`,
|
|
215
|
-
mocked paid trust path.
|
|
274
|
+
`npm test` runs live free preflight against `intel.twzrd.xyz`, free merchant_card path,
|
|
275
|
+
offline receipt verify, and a mocked paid trust path.
|
|
216
276
|
|
|
217
277
|
Manual earn smoke (requires `SOLANA_PRIVATE_KEY`):
|
|
218
278
|
|
|
@@ -224,9 +284,9 @@ npx tsx test/earn-e2e.ts
|
|
|
224
284
|
|
|
225
285
|
- [Agent Intel API](https://intel.twzrd.xyz)
|
|
226
286
|
- [API docs / llms.txt](https://intel.twzrd.xyz/llms.txt)
|
|
227
|
-
- [x402 gate (standalone firewall)](https://www.npmjs.com/package/twzrd-x402-gate)
|
|
287
|
+
- [x402 gate (standalone fetch firewall)](https://www.npmjs.com/package/twzrd-x402-gate)
|
|
288
|
+
- [plugin-trustgate (smaller Eliza spend guard)](https://www.npmjs.com/package/@wzrd_sol/plugin-trustgate)
|
|
228
289
|
- [GOAT plugin](https://www.npmjs.com/package/@wzrd_sol/goat-plugin)
|
|
229
|
-
- [TWZRD trust quickstart](https://intel.twzrd.xyz/docs/QUICKSTART.md)
|
|
230
290
|
|
|
231
291
|
## License
|
|
232
292
|
|
|
@@ -43,7 +43,8 @@ export const intelPreflightAction = {
|
|
|
43
43
|
similes: ['WZRD_PREFLIGHT', 'INTEL_PREFLIGHT', 'READINESS_CARD'],
|
|
44
44
|
description: 'Free pre-spend ReadinessCard for a seller/resource/price/intent. Returns decision (allow/warn/block), ' +
|
|
45
45
|
'trust_score, can_spend, caveats, paid_deep_dive upsell, and root_provenance when applicable. ' +
|
|
46
|
-
'
|
|
46
|
+
'Step 1 of the buyer sequence before any x402 payment; follow with WZRD_MERCHANT_CARD (wash refuse default) ' +
|
|
47
|
+
'or preSpendGate which runs both free checks.',
|
|
47
48
|
examples: [
|
|
48
49
|
[
|
|
49
50
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WZRD_INTEL_TRUST — Paid trust payload + signed receipt
|
|
3
|
-
* fetch. Preflight-gated:
|
|
4
|
-
* decision=block aborts before any spend
|
|
2
|
+
* WZRD_INTEL_TRUST — Paid trust payload + signed V6 receipt via x402-capable
|
|
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;
|
|
@@ -4,8 +4,9 @@ import { resolvePayingFetch } from '../paying-fetch.js';
|
|
|
4
4
|
export const intelTrustAction = {
|
|
5
5
|
name: 'WZRD_INTEL_TRUST',
|
|
6
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
|
|
8
|
-
'Runs
|
|
7
|
+
description: 'Paid GET /v1/intel/trust/{pubkey} (~0.05 USDC on Solana). Returns renormalized trust score + signed V6 ' +
|
|
8
|
+
'twzrd_receipt (portable offline proof). Runs free preflight + merchant_card wash check first; ' +
|
|
9
|
+
'aborts on decision=block or wash_flagged before any spend. ' +
|
|
9
10
|
'Requires an x402-capable fetchImpl (setPayingFetch or host service). ' +
|
|
10
11
|
'Surfaces payment requirements if no payer is configured.',
|
|
11
12
|
examples: [
|
|
@@ -24,24 +25,32 @@ export const intelTrustAction = {
|
|
|
24
25
|
}
|
|
25
26
|
const apiBase = getIntelBase(runtime);
|
|
26
27
|
const baseFetchImpl = resolvePayingFetch(runtime);
|
|
27
|
-
// preflight-before-pay
|
|
28
|
-
//
|
|
28
|
+
// preflight-before-pay + wash refuse: FREE ReadinessCard + free merchant_card.
|
|
29
|
+
// Abort on decision=block or wash_flagged before any payment. failOpen=false so
|
|
29
30
|
// 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.
|
|
31
|
+
// plugin must demonstrate the safe posture, not bypass it. Free reads only.
|
|
32
32
|
try {
|
|
33
|
-
const gate = await preSpendGate({ seller_wallet: pubkey }, { apiBase, failOpen: false, fetchImpl: baseFetchImpl });
|
|
33
|
+
const gate = await preSpendGate({ seller_wallet: pubkey }, { apiBase, failOpen: false, refuseWashFlagged: true, fetchImpl: baseFetchImpl });
|
|
34
34
|
if (!gate.allow) {
|
|
35
|
+
const washLine = gate.washFlagged === true
|
|
36
|
+
? `Wash flagged: yes (merchant_card refuse default)\n`
|
|
37
|
+
: '';
|
|
35
38
|
await callback?.({
|
|
36
39
|
text: `Preflight blocked the trust purchase for ${pubkey}.\n` +
|
|
37
40
|
`Decision: ${gate.decision}${gate.trustScore != null ? `, trust_score=${gate.trustScore}` : ''}\n` +
|
|
41
|
+
washLine +
|
|
38
42
|
`Reason: ${gate.reason}\n` +
|
|
39
43
|
`No payment was sent.`,
|
|
40
44
|
});
|
|
41
45
|
return {
|
|
42
46
|
success: false,
|
|
43
|
-
error: 'preflight_block',
|
|
44
|
-
data: {
|
|
47
|
+
error: gate.washFlagged === true ? 'wash_flagged' : 'preflight_block',
|
|
48
|
+
data: {
|
|
49
|
+
decision: gate.decision,
|
|
50
|
+
trustScore: gate.trustScore,
|
|
51
|
+
reason: gate.reason,
|
|
52
|
+
washFlagged: gate.washFlagged ?? null,
|
|
53
|
+
},
|
|
45
54
|
};
|
|
46
55
|
}
|
|
47
56
|
}
|
|
@@ -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
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WZRD_VERIFY_RECEIPT — Offline leaf + Ed25519 verification (no network).
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Primary surface is V6 (reputation leaf). Older V5 receipts still verify when
|
|
4
|
+
* presented; the SDK selects the leaf binding from the receipt domain.
|
|
5
5
|
*/
|
|
6
6
|
import type { Action } from '@elizaos/core';
|
|
7
7
|
export declare const verifyReceiptAction: Action;
|
|
@@ -3,11 +3,11 @@ import { getIntelBase, parseReceipt, withTimeout } from '../intel-helpers.js';
|
|
|
3
3
|
export const verifyReceiptAction = {
|
|
4
4
|
name: 'WZRD_VERIFY_RECEIPT',
|
|
5
5
|
similes: ['WZRD_VERIFY', 'VERIFY_TWZRD_RECEIPT', 'CHECK_RECEIPT'],
|
|
6
|
-
description: 'Offline verify a TwzrdReceipt (V5
|
|
7
|
-
'against the published TWZRD key. No network required when trustedPubkey is known.',
|
|
6
|
+
description: 'Offline verify a TwzrdReceipt (V6 primary; older V5 still accepted): recompute keccak leaf from preimage ' +
|
|
7
|
+
'and check Ed25519 signature against the published TWZRD key. No network required when trustedPubkey is known.',
|
|
8
8
|
examples: [
|
|
9
9
|
[
|
|
10
|
-
{ name: '{{user1}}', content: { text: 'Verify this receipt: {"version":"
|
|
10
|
+
{ name: '{{user1}}', content: { text: 'Verify this receipt: {"version":"v6","leaf":"0x...","preimage":{...}}' } },
|
|
11
11
|
{ name: '{{agentName}}', content: { text: 'Receipt valid: leaf OK, signature OK.' } },
|
|
12
12
|
],
|
|
13
13
|
],
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
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
|
|
6
|
-
* Paid intel requires caller-supplied x402 fetch
|
|
5
|
+
* WZRD_INTEL_PREFLIGHT → WZRD_MERCHANT_CARD → WZRD_INTEL_TRUST → WZRD_VERIFY_RECEIPT
|
|
6
|
+
* Paid intel requires a caller-supplied x402 fetch — either setPayingFetch(payingFetch)
|
|
7
|
+
* (already-composed, unguarded) or installTwzrdAutoGate(payWrap) (default-on: guards the
|
|
8
|
+
* raw fetch before your client signs, then registers it the same way).
|
|
9
|
+
* Default: preSpendGate refuses wash_flagged pay_to (free merchant_card).
|
|
7
10
|
*
|
|
8
11
|
* Earn lane (default https://api.twzrd.xyz):
|
|
9
12
|
* WZRD_INFER → WZRD_REPORT → WZRD_EARN → WZRD_CLAIM / WZRD_REWARDS
|
|
@@ -20,14 +23,15 @@ import { earnAction } from './actions/earn.js';
|
|
|
20
23
|
import { claimAction } from './actions/claim.js';
|
|
21
24
|
import { rewardsAction } from './actions/rewards.js';
|
|
22
25
|
import { intelPreflightAction } from './actions/intel-preflight.js';
|
|
26
|
+
import { merchantCardAction } from './actions/merchant-card.js';
|
|
23
27
|
import { intelTrustAction } from './actions/intel-trust.js';
|
|
24
28
|
import { verifyReceiptAction } from './actions/verify-receipt.js';
|
|
25
29
|
export declare const wzrdPlugin: Plugin;
|
|
26
30
|
export default wzrdPlugin;
|
|
27
|
-
export { intelPreflightAction, intelTrustAction, verifyReceiptAction, earnAction, inferAction, reportAction, claimAction, rewardsAction, };
|
|
31
|
+
export { intelPreflightAction, merchantCardAction, intelTrustAction, verifyReceiptAction, earnAction, inferAction, reportAction, claimAction, rewardsAction, };
|
|
28
32
|
export { getWzrdClient, clearClientCache, getIntelApiBase, getIntelClient } from './client-factory.js';
|
|
29
|
-
export { setPayingFetch, clearPayingFetch, resolvePayingFetch } from './paying-fetch.js';
|
|
33
|
+
export { setPayingFetch, clearPayingFetch, resolvePayingFetch, installTwzrdAutoGate, } from './paying-fetch.js';
|
|
30
34
|
export { WzrdClient } from './client.js';
|
|
31
35
|
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';
|
|
36
|
+
export { IntelPaymentRequiredError, intelPreflight, fetchIntelTrust, fetchMerchantCard, verifyReceipt, preSpendGate, intelTrustUrl, TRUSTED_RECEIPT_PUBKEY, INTEL_TRUST_PRICE_USDC, } from '@wzrd_sol/sdk';
|
|
37
|
+
export type { ReadinessCard, PreflightInput, PreflightResponse, MerchantCard, TwzrdReceipt, IntelTrustResponse, VerifyReceiptResult, X402PaymentRequired, } from '@wzrd_sol/sdk';
|
package/dist/index.js
CHANGED
|
@@ -4,15 +4,18 @@ 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
|
-
'(
|
|
13
|
-
'
|
|
12
|
+
description: 'WZRD Agent Intel — free ReadinessCard preflight + free merchant_card wash refuse (default), ' +
|
|
13
|
+
'then optional x402-paid V6 trust receipt (~0.05 USDC) + offline verify on intel.twzrd.xyz. ' +
|
|
14
|
+
'Buyer sequence is call-site / action-driven (not an auto-interceptor of all payments). ' +
|
|
15
|
+
'Also ships the legacy earn loop (infer/report/claim) on api.twzrd.xyz.',
|
|
14
16
|
actions: [
|
|
15
17
|
intelPreflightAction,
|
|
18
|
+
merchantCardAction,
|
|
16
19
|
intelTrustAction,
|
|
17
20
|
verifyReceiptAction,
|
|
18
21
|
earnAction,
|
|
@@ -23,8 +26,8 @@ export const wzrdPlugin = {
|
|
|
23
26
|
],
|
|
24
27
|
};
|
|
25
28
|
export default wzrdPlugin;
|
|
26
|
-
export { intelPreflightAction, intelTrustAction, verifyReceiptAction, earnAction, inferAction, reportAction, claimAction, rewardsAction, };
|
|
29
|
+
export { intelPreflightAction, merchantCardAction, intelTrustAction, verifyReceiptAction, earnAction, inferAction, reportAction, claimAction, rewardsAction, };
|
|
27
30
|
export { getWzrdClient, clearClientCache, getIntelApiBase, getIntelClient } from './client-factory.js';
|
|
28
|
-
export { setPayingFetch, clearPayingFetch, resolvePayingFetch } from './paying-fetch.js';
|
|
31
|
+
export { setPayingFetch, clearPayingFetch, resolvePayingFetch, installTwzrdAutoGate, } from './paying-fetch.js';
|
|
29
32
|
export { WzrdClient } from './client.js';
|
|
30
|
-
export { IntelPaymentRequiredError, intelPreflight, fetchIntelTrust, verifyReceipt, preSpendGate, intelTrustUrl, TRUSTED_RECEIPT_PUBKEY, INTEL_TRUST_PRICE_USDC, } from '@wzrd_sol/sdk';
|
|
33
|
+
export { IntelPaymentRequiredError, intelPreflight, fetchIntelTrust, fetchMerchantCard, verifyReceipt, preSpendGate, intelTrustUrl, TRUSTED_RECEIPT_PUBKEY, INTEL_TRUST_PRICE_USDC, } from '@wzrd_sol/sdk';
|
package/dist/paying-fetch.d.ts
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
/** x402-capable fetch injection for paid intel actions. No embedded wallet. */
|
|
2
2
|
import type { IAgentRuntime } from '@elizaos/core';
|
|
3
|
+
import { type InstallAutoGateOptions, type PayWrap } from 'twzrd-x402-gate';
|
|
3
4
|
/** Host supplies an x402-capable fetch (agentcash, twzrd-x402-gate, etc.) before runtime creation. */
|
|
4
5
|
export declare function setPayingFetch(f: typeof fetch): void;
|
|
6
|
+
/**
|
|
7
|
+
* Default-on replacement for `setPayingFetch(payWrap(rawFetch))`: guards the raw fetch
|
|
8
|
+
* with the free TWZRD preflight BEFORE handing it to your x402 client's `payWrap`, so a
|
|
9
|
+
* blocked seller is refused before your client ever signs — then registers the result as
|
|
10
|
+
* the module paying fetch (same slot `setPayingFetch` writes to).
|
|
11
|
+
*
|
|
12
|
+
* Opt out with `TWZRD_AUTO_GATE=0` (env) or `{ disabled: true }`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* import { installTwzrdAutoGate } from '@wzrd_sol/eliza-plugin';
|
|
16
|
+
* import { wrapFetchWithPayment } from '@x402/svm';
|
|
17
|
+
*
|
|
18
|
+
* installTwzrdAutoGate((guarded) => wrapFetchWithPayment(guarded, buyerWallet));
|
|
19
|
+
* const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
20
|
+
*/
|
|
21
|
+
export declare function installTwzrdAutoGate(payWrap: PayWrap, options?: InstallAutoGateOptions): void;
|
|
5
22
|
export declare function clearPayingFetch(): void;
|
|
6
23
|
type FetchLike = typeof fetch;
|
|
7
24
|
/** Resolve paying fetch: module setter > runtime service > runtime.fetch > global fetch. */
|
package/dist/paying-fetch.js
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
|
+
import { installTwzrdAutoGate as buildAutoGate, } from 'twzrd-x402-gate';
|
|
1
2
|
let modulePayingFetch = null;
|
|
2
3
|
/** Host supplies an x402-capable fetch (agentcash, twzrd-x402-gate, etc.) before runtime creation. */
|
|
3
4
|
export function setPayingFetch(f) {
|
|
4
5
|
modulePayingFetch = f;
|
|
5
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Default-on replacement for `setPayingFetch(payWrap(rawFetch))`: guards the raw fetch
|
|
9
|
+
* with the free TWZRD preflight BEFORE handing it to your x402 client's `payWrap`, so a
|
|
10
|
+
* blocked seller is refused before your client ever signs — then registers the result as
|
|
11
|
+
* the module paying fetch (same slot `setPayingFetch` writes to).
|
|
12
|
+
*
|
|
13
|
+
* Opt out with `TWZRD_AUTO_GATE=0` (env) or `{ disabled: true }`.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* import { installTwzrdAutoGate } from '@wzrd_sol/eliza-plugin';
|
|
17
|
+
* import { wrapFetchWithPayment } from '@x402/svm';
|
|
18
|
+
*
|
|
19
|
+
* installTwzrdAutoGate((guarded) => wrapFetchWithPayment(guarded, buyerWallet));
|
|
20
|
+
* const agent = new AgentRuntime({ plugins: [wzrdPlugin] });
|
|
21
|
+
*/
|
|
22
|
+
export function installTwzrdAutoGate(payWrap, options) {
|
|
23
|
+
setPayingFetch(buildAutoGate(payWrap, options));
|
|
24
|
+
}
|
|
6
25
|
export function clearPayingFetch() {
|
|
7
26
|
modulePayingFetch = null;
|
|
8
27
|
}
|
|
@@ -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.
|
|
4
|
-
"description": "WZRD Agent Intel for ElizaOS
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "WZRD Agent Intel for ElizaOS. Free buyer sequence: preflight ReadinessCard + merchant_card (wash_flagged refuse default). Paid: GET /v1/intel/trust (0.05 USDC) for signed V6 receipt. Offline verify. installTwzrdAutoGate(payWrap) registers a default-on guarded paying fetch in one call; setPayingFetch / actions / preSpendGate remain available for manual wiring. Also ships the legacy earn loop.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -19,9 +19,10 @@
|
|
|
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
|
-
"tweetnacl": "^1.0.3"
|
|
24
|
+
"tweetnacl": "^1.0.3",
|
|
25
|
+
"twzrd-x402-gate": "^0.5.0"
|
|
25
26
|
},
|
|
26
27
|
"peerDependencies": {
|
|
27
28
|
"@elizaos/core": "^1.0.0"
|
|
@@ -47,6 +48,9 @@
|
|
|
47
48
|
"receipt",
|
|
48
49
|
"reputation",
|
|
49
50
|
"preflight",
|
|
51
|
+
"merchant_card",
|
|
52
|
+
"wash",
|
|
53
|
+
"marketplace",
|
|
50
54
|
"ccm",
|
|
51
55
|
"inference",
|
|
52
56
|
"earn",
|
|
@@ -59,8 +63,8 @@
|
|
|
59
63
|
},
|
|
60
64
|
"repository": {
|
|
61
65
|
"type": "git",
|
|
62
|
-
"url": "git+https://github.com/twzrd-sol/
|
|
63
|
-
"directory": "
|
|
66
|
+
"url": "git+https://github.com/twzrd-sol/twzrd-trust.git",
|
|
67
|
+
"directory": "eliza-plugin"
|
|
64
68
|
},
|
|
65
69
|
"bugs": {
|
|
66
70
|
"url": "https://github.com/twzrd-sol/twzrd-trust/issues"
|