wolverine-ai 5.2.6 → 5.2.8
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/.env.example +7 -0
- package/package.json +1 -1
- package/src/middleware/x402-fastify.js +30 -6
package/.env.example
CHANGED
|
@@ -16,6 +16,13 @@ WOLVERINE_API_KEY=
|
|
|
16
16
|
# Generate: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
|
17
17
|
WOLVERINE_ADMIN_KEY=
|
|
18
18
|
|
|
19
|
+
# ── CDP x402 Facilitator (mainnet payments) ──────────────────────
|
|
20
|
+
# Required for x402 USDC payments on Base mainnet.
|
|
21
|
+
# Sign up free at https://cdp.coinbase.com → create project → get keys
|
|
22
|
+
# Without these, x402 only works on testnet (Base Sepolia).
|
|
23
|
+
CDP_API_KEY_ID=
|
|
24
|
+
CDP_API_KEY_SECRET=
|
|
25
|
+
|
|
19
26
|
# ── Custom Secrets ───────────────────────────────────────────────
|
|
20
27
|
# Add any secret here — wolverine automatically redacts its value
|
|
21
28
|
# from all AI calls, logs, brain storage, and dashboard output.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wolverine-ai",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.8",
|
|
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": {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
|
|
4
|
+
// Node 18 needs globalThis.crypto for CDP SDK (Ed25519 JWT signing)
|
|
5
|
+
if (!globalThis.crypto) {
|
|
6
|
+
globalThis.crypto = require("crypto").webcrypto;
|
|
7
|
+
}
|
|
8
|
+
|
|
4
9
|
/**
|
|
5
10
|
* x402 Fastify Plugin — add crypto payments to any route with one flag.
|
|
6
11
|
*
|
|
@@ -16,7 +21,7 @@ const USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
|
16
21
|
|
|
17
22
|
let _payTo = null;
|
|
18
23
|
let _network = "eip155:8453";
|
|
19
|
-
let _facilitatorUrl = "https://
|
|
24
|
+
let _facilitatorUrl = "https://api.cdp.coinbase.com/platform/v2/x402";
|
|
20
25
|
|
|
21
26
|
async function x402Plugin(fastify, opts) {
|
|
22
27
|
_network = opts.network || _network;
|
|
@@ -42,10 +47,9 @@ async function x402Plugin(fastify, opts) {
|
|
|
42
47
|
|
|
43
48
|
// Auto-select facilitator based on network
|
|
44
49
|
if (!opts.facilitator) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
: "https://www.x402.org/facilitator"; // www. avoids 308 redirect from x402.org
|
|
50
|
+
if (!process.env.CDP_API_KEY_ID) {
|
|
51
|
+
console.log(` ⚠️ x402: CDP_API_KEY_ID not set — facilitator auth may fail`);
|
|
52
|
+
}
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
if (_payTo) {
|
|
@@ -224,9 +228,29 @@ async function _facilitatorCall(endpoint, paymentPayload, paymentRequirements) {
|
|
|
224
228
|
const controller = new AbortController();
|
|
225
229
|
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
226
230
|
|
|
231
|
+
// Build headers — add CDP JWT auth if using CDP facilitator
|
|
232
|
+
const headers = { "Content-Type": "application/json" };
|
|
233
|
+
if (url.includes("api.cdp.coinbase.com") && process.env.CDP_API_KEY_ID) {
|
|
234
|
+
try {
|
|
235
|
+
// Use dynamic import for @coinbase/cdp-sdk (ESM-only jose dependency)
|
|
236
|
+
const { generateJwt } = await import("@coinbase/cdp-sdk/auth");
|
|
237
|
+
const parsedUrl = new URL(url);
|
|
238
|
+
const jwt = await generateJwt({
|
|
239
|
+
apiKeyId: process.env.CDP_API_KEY_ID,
|
|
240
|
+
apiKeySecret: process.env.CDP_API_KEY_SECRET,
|
|
241
|
+
requestMethod: "POST",
|
|
242
|
+
requestHost: `https://${parsedUrl.host}`,
|
|
243
|
+
requestPath: parsedUrl.pathname,
|
|
244
|
+
});
|
|
245
|
+
headers["Authorization"] = `Bearer ${jwt}`;
|
|
246
|
+
} catch (authErr) {
|
|
247
|
+
console.log(` ⚠️ x402 CDP auth failed: ${authErr.message}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
227
251
|
const response = await fetch(url, {
|
|
228
252
|
method: "POST",
|
|
229
|
-
headers
|
|
253
|
+
headers,
|
|
230
254
|
body,
|
|
231
255
|
redirect: "follow",
|
|
232
256
|
signal: controller.signal,
|