wolverine-ai 5.0.0 → 5.0.2
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/bin/wolverine.js +22 -15
- package/package.json +1 -1
- package/src/brain/brain.js +1 -1
- package/src/middleware/x402-fastify.js +105 -198
- package/src/skills/vault.js +1 -24
package/bin/wolverine.js
CHANGED
|
@@ -38,7 +38,7 @@ ${chalk.bold("Options:")}
|
|
|
38
38
|
--workers <n> Force specific worker count
|
|
39
39
|
--info Show system info and exit
|
|
40
40
|
--init Scan server/ and build context map (routes, DB, config, deps)
|
|
41
|
-
--x402-
|
|
41
|
+
--x402-info Show x402 payment configuration
|
|
42
42
|
|
|
43
43
|
${chalk.bold("Configuration:")}
|
|
44
44
|
server/config/settings.json Models, telemetry, limits, health checks
|
|
@@ -67,20 +67,27 @@ if (args.includes("--info")) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// --init: scan server/ and build context map
|
|
70
|
-
// --x402-
|
|
71
|
-
if (args.includes("--x402-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
70
|
+
// --x402-info: show payment configuration
|
|
71
|
+
if (args.includes("--x402-info")) {
|
|
72
|
+
(async () => {
|
|
73
|
+
let payTo = "not configured";
|
|
74
|
+
try {
|
|
75
|
+
const { getWalletAddress } = require("../src/vault/wallet-ops");
|
|
76
|
+
payTo = await getWalletAddress();
|
|
77
|
+
} catch {}
|
|
78
|
+
console.log(chalk.blue("\n 💰 x402 Payment Configuration\n"));
|
|
79
|
+
console.log(chalk.gray(` Wallet: ${payTo}`));
|
|
80
|
+
console.log(chalk.gray(` Network: Base (eip155:8453)`));
|
|
81
|
+
console.log(chalk.gray(` Token: USDC`));
|
|
82
|
+
console.log(chalk.gray(` Protocol: x402 (HTTP 402 Payment Required)`));
|
|
83
|
+
console.log(chalk.gray(` Facilitator: x402.org`));
|
|
84
|
+
console.log(chalk.gray(`\n Add to any Fastify route:`));
|
|
85
|
+
console.log(chalk.cyan(` { config: { x402: { price: "$0.10" } } }`));
|
|
86
|
+
console.log(chalk.gray(`\n Variable pricing (credit purchases):`));
|
|
87
|
+
console.log(chalk.cyan(` { config: { x402: { variable: true, min: "$1", max: "$10000", priceField: "dollars" } } }\n`));
|
|
88
|
+
process.exit(0);
|
|
89
|
+
})();
|
|
90
|
+
return;
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
if (args.includes("--init")) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wolverine-ai",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"description": "Self-healing Node.js server framework powered by AI. Catches crashes, diagnoses errors, generates fixes, verifies, and restarts — automatically.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
package/src/brain/brain.js
CHANGED
|
@@ -190,7 +190,7 @@ const SEED_DOCS = [
|
|
|
190
190
|
metadata: { topic: "notifications" },
|
|
191
191
|
},
|
|
192
192
|
{
|
|
193
|
-
text: "Vault + x402 payments: encrypted key storage in .wolverine/vault/. AES-256-GCM
|
|
193
|
+
text: "Vault + x402 payments: encrypted key storage in .wolverine/vault/. AES-256-GCM. Private key NEVER as JS string — Buffer only, wiped after use. x402 protocol: HTTP 402 Payment Required for USDC payments on Base. Fastify plugin (src/middleware/x402-fastify.js) adds crypto to any route via config flag. Fixed price: { config: { x402: { price: '$0.10' } } }. Variable price (credit purchases): { config: { x402: { variable: true, min: '$1', max: '$10000', priceField: 'dollars' } } } — reads amount from request body. Flow: client requests → 402 with Payment-Required header → client SDK signs USDC auth → retries with Payment-Signature → server verifies via facilitator → 200 + receipt. req.x402.paid/amount/txHash available in handler after payment. Vault wallet is auto-detected as payTo. GET /x402/info shows payment config. Buyer SDKs: @x402/fetch, @x402/axios auto-handle 402→sign→retry.",
|
|
194
194
|
metadata: { topic: "vault-x402" },
|
|
195
195
|
},
|
|
196
196
|
{
|
|
@@ -1,91 +1,60 @@
|
|
|
1
|
-
const path = require("path");
|
|
2
1
|
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* x402
|
|
5
|
+
* x402 Fastify Plugin — add crypto payments to any route with one flag.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Makes it dead simple to accept USDC payments on Base network.
|
|
8
|
+
* The developer marks a route with x402 config, and the middleware
|
|
9
|
+
* handles the 402 → payment → verification → callback flow.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* network: 'eip155:8453', // Base mainnet
|
|
14
|
-
* });
|
|
11
|
+
* Two modes:
|
|
12
|
+
* Fixed price: { x402: { price: "$0.01" } }
|
|
13
|
+
* Variable price: { x402: { variable: true, min: "$1", max: "$10000" } }
|
|
15
14
|
*
|
|
16
|
-
*
|
|
17
|
-
* "
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
15
|
+
* Example — fixed price route:
|
|
16
|
+
* fastify.get("/premium-data", { config: { x402: { price: "$0.10" } } }, handler)
|
|
17
|
+
*
|
|
18
|
+
* Example — variable price (credit purchase):
|
|
19
|
+
* fastify.post("/buy-credits", {
|
|
20
|
+
* config: {
|
|
21
|
+
* x402: {
|
|
22
|
+
* variable: true,
|
|
23
|
+
* min: "$1",
|
|
24
|
+
* max: "$10000",
|
|
25
|
+
* priceField: "dollars", // reads amount from request body
|
|
26
|
+
* }
|
|
22
27
|
* }
|
|
23
|
-
* }
|
|
28
|
+
* }, async (req, reply) => {
|
|
29
|
+
* // req.x402.paid === true, req.x402.amount === "$5.00"
|
|
30
|
+
* addCredits(req.x402.amount);
|
|
31
|
+
* return { credits: newBalance };
|
|
32
|
+
* })
|
|
24
33
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* wolverine --x402-price "POST /v1/chat/completions" "$0.002"
|
|
34
|
+
* The payment receipt is in req.x402 after verification:
|
|
35
|
+
* { paid: true, amount: "$5.00", receipt: {...}, txHash: "0x..." }
|
|
28
36
|
*/
|
|
29
37
|
|
|
30
|
-
// In-memory route pricing — survives hot updates without restart
|
|
31
|
-
let _routePricing = {};
|
|
32
38
|
let _payTo = null;
|
|
33
|
-
let _network = "eip155:8453";
|
|
39
|
+
let _network = "eip155:8453";
|
|
34
40
|
let _facilitatorUrl = "https://x402.org/facilitator";
|
|
35
|
-
let _initialized = false;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Get current route pricing (for external access).
|
|
39
|
-
*/
|
|
40
|
-
function getPricing() { return { ..._routePricing }; }
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Update a single route's price live — no restart needed.
|
|
44
|
-
*/
|
|
45
|
-
function setPrice(routeKey, price) {
|
|
46
|
-
if (!price.startsWith("$")) price = "$" + price;
|
|
47
|
-
_routePricing[routeKey] = { price };
|
|
48
|
-
// Persist to settings.json
|
|
49
|
-
_persistPricing();
|
|
50
|
-
return { route: routeKey, price };
|
|
51
|
-
}
|
|
52
41
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
_persistPricing();
|
|
59
|
-
return { route: routeKey, price: "free" };
|
|
60
|
-
}
|
|
42
|
+
async function x402Plugin(fastify, opts) {
|
|
43
|
+
// Config
|
|
44
|
+
_network = opts.network || _network;
|
|
45
|
+
_facilitatorUrl = opts.facilitator || _facilitatorUrl;
|
|
46
|
+
_payTo = opts.payTo || null;
|
|
61
47
|
|
|
62
|
-
|
|
48
|
+
// Load from settings.json
|
|
63
49
|
try {
|
|
64
50
|
const settingsPath = path.join(process.cwd(), "server", "config", "settings.json");
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
for (const [route, cfg] of Object.entries(_routePricing)) {
|
|
70
|
-
settings.x402.routes[route] = { price: cfg.price };
|
|
71
|
-
}
|
|
72
|
-
const tmp = settingsPath + ".tmp";
|
|
73
|
-
fs.writeFileSync(tmp, JSON.stringify(settings, null, 2), "utf-8");
|
|
74
|
-
fs.renameSync(tmp, settingsPath);
|
|
75
|
-
}
|
|
51
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
52
|
+
if (settings.x402?.network) _network = settings.x402.network;
|
|
53
|
+
if (settings.x402?.facilitator) _facilitatorUrl = settings.x402.facilitator;
|
|
54
|
+
if (settings.x402?.payTo) _payTo = settings.x402.payTo;
|
|
76
55
|
} catch {}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Fastify plugin — registers x402 payment middleware.
|
|
81
|
-
*/
|
|
82
|
-
async function x402Plugin(fastify, opts) {
|
|
83
|
-
// Load config
|
|
84
|
-
_payTo = opts.payTo || null;
|
|
85
|
-
_network = opts.network || "eip155:8453";
|
|
86
|
-
_facilitatorUrl = opts.facilitator || "https://x402.org/facilitator";
|
|
87
56
|
|
|
88
|
-
// Auto-detect payTo from vault
|
|
57
|
+
// Auto-detect payTo from vault
|
|
89
58
|
if (!_payTo) {
|
|
90
59
|
try {
|
|
91
60
|
const { getWalletAddress } = require("../vault/wallet-ops");
|
|
@@ -93,188 +62,130 @@ async function x402Plugin(fastify, opts) {
|
|
|
93
62
|
} catch {}
|
|
94
63
|
}
|
|
95
64
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const settingsPath = path.join(process.cwd(), "server", "config", "settings.json");
|
|
99
|
-
if (fs.existsSync(settingsPath)) {
|
|
100
|
-
const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
101
|
-
if (settings.x402?.routes) {
|
|
102
|
-
for (const [route, cfg] of Object.entries(settings.x402.routes)) {
|
|
103
|
-
_routePricing[route] = { price: cfg.price };
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (settings.x402?.network) _network = settings.x402.network;
|
|
107
|
-
if (settings.x402?.facilitator) _facilitatorUrl = settings.x402.facilitator;
|
|
108
|
-
}
|
|
109
|
-
} catch {}
|
|
110
|
-
|
|
111
|
-
if (!_payTo) {
|
|
112
|
-
console.log(" ⚠️ x402: no payTo address (set in settings.json or init vault)");
|
|
113
|
-
return;
|
|
65
|
+
if (_payTo) {
|
|
66
|
+
console.log(` 💰 x402: payments to ${_payTo.slice(0, 6)}...${_payTo.slice(-4)} on ${_network}`);
|
|
114
67
|
}
|
|
115
68
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
69
|
+
// ── Route-level x402 hook (preHandler so body is parsed for variable pricing) ──
|
|
70
|
+
fastify.addHook("preHandler", async (request, reply) => {
|
|
71
|
+
// Check if this route has x402 config (Fastify v4: context.config, v5: routeOptions.config)
|
|
72
|
+
const routeConfig = request.routeOptions?.config?.x402 || request.routeConfig?.x402 || request.context?.config?.x402;
|
|
73
|
+
if (!routeConfig) return; // Not an x402 route
|
|
74
|
+
if (!_payTo) {
|
|
75
|
+
reply.code(500).send({ error: "x402 not configured — no wallet address" });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
125
78
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (
|
|
79
|
+
// Determine the price
|
|
80
|
+
let price;
|
|
81
|
+
if (routeConfig.variable) {
|
|
82
|
+
// Variable pricing — read amount from request body or query
|
|
83
|
+
const field = routeConfig.priceField || "dollars";
|
|
84
|
+
const raw = request.body?.[field] || request.query?.[field];
|
|
85
|
+
if (!raw) {
|
|
86
|
+
reply.code(400).send({
|
|
87
|
+
error: `${field} required`,
|
|
88
|
+
x402: { variable: true, min: routeConfig.min || "$1", max: routeConfig.max || "$10000" },
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const amount = parseFloat(String(raw).replace("$", ""));
|
|
93
|
+
const min = parseFloat((routeConfig.min || "$1").replace("$", ""));
|
|
94
|
+
const max = parseFloat((routeConfig.max || "$10000").replace("$", ""));
|
|
95
|
+
if (isNaN(amount) || amount < min || amount > max) {
|
|
96
|
+
reply.code(400).send({ error: `Amount must be $${min}-$${max}` });
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
price = "$" + amount.toFixed(2);
|
|
100
|
+
} else {
|
|
101
|
+
price = routeConfig.price;
|
|
102
|
+
if (!price) { reply.code(500).send({ error: "x402 route missing price config" }); return; }
|
|
103
|
+
}
|
|
129
104
|
|
|
130
105
|
const paymentSig = request.headers["payment-signature"];
|
|
131
106
|
|
|
132
107
|
// No payment — return 402 with payment instructions
|
|
133
108
|
if (!paymentSig) {
|
|
134
|
-
const
|
|
109
|
+
const instructions = {
|
|
135
110
|
accepts: [{
|
|
136
111
|
scheme: "exact",
|
|
137
|
-
price
|
|
112
|
+
price,
|
|
138
113
|
network: _network,
|
|
139
114
|
payTo: _payTo,
|
|
140
115
|
}],
|
|
141
|
-
description: `Payment
|
|
116
|
+
description: routeConfig.description || `Payment for ${request.method} ${request.url}`,
|
|
142
117
|
mimeType: "application/json",
|
|
143
118
|
};
|
|
144
|
-
|
|
145
119
|
reply
|
|
146
120
|
.code(402)
|
|
147
|
-
.header("Payment-Required", JSON.stringify(
|
|
148
|
-
.header("X-402-Version", "1.0")
|
|
121
|
+
.header("Payment-Required", JSON.stringify(instructions))
|
|
149
122
|
.send({
|
|
150
123
|
error: "Payment Required",
|
|
151
|
-
price
|
|
124
|
+
price,
|
|
152
125
|
network: _network,
|
|
153
126
|
payTo: _payTo,
|
|
154
127
|
protocol: "x402",
|
|
128
|
+
...(routeConfig.variable ? { variable: true, min: routeConfig.min, max: routeConfig.max, priceField: routeConfig.priceField || "dollars" } : {}),
|
|
155
129
|
});
|
|
156
130
|
return;
|
|
157
131
|
}
|
|
158
132
|
|
|
159
|
-
// Payment present — verify
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
request.x402 = { paid: true, amount: routeConfig.price, txHash: verified.txHash };
|
|
166
|
-
return; // continue to route handler
|
|
167
|
-
}
|
|
168
|
-
} catch {}
|
|
169
|
-
|
|
170
|
-
// Verification failed
|
|
171
|
-
reply.code(402).send({
|
|
172
|
-
error: "Payment verification failed",
|
|
173
|
-
price: routeConfig.price,
|
|
174
|
-
network: _network,
|
|
175
|
-
payTo: _payTo,
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
// ── Live price management API ──
|
|
180
|
-
fastify.put("/x402/price", async (request, reply) => {
|
|
181
|
-
// Admin only
|
|
182
|
-
const token = request.headers.authorization?.replace("Bearer ", "");
|
|
183
|
-
let settings = {};
|
|
184
|
-
try { settings = JSON.parse(fs.readFileSync(path.join(process.cwd(), "server", "config", "settings.json"), "utf-8")); } catch {}
|
|
185
|
-
if (token !== settings.platform?.apiKey) {
|
|
186
|
-
return reply.code(403).send({ error: "Admin only" });
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const { route, price } = request.body || {};
|
|
190
|
-
if (!route || !price) return reply.code(400).send({ error: "route and price required" });
|
|
191
|
-
const result = setPrice(route, price);
|
|
192
|
-
return { updated: true, ...result };
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
fastify.delete("/x402/price", async (request, reply) => {
|
|
196
|
-
const token = request.headers.authorization?.replace("Bearer ", "");
|
|
197
|
-
let settings = {};
|
|
198
|
-
try { settings = JSON.parse(fs.readFileSync(path.join(process.cwd(), "server", "config", "settings.json"), "utf-8")); } catch {}
|
|
199
|
-
if (token !== settings.platform?.apiKey) {
|
|
200
|
-
return reply.code(403).send({ error: "Admin only" });
|
|
133
|
+
// Payment present — verify
|
|
134
|
+
const verified = await _verifyPayment(paymentSig, price);
|
|
135
|
+
if (verified.valid) {
|
|
136
|
+
reply.header("Payment-Response", JSON.stringify(verified.receipt || {}));
|
|
137
|
+
request.x402 = { paid: true, amount: price, receipt: verified.receipt, txHash: verified.txHash };
|
|
138
|
+
return; // continue to route handler
|
|
201
139
|
}
|
|
202
140
|
|
|
203
|
-
|
|
204
|
-
if (!route) return reply.code(400).send({ error: "route required" });
|
|
205
|
-
return removePrice(route);
|
|
141
|
+
reply.code(402).send({ error: "Payment verification failed", price, payTo: _payTo });
|
|
206
142
|
});
|
|
207
143
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
144
|
+
// ── Public pricing endpoint ──
|
|
145
|
+
fastify.get("/x402/info", async () => ({
|
|
146
|
+
payTo: _payTo,
|
|
147
|
+
network: _network,
|
|
148
|
+
facilitator: _facilitatorUrl,
|
|
149
|
+
protocol: "x402",
|
|
150
|
+
docs: "https://docs.cdp.coinbase.com/x402/welcome",
|
|
151
|
+
}));
|
|
215
152
|
}
|
|
216
153
|
|
|
217
|
-
|
|
218
|
-
* Verify a payment signature via the facilitator.
|
|
219
|
-
*/
|
|
220
|
-
async function _verifyPayment(paymentSig, routeConfig) {
|
|
154
|
+
async function _verifyPayment(paymentSig, price) {
|
|
221
155
|
try {
|
|
222
|
-
// Try @x402/core
|
|
156
|
+
// Try @x402/core if available
|
|
223
157
|
const { HTTPFacilitatorClient } = require("@x402/core/server");
|
|
224
|
-
const { ExactEvmScheme } = require("@x402/evm/exact/server");
|
|
225
|
-
|
|
226
158
|
const facilitator = new HTTPFacilitatorClient({ url: _facilitatorUrl });
|
|
227
159
|
const result = await facilitator.verify({
|
|
228
160
|
paymentSignature: paymentSig,
|
|
229
|
-
routeConfig: {
|
|
230
|
-
accepts: [{
|
|
231
|
-
scheme: "exact",
|
|
232
|
-
price: routeConfig.price,
|
|
233
|
-
network: _network,
|
|
234
|
-
payTo: _payTo,
|
|
235
|
-
}],
|
|
236
|
-
},
|
|
161
|
+
routeConfig: { accepts: [{ scheme: "exact", price, network: _network, payTo: _payTo }] },
|
|
237
162
|
});
|
|
238
163
|
return { valid: result.valid, receipt: result.receipt, txHash: result.txHash };
|
|
239
164
|
} catch {
|
|
240
|
-
// Fallback:
|
|
165
|
+
// Fallback: raw HTTP to facilitator
|
|
241
166
|
try {
|
|
242
167
|
const https = require("https");
|
|
243
168
|
const http = require("http");
|
|
244
169
|
const url = new (require("url").URL)(_facilitatorUrl + "/verify");
|
|
245
170
|
const body = JSON.stringify({
|
|
246
171
|
paymentSignature: paymentSig,
|
|
247
|
-
routeConfig: {
|
|
248
|
-
accepts: [{
|
|
249
|
-
scheme: "exact",
|
|
250
|
-
price: routeConfig.price,
|
|
251
|
-
network: _network,
|
|
252
|
-
payTo: _payTo,
|
|
253
|
-
}],
|
|
254
|
-
},
|
|
172
|
+
routeConfig: { accepts: [{ scheme: "exact", price, network: _network, payTo: _payTo }] },
|
|
255
173
|
});
|
|
256
|
-
|
|
257
174
|
return new Promise((resolve) => {
|
|
258
175
|
const client = url.protocol === "https:" ? https : http;
|
|
259
176
|
const req = client.request({
|
|
260
|
-
hostname: url.hostname,
|
|
261
|
-
port: url.port,
|
|
262
|
-
path: url.pathname,
|
|
263
|
-
method: "POST",
|
|
177
|
+
hostname: url.hostname, port: url.port, path: url.pathname, method: "POST",
|
|
264
178
|
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) },
|
|
265
179
|
timeout: 10000,
|
|
266
180
|
}, (res) => {
|
|
267
181
|
let data = "";
|
|
268
182
|
res.on("data", (c) => data += c);
|
|
269
183
|
res.on("end", () => {
|
|
270
|
-
try {
|
|
271
|
-
|
|
272
|
-
resolve({ valid: parsed.valid || parsed.success, receipt: parsed, txHash: parsed.txHash });
|
|
273
|
-
} catch { resolve({ valid: false }); }
|
|
184
|
+
try { const p = JSON.parse(data); resolve({ valid: p.valid || p.success, receipt: p, txHash: p.txHash }); }
|
|
185
|
+
catch { resolve({ valid: false }); }
|
|
274
186
|
});
|
|
275
187
|
});
|
|
276
188
|
req.on("error", () => resolve({ valid: false }));
|
|
277
|
-
req.on("timeout", () => { req.destroy(); resolve({ valid: false }); });
|
|
278
189
|
req.write(body);
|
|
279
190
|
req.end();
|
|
280
191
|
});
|
|
@@ -282,9 +193,5 @@ async function _verifyPayment(paymentSig, routeConfig) {
|
|
|
282
193
|
}
|
|
283
194
|
}
|
|
284
195
|
|
|
285
|
-
x402Plugin[Symbol.for("skip-override")] = true;
|
|
286
|
-
|
|
196
|
+
x402Plugin[Symbol.for("skip-override")] = true;
|
|
287
197
|
module.exports = x402Plugin;
|
|
288
|
-
module.exports.getPricing = getPricing;
|
|
289
|
-
module.exports.setPrice = setPrice;
|
|
290
|
-
module.exports.removePrice = removePrice;
|
package/src/skills/vault.js
CHANGED
|
@@ -61,31 +61,8 @@ async function execute(action, params = {}) {
|
|
|
61
61
|
return { signedTransaction: signed };
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// x402 payment actions
|
|
65
|
-
case "x402_pricing":
|
|
66
|
-
try {
|
|
67
|
-
const { getPricing } = require("../middleware/x402-fastify");
|
|
68
|
-
return getPricing();
|
|
69
|
-
} catch { return { error: "x402 middleware not loaded" }; }
|
|
70
|
-
|
|
71
|
-
case "x402_set_price": {
|
|
72
|
-
if (!params.route || !params.price) return { error: "route and price required" };
|
|
73
|
-
try {
|
|
74
|
-
const { setPrice } = require("../middleware/x402-fastify");
|
|
75
|
-
return setPrice(params.route, params.price);
|
|
76
|
-
} catch { return { error: "x402 middleware not loaded" }; }
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
case "x402_remove_price": {
|
|
80
|
-
if (!params.route) return { error: "route required" };
|
|
81
|
-
try {
|
|
82
|
-
const { removePrice } = require("../middleware/x402-fastify");
|
|
83
|
-
return removePrice(params.route);
|
|
84
|
-
} catch { return { error: "x402 middleware not loaded" }; }
|
|
85
|
-
}
|
|
86
|
-
|
|
87
64
|
default:
|
|
88
|
-
return { error: `Unknown vault action: ${action}. Use: status, address, sign_tx, sign_message, public_key
|
|
65
|
+
return { error: `Unknown vault action: ${action}. Use: status, address, sign_tx, sign_message, public_key` };
|
|
89
66
|
}
|
|
90
67
|
}
|
|
91
68
|
|