@scriptmasterlabs/mcp-x402 2.0.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/.env.example +35 -0
- package/.github/workflows/ci.yml +59 -0
- package/.github/workflows/keepalive.yml +31 -0
- package/.well-known/agentcard.json +34 -0
- package/CONTRIBUTING.md +76 -0
- package/Dockerfile +19 -0
- package/LICENSE +21 -0
- package/README.md +304 -0
- package/agents.json +67 -0
- package/dist/lib/chains/base.d.ts +10 -0
- package/dist/lib/chains/base.d.ts.map +1 -0
- package/dist/lib/chains/base.js +73 -0
- package/dist/lib/chains/base.js.map +1 -0
- package/dist/lib/chains/solana.d.ts +10 -0
- package/dist/lib/chains/solana.d.ts.map +1 -0
- package/dist/lib/chains/solana.js +49 -0
- package/dist/lib/chains/solana.js.map +1 -0
- package/dist/lib/chains/xrpl.d.ts +10 -0
- package/dist/lib/chains/xrpl.d.ts.map +1 -0
- package/dist/lib/chains/xrpl.js +55 -0
- package/dist/lib/chains/xrpl.js.map +1 -0
- package/dist/lib/credit/bureau.d.ts +10 -0
- package/dist/lib/credit/bureau.d.ts.map +1 -0
- package/dist/lib/credit/bureau.js +58 -0
- package/dist/lib/credit/bureau.js.map +1 -0
- package/dist/lib/sml-api/agentcard.d.ts +17 -0
- package/dist/lib/sml-api/agentcard.d.ts.map +1 -0
- package/dist/lib/sml-api/agentcard.js +30 -0
- package/dist/lib/sml-api/agentcard.js.map +1 -0
- package/dist/lib/sml-api/backtest.d.ts +22 -0
- package/dist/lib/sml-api/backtest.d.ts.map +1 -0
- package/dist/lib/sml-api/backtest.js +28 -0
- package/dist/lib/sml-api/backtest.js.map +1 -0
- package/dist/lib/sml-api/brokers.d.ts +40 -0
- package/dist/lib/sml-api/brokers.d.ts.map +1 -0
- package/dist/lib/sml-api/brokers.js +128 -0
- package/dist/lib/sml-api/brokers.js.map +1 -0
- package/dist/lib/sml-api/copytrader.d.ts +11 -0
- package/dist/lib/sml-api/copytrader.d.ts.map +1 -0
- package/dist/lib/sml-api/copytrader.js +30 -0
- package/dist/lib/sml-api/copytrader.js.map +1 -0
- package/dist/lib/sml-api/crawl.d.ts +20 -0
- package/dist/lib/sml-api/crawl.d.ts.map +1 -0
- package/dist/lib/sml-api/crawl.js +32 -0
- package/dist/lib/sml-api/crawl.js.map +1 -0
- package/dist/lib/sml-api/echo.d.ts +10 -0
- package/dist/lib/sml-api/echo.d.ts.map +1 -0
- package/dist/lib/sml-api/echo.js +23 -0
- package/dist/lib/sml-api/echo.js.map +1 -0
- package/dist/lib/sml-api/forge.d.ts +11 -0
- package/dist/lib/sml-api/forge.d.ts.map +1 -0
- package/dist/lib/sml-api/forge.js +29 -0
- package/dist/lib/sml-api/forge.js.map +1 -0
- package/dist/lib/sml-api/ftd.d.ts +18 -0
- package/dist/lib/sml-api/ftd.d.ts.map +1 -0
- package/dist/lib/sml-api/ftd.js +43 -0
- package/dist/lib/sml-api/ftd.js.map +1 -0
- package/dist/lib/sml-api/ghost.d.ts +13 -0
- package/dist/lib/sml-api/ghost.d.ts.map +1 -0
- package/dist/lib/sml-api/ghost.js +29 -0
- package/dist/lib/sml-api/ghost.js.map +1 -0
- package/dist/lib/sml-api/launchpad.d.ts +20 -0
- package/dist/lib/sml-api/launchpad.d.ts.map +1 -0
- package/dist/lib/sml-api/launchpad.js +31 -0
- package/dist/lib/sml-api/launchpad.js.map +1 -0
- package/dist/lib/sml-api/leviathan.d.ts +22 -0
- package/dist/lib/sml-api/leviathan.d.ts.map +1 -0
- package/dist/lib/sml-api/leviathan.js +33 -0
- package/dist/lib/sml-api/leviathan.js.map +1 -0
- package/dist/lib/sml-api/nexus.d.ts +18 -0
- package/dist/lib/sml-api/nexus.d.ts.map +1 -0
- package/dist/lib/sml-api/nexus.js +40 -0
- package/dist/lib/sml-api/nexus.js.map +1 -0
- package/dist/lib/sml-api/proof402.d.ts +6 -0
- package/dist/lib/sml-api/proof402.d.ts.map +1 -0
- package/dist/lib/sml-api/proof402.js +30 -0
- package/dist/lib/sml-api/proof402.js.map +1 -0
- package/dist/lib/sml-api/rails.d.ts +12 -0
- package/dist/lib/sml-api/rails.d.ts.map +1 -0
- package/dist/lib/sml-api/rails.js +29 -0
- package/dist/lib/sml-api/rails.js.map +1 -0
- package/dist/lib/sml-api/shadow.d.ts +15 -0
- package/dist/lib/sml-api/shadow.d.ts.map +1 -0
- package/dist/lib/sml-api/shadow.js +27 -0
- package/dist/lib/sml-api/shadow.js.map +1 -0
- package/dist/lib/sml-api/squeezeos.d.ts +21 -0
- package/dist/lib/sml-api/squeezeos.d.ts.map +1 -0
- package/dist/lib/sml-api/squeezeos.js +97 -0
- package/dist/lib/sml-api/squeezeos.js.map +1 -0
- package/dist/lib/sml-api/xdeo.d.ts +13 -0
- package/dist/lib/sml-api/xdeo.d.ts.map +1 -0
- package/dist/lib/sml-api/xdeo.js +34 -0
- package/dist/lib/sml-api/xdeo.js.map +1 -0
- package/dist/lib/sml-api/xmit.d.ts +13 -0
- package/dist/lib/sml-api/xmit.d.ts.map +1 -0
- package/dist/lib/sml-api/xmit.js +34 -0
- package/dist/lib/sml-api/xmit.js.map +1 -0
- package/dist/server/health.d.ts +16 -0
- package/dist/server/health.d.ts.map +1 -0
- package/dist/server/health.js +39 -0
- package/dist/server/health.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +193 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/payments/ap2.d.ts +17 -0
- package/dist/server/payments/ap2.d.ts.map +1 -0
- package/dist/server/payments/ap2.js +75 -0
- package/dist/server/payments/ap2.js.map +1 -0
- package/dist/server/payments/receipt.d.ts +28 -0
- package/dist/server/payments/receipt.d.ts.map +1 -0
- package/dist/server/payments/receipt.js +60 -0
- package/dist/server/payments/receipt.js.map +1 -0
- package/dist/server/payments/router.d.ts +23 -0
- package/dist/server/payments/router.d.ts.map +1 -0
- package/dist/server/payments/router.js +69 -0
- package/dist/server/payments/router.js.map +1 -0
- package/dist/server/payments/wallet.d.ts +18 -0
- package/dist/server/payments/wallet.d.ts.map +1 -0
- package/dist/server/payments/wallet.js +107 -0
- package/dist/server/payments/wallet.js.map +1 -0
- package/dist/server/payments/x402.d.ts +29 -0
- package/dist/server/payments/x402.d.ts.map +1 -0
- package/dist/server/payments/x402.js +122 -0
- package/dist/server/payments/x402.js.map +1 -0
- package/dist/server/registry/catalog.d.ts +12 -0
- package/dist/server/registry/catalog.d.ts.map +1 -0
- package/dist/server/registry/catalog.js +55 -0
- package/dist/server/registry/catalog.js.map +1 -0
- package/dist/server/registry/discovery.d.ts +16 -0
- package/dist/server/registry/discovery.d.ts.map +1 -0
- package/dist/server/registry/discovery.js +33 -0
- package/dist/server/registry/discovery.js.map +1 -0
- package/dist/server/registry/pricing.d.ts +10 -0
- package/dist/server/registry/pricing.d.ts.map +1 -0
- package/dist/server/registry/pricing.js +66 -0
- package/dist/server/registry/pricing.js.map +1 -0
- package/dist/server/security/acl.d.ts +28 -0
- package/dist/server/security/acl.d.ts.map +1 -0
- package/dist/server/security/acl.js +36 -0
- package/dist/server/security/acl.js.map +1 -0
- package/dist/server/security/audit.d.ts +15 -0
- package/dist/server/security/audit.d.ts.map +1 -0
- package/dist/server/security/audit.js +77 -0
- package/dist/server/security/audit.js.map +1 -0
- package/dist/server/security/rate-limit.d.ts +12 -0
- package/dist/server/security/rate-limit.d.ts.map +1 -0
- package/dist/server/security/rate-limit.js +72 -0
- package/dist/server/security/rate-limit.js.map +1 -0
- package/dist/server/security/sandbox.d.ts +7 -0
- package/dist/server/security/sandbox.d.ts.map +1 -0
- package/dist/server/security/sandbox.js +42 -0
- package/dist/server/security/sandbox.js.map +1 -0
- package/dist/server/tools/agentcard.d.ts +3 -0
- package/dist/server/tools/agentcard.d.ts.map +1 -0
- package/dist/server/tools/agentcard.js +118 -0
- package/dist/server/tools/agentcard.js.map +1 -0
- package/dist/server/tools/backtest.d.ts +3 -0
- package/dist/server/tools/backtest.d.ts.map +1 -0
- package/dist/server/tools/backtest.js +112 -0
- package/dist/server/tools/backtest.js.map +1 -0
- package/dist/server/tools/brokers.d.ts +3 -0
- package/dist/server/tools/brokers.d.ts.map +1 -0
- package/dist/server/tools/brokers.js +223 -0
- package/dist/server/tools/brokers.js.map +1 -0
- package/dist/server/tools/copytrader.d.ts +3 -0
- package/dist/server/tools/copytrader.d.ts.map +1 -0
- package/dist/server/tools/copytrader.js +90 -0
- package/dist/server/tools/copytrader.js.map +1 -0
- package/dist/server/tools/crawl.d.ts +3 -0
- package/dist/server/tools/crawl.d.ts.map +1 -0
- package/dist/server/tools/crawl.js +60 -0
- package/dist/server/tools/crawl.js.map +1 -0
- package/dist/server/tools/discovery.d.ts +3 -0
- package/dist/server/tools/discovery.d.ts.map +1 -0
- package/dist/server/tools/discovery.js +188 -0
- package/dist/server/tools/discovery.js.map +1 -0
- package/dist/server/tools/echo.d.ts +3 -0
- package/dist/server/tools/echo.d.ts.map +1 -0
- package/dist/server/tools/echo.js +48 -0
- package/dist/server/tools/echo.js.map +1 -0
- package/dist/server/tools/forge.d.ts +3 -0
- package/dist/server/tools/forge.d.ts.map +1 -0
- package/dist/server/tools/forge.js +77 -0
- package/dist/server/tools/forge.js.map +1 -0
- package/dist/server/tools/ftd.d.ts +3 -0
- package/dist/server/tools/ftd.d.ts.map +1 -0
- package/dist/server/tools/ftd.js +70 -0
- package/dist/server/tools/ftd.js.map +1 -0
- package/dist/server/tools/ghost.d.ts +3 -0
- package/dist/server/tools/ghost.d.ts.map +1 -0
- package/dist/server/tools/ghost.js +83 -0
- package/dist/server/tools/ghost.js.map +1 -0
- package/dist/server/tools/index.d.ts +3 -0
- package/dist/server/tools/index.d.ts.map +1 -0
- package/dist/server/tools/index.js +44 -0
- package/dist/server/tools/index.js.map +1 -0
- package/dist/server/tools/launchpad.d.ts +3 -0
- package/dist/server/tools/launchpad.d.ts.map +1 -0
- package/dist/server/tools/launchpad.js +151 -0
- package/dist/server/tools/launchpad.js.map +1 -0
- package/dist/server/tools/leviathan.d.ts +3 -0
- package/dist/server/tools/leviathan.d.ts.map +1 -0
- package/dist/server/tools/leviathan.js +73 -0
- package/dist/server/tools/leviathan.js.map +1 -0
- package/dist/server/tools/nexus.d.ts +3 -0
- package/dist/server/tools/nexus.d.ts.map +1 -0
- package/dist/server/tools/nexus.js +65 -0
- package/dist/server/tools/nexus.js.map +1 -0
- package/dist/server/tools/proof402.d.ts +3 -0
- package/dist/server/tools/proof402.d.ts.map +1 -0
- package/dist/server/tools/proof402.js +74 -0
- package/dist/server/tools/proof402.js.map +1 -0
- package/dist/server/tools/rails.d.ts +3 -0
- package/dist/server/tools/rails.d.ts.map +1 -0
- package/dist/server/tools/rails.js +82 -0
- package/dist/server/tools/rails.js.map +1 -0
- package/dist/server/tools/shadow.d.ts +3 -0
- package/dist/server/tools/shadow.d.ts.map +1 -0
- package/dist/server/tools/shadow.js +114 -0
- package/dist/server/tools/shadow.js.map +1 -0
- package/dist/server/tools/squeezeos.d.ts +3 -0
- package/dist/server/tools/squeezeos.d.ts.map +1 -0
- package/dist/server/tools/squeezeos.js +231 -0
- package/dist/server/tools/squeezeos.js.map +1 -0
- package/dist/server/tools/xdeo.d.ts +3 -0
- package/dist/server/tools/xdeo.d.ts.map +1 -0
- package/dist/server/tools/xdeo.js +58 -0
- package/dist/server/tools/xdeo.js.map +1 -0
- package/dist/server/tools/xmit.d.ts +3 -0
- package/dist/server/tools/xmit.d.ts.map +1 -0
- package/dist/server/tools/xmit.js +59 -0
- package/dist/server/tools/xmit.js.map +1 -0
- package/docker-compose.yml +50 -0
- package/llms.txt +70 -0
- package/package.json +77 -0
- package/render.yaml +39 -0
- package/sdk/mcp-x402-sdk/package.json +18 -0
- package/sdk/mcp-x402-sdk/src/index.ts +118 -0
- package/sdk/mcp-x402-sdk/tsconfig.json +14 -0
- package/server.json +60 -0
- package/services/backtest_service.py +176 -0
- package/src/lib/chains/base.ts +77 -0
- package/src/lib/chains/solana.ts +59 -0
- package/src/lib/chains/xrpl.ts +63 -0
- package/src/lib/credit/bureau.ts +65 -0
- package/src/lib/sml-api/agentcard.ts +40 -0
- package/src/lib/sml-api/backtest.ts +47 -0
- package/src/lib/sml-api/brokers.ts +160 -0
- package/src/lib/sml-api/copytrader.ts +33 -0
- package/src/lib/sml-api/crawl.ts +44 -0
- package/src/lib/sml-api/echo.ts +28 -0
- package/src/lib/sml-api/forge.ts +33 -0
- package/src/lib/sml-api/ftd.ts +53 -0
- package/src/lib/sml-api/ghost.ts +35 -0
- package/src/lib/sml-api/launchpad.ts +43 -0
- package/src/lib/sml-api/leviathan.ts +49 -0
- package/src/lib/sml-api/nexus.ts +50 -0
- package/src/lib/sml-api/proof402.ts +27 -0
- package/src/lib/sml-api/rails.ts +34 -0
- package/src/lib/sml-api/shadow.ts +35 -0
- package/src/lib/sml-api/squeezeos.ts +95 -0
- package/src/lib/sml-api/xdeo.ts +40 -0
- package/src/lib/sml-api/xmit.ts +40 -0
- package/src/server/health.ts +52 -0
- package/src/server/index.ts +206 -0
- package/src/server/payments/ap2.ts +99 -0
- package/src/server/payments/receipt.ts +85 -0
- package/src/server/payments/router.ts +110 -0
- package/src/server/payments/wallet.ts +123 -0
- package/src/server/payments/x402.ts +162 -0
- package/src/server/registry/catalog.ts +61 -0
- package/src/server/registry/discovery.ts +39 -0
- package/src/server/registry/pricing.ts +76 -0
- package/src/server/security/acl.ts +42 -0
- package/src/server/security/audit.ts +94 -0
- package/src/server/security/rate-limit.ts +84 -0
- package/src/server/security/sandbox.ts +40 -0
- package/src/server/tools/agentcard.ts +134 -0
- package/src/server/tools/backtest.ts +119 -0
- package/src/server/tools/brokers.ts +250 -0
- package/src/server/tools/copytrader.ts +104 -0
- package/src/server/tools/crawl.ts +70 -0
- package/src/server/tools/discovery.ts +202 -0
- package/src/server/tools/echo.ts +58 -0
- package/src/server/tools/forge.ts +87 -0
- package/src/server/tools/ftd.ts +88 -0
- package/src/server/tools/ghost.ts +93 -0
- package/src/server/tools/index.ts +42 -0
- package/src/server/tools/launchpad.ts +173 -0
- package/src/server/tools/leviathan.ts +81 -0
- package/src/server/tools/nexus.ts +76 -0
- package/src/server/tools/proof402.ts +87 -0
- package/src/server/tools/rails.ts +92 -0
- package/src/server/tools/shadow.ts +128 -0
- package/src/server/tools/squeezeos.ts +312 -0
- package/src/server/tools/xdeo.ts +67 -0
- package/src/server/tools/xmit.ts +68 -0
- package/tests/integration/e2e.test.ts +51 -0
- package/tests/unit/payments.test.ts +49 -0
- package/tests/unit/security.test.ts +92 -0
- package/tests/unit/tools.test.ts +42 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +20 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AP2Client = void 0;
|
|
4
|
+
const audit_js_1 = require("../security/audit.js");
|
|
5
|
+
// In-memory mandate cache — 5 minute TTL per wallet+tool combination
|
|
6
|
+
const mandateCache = new Map();
|
|
7
|
+
class AP2Client {
|
|
8
|
+
static instance;
|
|
9
|
+
baseUrl;
|
|
10
|
+
constructor() {
|
|
11
|
+
this.baseUrl = process.env['SML_API_BASE'] ?? 'https://api.scriptmasterlabs.com';
|
|
12
|
+
}
|
|
13
|
+
static getInstance() {
|
|
14
|
+
if (!AP2Client.instance) {
|
|
15
|
+
AP2Client.instance = new AP2Client();
|
|
16
|
+
}
|
|
17
|
+
return AP2Client.instance;
|
|
18
|
+
}
|
|
19
|
+
async verifyMandate(wallet, params) {
|
|
20
|
+
const cacheKey = `${wallet}:${params.toolName}:${params.currency}`;
|
|
21
|
+
const cached = mandateCache.get(cacheKey);
|
|
22
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
23
|
+
return cached.valid;
|
|
24
|
+
}
|
|
25
|
+
const audit = audit_js_1.AuditLogger.getInstance();
|
|
26
|
+
try {
|
|
27
|
+
const controller = new AbortController();
|
|
28
|
+
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
29
|
+
const res = await fetch(`${this.baseUrl}/ap2/v1/mandate/verify`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: { 'Content-Type': 'application/json' },
|
|
32
|
+
body: JSON.stringify({
|
|
33
|
+
wallet,
|
|
34
|
+
max_amount: params.maxAmount,
|
|
35
|
+
currency: params.currency,
|
|
36
|
+
tool: params.toolName,
|
|
37
|
+
}),
|
|
38
|
+
signal: controller.signal,
|
|
39
|
+
});
|
|
40
|
+
clearTimeout(timeout);
|
|
41
|
+
if (!res.ok) {
|
|
42
|
+
audit.warn('ap2_mandate_http_error', { status: res.status, wallet });
|
|
43
|
+
mandateCache.set(cacheKey, { valid: false, expiresAt: Date.now() + 60_000 });
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const body = (await res.json());
|
|
47
|
+
const ttl = (body.expires_in ?? 300) * 1000;
|
|
48
|
+
mandateCache.set(cacheKey, { valid: body.valid, expiresAt: Date.now() + ttl });
|
|
49
|
+
return body.valid;
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
audit.error('ap2_mandate_error', { error: String(err), wallet });
|
|
53
|
+
// Fail closed — if AP2 is unreachable, deny payment
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async createMandate(wallet, params) {
|
|
58
|
+
const res = await fetch(`${this.baseUrl}/ap2/v1/mandate/create`, {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
headers: { 'Content-Type': 'application/json' },
|
|
61
|
+
body: JSON.stringify({
|
|
62
|
+
wallet,
|
|
63
|
+
daily_cap: params.dailyCap,
|
|
64
|
+
currency: params.currency,
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
if (!res.ok) {
|
|
68
|
+
throw new Error(`AP2 mandate creation failed: HTTP ${res.status}`);
|
|
69
|
+
}
|
|
70
|
+
const body = (await res.json());
|
|
71
|
+
return body.mandate_id;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.AP2Client = AP2Client;
|
|
75
|
+
//# sourceMappingURL=ap2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ap2.js","sourceRoot":"","sources":["../../../src/server/payments/ap2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface ReceiptInput {
|
|
2
|
+
txHash: string;
|
|
3
|
+
chain: string;
|
|
4
|
+
amount: string;
|
|
5
|
+
currency: string;
|
|
6
|
+
tool: string;
|
|
7
|
+
wallet: string;
|
|
8
|
+
}
|
|
9
|
+
export interface Receipt {
|
|
10
|
+
id: string;
|
|
11
|
+
txHash: string;
|
|
12
|
+
chain: string;
|
|
13
|
+
amount: string;
|
|
14
|
+
currency: string;
|
|
15
|
+
tool: string;
|
|
16
|
+
wallet: string;
|
|
17
|
+
issuedAt: number;
|
|
18
|
+
hash: string;
|
|
19
|
+
}
|
|
20
|
+
export declare class ReceiptStore {
|
|
21
|
+
private static instance;
|
|
22
|
+
private readonly baseUrl;
|
|
23
|
+
private constructor();
|
|
24
|
+
static getInstance(): ReceiptStore;
|
|
25
|
+
create(input: ReceiptInput): Promise<Receipt>;
|
|
26
|
+
private registerWithProofServer;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=receipt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.d.ts","sourceRoot":"","sources":["../../../src/server/payments/receipt.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,OAAO;IAIP,MAAM,CAAC,WAAW,IAAI,YAAY;IAO5B,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;YAuBrC,uBAAuB;CAsBtC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReceiptStore = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const audit_js_1 = require("../security/audit.js");
|
|
6
|
+
class ReceiptStore {
|
|
7
|
+
static instance;
|
|
8
|
+
baseUrl;
|
|
9
|
+
constructor() {
|
|
10
|
+
this.baseUrl = process.env['SML_API_BASE'] ?? 'https://api.scriptmasterlabs.com';
|
|
11
|
+
}
|
|
12
|
+
static getInstance() {
|
|
13
|
+
if (!ReceiptStore.instance) {
|
|
14
|
+
ReceiptStore.instance = new ReceiptStore();
|
|
15
|
+
}
|
|
16
|
+
return ReceiptStore.instance;
|
|
17
|
+
}
|
|
18
|
+
async create(input) {
|
|
19
|
+
const id = (0, crypto_1.randomUUID)();
|
|
20
|
+
const issuedAt = Date.now();
|
|
21
|
+
// Content hash for tamper detection
|
|
22
|
+
const hash = (0, crypto_1.createHash)('sha256')
|
|
23
|
+
.update(`${id}:${input.txHash}:${input.chain}:${input.amount}:${input.currency}:${input.tool}:${input.wallet}:${issuedAt}`)
|
|
24
|
+
.digest('hex');
|
|
25
|
+
const receipt = { id, ...input, issuedAt, hash };
|
|
26
|
+
// Attempt to register with 402Proof server (N7)
|
|
27
|
+
try {
|
|
28
|
+
await this.registerWithProofServer(receipt);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
// Log but don't fail — local receipt is still valid
|
|
32
|
+
audit_js_1.AuditLogger.getInstance().warn('proof_server_register_fail', { error: String(err), receiptId: id });
|
|
33
|
+
}
|
|
34
|
+
audit_js_1.AuditLogger.getInstance().info('receipt_issued', { receiptId: id, tool: input.tool });
|
|
35
|
+
return receipt;
|
|
36
|
+
}
|
|
37
|
+
async registerWithProofServer(receipt) {
|
|
38
|
+
const proofUrl = process.env['PROOF402_URL'] ?? 'https://four02proof.onrender.com';
|
|
39
|
+
const res = await fetch(`${proofUrl}/v1/receipt`, {
|
|
40
|
+
method: 'POST',
|
|
41
|
+
headers: { 'Content-Type': 'application/json' },
|
|
42
|
+
body: JSON.stringify({
|
|
43
|
+
receipt_id: receipt.id,
|
|
44
|
+
tx_hash: receipt.txHash,
|
|
45
|
+
chain: receipt.chain,
|
|
46
|
+
amount: receipt.amount,
|
|
47
|
+
currency: receipt.currency,
|
|
48
|
+
tool: receipt.tool,
|
|
49
|
+
wallet: receipt.wallet,
|
|
50
|
+
issued_at: receipt.issuedAt,
|
|
51
|
+
hash: receipt.hash,
|
|
52
|
+
}),
|
|
53
|
+
});
|
|
54
|
+
if (!res.ok) {
|
|
55
|
+
throw new Error(`402Proof server returned HTTP ${res.status}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.ReceiptStore = ReceiptStore;
|
|
60
|
+
//# sourceMappingURL=receipt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.js","sourceRoot":"","sources":["../../../src/server/payments/receipt.ts"],"names":[],"mappings":";;;AAAA,mCAAgD;AAChD,mDAAmD;AAuBnD,MAAa,YAAY;IACf,MAAM,CAAC,QAAQ,CAAe;IACrB,OAAO,CAAS;IAEjC;QACE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,kCAAkC,CAAC;IACnF,CAAC;IAED,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC3B,YAAY,CAAC,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;QAC7C,CAAC;QACD,OAAO,YAAY,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAmB;QAC9B,MAAM,EAAE,GAAG,IAAA,mBAAU,GAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE5B,oCAAoC;QACpC,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC;aAC9B,MAAM,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;aAC1H,MAAM,CAAC,KAAK,CAAC,CAAC;QAEjB,MAAM,OAAO,GAAY,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAE1D,gDAAgD;QAChD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,oDAAoD;YACpD,sBAAW,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QACtG,CAAC;QAED,sBAAW,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACtF,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,OAAgB;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,kCAAkC,CAAC;QACnF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,aAAa,EAAE;YAChD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,UAAU,EAAE,OAAO,CAAC,EAAE;gBACtB,OAAO,EAAE,OAAO,CAAC,MAAM;gBACvB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,OAAO,CAAC,QAAQ;gBAC3B,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;CACF;AA5DD,oCA4DC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface RouteParams {
|
|
2
|
+
amount: string;
|
|
3
|
+
currency: 'USDC' | 'RLUSD';
|
|
4
|
+
from: string;
|
|
5
|
+
to: string;
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface RouteResult {
|
|
9
|
+
txHash: string;
|
|
10
|
+
chain: string;
|
|
11
|
+
latencyMs: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class ChainRouter {
|
|
14
|
+
private readonly base;
|
|
15
|
+
private readonly xrpl;
|
|
16
|
+
private readonly solana;
|
|
17
|
+
private static instance;
|
|
18
|
+
private constructor();
|
|
19
|
+
static getInstance(): ChainRouter;
|
|
20
|
+
route(params: RouteParams): Promise<RouteResult>;
|
|
21
|
+
private withTimeout;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/server/payments/router.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,qBAAa,WAAW;IAIpB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAc;IAErC,OAAO;IAMP,MAAM,CAAC,WAAW,IAAI,WAAW;IAO3B,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAuDtD,OAAO,CAAC,WAAW;CAgBpB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChainRouter = void 0;
|
|
4
|
+
const audit_js_1 = require("../security/audit.js");
|
|
5
|
+
const base_js_1 = require("../../lib/chains/base.js");
|
|
6
|
+
const xrpl_js_1 = require("../../lib/chains/xrpl.js");
|
|
7
|
+
const solana_js_1 = require("../../lib/chains/solana.js");
|
|
8
|
+
// Chain preference order: cheapest/fastest first (N13)
|
|
9
|
+
const CHAIN_PREFERENCE = ['base', 'xrpl', 'solana'];
|
|
10
|
+
class ChainRouter {
|
|
11
|
+
base;
|
|
12
|
+
xrpl;
|
|
13
|
+
solana;
|
|
14
|
+
static instance;
|
|
15
|
+
constructor(base = base_js_1.BaseChain.getInstance(), xrpl = xrpl_js_1.XRPLChain.getInstance(), solana = solana_js_1.SolanaChain.getInstance()) {
|
|
16
|
+
this.base = base;
|
|
17
|
+
this.xrpl = xrpl;
|
|
18
|
+
this.solana = solana;
|
|
19
|
+
}
|
|
20
|
+
static getInstance() {
|
|
21
|
+
if (!ChainRouter.instance) {
|
|
22
|
+
ChainRouter.instance = new ChainRouter();
|
|
23
|
+
}
|
|
24
|
+
return ChainRouter.instance;
|
|
25
|
+
}
|
|
26
|
+
async route(params) {
|
|
27
|
+
const audit = audit_js_1.AuditLogger.getInstance();
|
|
28
|
+
const timeout = params.timeoutMs ?? 3000;
|
|
29
|
+
// For RLUSD, prefer XRPL
|
|
30
|
+
const ordered = params.currency === 'RLUSD'
|
|
31
|
+
? ['xrpl', 'base', 'solana']
|
|
32
|
+
: CHAIN_PREFERENCE;
|
|
33
|
+
const errors = [];
|
|
34
|
+
for (const chain of ordered) {
|
|
35
|
+
try {
|
|
36
|
+
const start = Date.now();
|
|
37
|
+
let txHash;
|
|
38
|
+
switch (chain) {
|
|
39
|
+
case 'base':
|
|
40
|
+
txHash = await this.withTimeout(this.base.sendPayment(params), timeout, 'base');
|
|
41
|
+
break;
|
|
42
|
+
case 'xrpl':
|
|
43
|
+
txHash = await this.withTimeout(this.xrpl.sendPayment(params), timeout, 'xrpl');
|
|
44
|
+
break;
|
|
45
|
+
case 'solana':
|
|
46
|
+
txHash = await this.withTimeout(this.solana.sendPayment(params), timeout, 'solana');
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
const latencyMs = Date.now() - start;
|
|
50
|
+
audit.info('chain_route_success', { chain, latencyMs, tx: txHash });
|
|
51
|
+
return { txHash, chain, latencyMs };
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const msg = String(err);
|
|
55
|
+
errors.push(`${chain}: ${msg}`);
|
|
56
|
+
audit.warn('chain_route_fail', { chain, error: msg });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
throw new Error(`All chains failed.\n${errors.join('\n')}`);
|
|
60
|
+
}
|
|
61
|
+
withTimeout(promise, ms, chain) {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
const t = setTimeout(() => reject(new Error(`${chain} timeout after ${ms}ms`)), ms);
|
|
64
|
+
promise.then((v) => { clearTimeout(t); resolve(v); }, (e) => { clearTimeout(t); reject(e); });
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.ChainRouter = ChainRouter;
|
|
69
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/server/payments/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface WalletInfo {
|
|
2
|
+
address: string;
|
|
3
|
+
chain: 'base' | 'xrpl' | 'solana';
|
|
4
|
+
}
|
|
5
|
+
export declare class WalletManager {
|
|
6
|
+
private static instance;
|
|
7
|
+
private cachedAddress;
|
|
8
|
+
private cachedSeed;
|
|
9
|
+
private constructor();
|
|
10
|
+
static getInstance(): WalletManager;
|
|
11
|
+
private keytarGet;
|
|
12
|
+
private keytarSet;
|
|
13
|
+
getSeed(): Promise<string>;
|
|
14
|
+
getOrCreateWallet(): Promise<WalletInfo>;
|
|
15
|
+
private deriveAddress;
|
|
16
|
+
signPayload(payload: string): Promise<string>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=wallet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../../src/server/payments/wallet.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;CACnC;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IACvC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,UAAU,CAAuB;IAEzC,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,aAAa;YAQrB,SAAS;YAST,SAAS;IAcjB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IA2B1B,iBAAiB,IAAI,OAAO,CAAC,UAAU,CAAC;YAahC,aAAa;IAkBrB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAgBpD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WalletManager = void 0;
|
|
4
|
+
const audit_js_1 = require("../security/audit.js");
|
|
5
|
+
const KEYCHAIN_SERVICE = 'mcp-x402';
|
|
6
|
+
const KEYCHAIN_ACCOUNT = 'master-seed';
|
|
7
|
+
class WalletManager {
|
|
8
|
+
static instance;
|
|
9
|
+
cachedAddress = null;
|
|
10
|
+
cachedSeed = null;
|
|
11
|
+
constructor() { }
|
|
12
|
+
static getInstance() {
|
|
13
|
+
if (!WalletManager.instance) {
|
|
14
|
+
WalletManager.instance = new WalletManager();
|
|
15
|
+
}
|
|
16
|
+
return WalletManager.instance;
|
|
17
|
+
}
|
|
18
|
+
// Try OS keychain; returns null if keytar is unavailable (Docker/cloud) or no entry exists.
|
|
19
|
+
async keytarGet() {
|
|
20
|
+
try {
|
|
21
|
+
const kt = await import('keytar');
|
|
22
|
+
return await kt.getPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async keytarSet(value) {
|
|
29
|
+
try {
|
|
30
|
+
const kt = await import('keytar');
|
|
31
|
+
await kt.setPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, value);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Silently skip — keytar unavailable in this environment
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Seed resolution priority:
|
|
38
|
+
// 1. OS keychain (local desktop — most secure)
|
|
39
|
+
// 2. WALLET_SEED env var (Render secret — cloud/Docker deployment)
|
|
40
|
+
// 3. CI_WALLET_SEED env var (CI only, never production)
|
|
41
|
+
// 4. Generate fresh and try to persist in keychain
|
|
42
|
+
async getSeed() {
|
|
43
|
+
if (this.cachedSeed)
|
|
44
|
+
return this.cachedSeed;
|
|
45
|
+
const audit = audit_js_1.AuditLogger.getInstance();
|
|
46
|
+
let seed = await this.keytarGet();
|
|
47
|
+
if (!seed) {
|
|
48
|
+
const envSeed = process.env['WALLET_SEED'];
|
|
49
|
+
if (envSeed) {
|
|
50
|
+
seed = envSeed;
|
|
51
|
+
audit.warn('wallet_env_seed', { note: 'Using WALLET_SEED env var (cloud deployment).' });
|
|
52
|
+
}
|
|
53
|
+
else if (process.env['CI_WALLET_SEED'] && process.env['NODE_ENV'] !== 'production') {
|
|
54
|
+
seed = process.env['CI_WALLET_SEED'];
|
|
55
|
+
audit.warn('wallet_ci_fallback', { note: 'Using CI_WALLET_SEED. NEVER do this in production.' });
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const { generateMnemonic } = await import('bip39');
|
|
59
|
+
seed = generateMnemonic(256);
|
|
60
|
+
await this.keytarSet(seed);
|
|
61
|
+
audit.info('wallet_created', { note: 'New BIP-39 seed generated.' });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
this.cachedSeed = seed;
|
|
65
|
+
return seed;
|
|
66
|
+
}
|
|
67
|
+
async getOrCreateWallet() {
|
|
68
|
+
if (this.cachedAddress) {
|
|
69
|
+
return { address: this.cachedAddress, chain: 'base' };
|
|
70
|
+
}
|
|
71
|
+
const audit = audit_js_1.AuditLogger.getInstance();
|
|
72
|
+
const seed = await this.getSeed();
|
|
73
|
+
const address = await this.deriveAddress(seed);
|
|
74
|
+
this.cachedAddress = address;
|
|
75
|
+
audit.info('wallet_loaded', { address });
|
|
76
|
+
return { address, chain: 'base' };
|
|
77
|
+
}
|
|
78
|
+
async deriveAddress(mnemonic) {
|
|
79
|
+
// BIP-44 deterministic derivation: m/44'/60'/0'/0/0 (Base = EVM)
|
|
80
|
+
const { mnemonicToSeedSync } = await import('bip39');
|
|
81
|
+
const { default: HDKey } = await import('hdkey');
|
|
82
|
+
const { privateKeyToAccount } = await import('viem/accounts');
|
|
83
|
+
const seed = mnemonicToSeedSync(mnemonic);
|
|
84
|
+
const hdkey = HDKey.fromMasterSeed(seed);
|
|
85
|
+
const child = hdkey.derive("m/44'/60'/0'/0/0");
|
|
86
|
+
if (!child.privateKey) {
|
|
87
|
+
throw new Error('Failed to derive private key from HD path');
|
|
88
|
+
}
|
|
89
|
+
const account = privateKeyToAccount(`0x${child.privateKey.toString('hex')}`);
|
|
90
|
+
return account.address;
|
|
91
|
+
}
|
|
92
|
+
async signPayload(payload) {
|
|
93
|
+
const mnemonic = await this.getSeed();
|
|
94
|
+
const { mnemonicToSeedSync } = await import('bip39');
|
|
95
|
+
const { default: HDKey } = await import('hdkey');
|
|
96
|
+
const { privateKeyToAccount } = await import('viem/accounts');
|
|
97
|
+
const seed = mnemonicToSeedSync(mnemonic);
|
|
98
|
+
const hdkey = HDKey.fromMasterSeed(seed);
|
|
99
|
+
const child = hdkey.derive("m/44'/60'/0'/0/0");
|
|
100
|
+
if (!child.privateKey)
|
|
101
|
+
throw new Error('Key derivation failed');
|
|
102
|
+
const account = privateKeyToAccount(`0x${child.privateKey.toString('hex')}`);
|
|
103
|
+
return account.signMessage({ message: payload });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.WalletManager = WalletManager;
|
|
107
|
+
//# sourceMappingURL=wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../../src/server/payments/wallet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const PaymentConfigSchema: z.ZodObject<{
|
|
3
|
+
price: z.ZodString;
|
|
4
|
+
currency: z.ZodEnum<["USDC", "RLUSD"]>;
|
|
5
|
+
toolName: z.ZodString;
|
|
6
|
+
walletAddress: z.ZodOptional<z.ZodString>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
currency: "USDC" | "RLUSD";
|
|
9
|
+
price: string;
|
|
10
|
+
toolName: string;
|
|
11
|
+
walletAddress?: string | undefined;
|
|
12
|
+
}, {
|
|
13
|
+
currency: "USDC" | "RLUSD";
|
|
14
|
+
price: string;
|
|
15
|
+
toolName: string;
|
|
16
|
+
walletAddress?: string | undefined;
|
|
17
|
+
}>;
|
|
18
|
+
export type PaymentConfig = z.infer<typeof PaymentConfigSchema>;
|
|
19
|
+
export interface PaymentResult {
|
|
20
|
+
receiptId: string;
|
|
21
|
+
txHash: string;
|
|
22
|
+
chain: string;
|
|
23
|
+
amountPaid: string;
|
|
24
|
+
currency: string;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
walletAddress: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function executeX402Payment(config: PaymentConfig): Promise<PaymentResult>;
|
|
29
|
+
//# sourceMappingURL=x402.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x402.d.ts","sourceRoot":"","sources":["../../../src/server/payments/x402.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;EAK9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AA6BD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,CAwGxB"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PaymentConfigSchema = void 0;
|
|
4
|
+
exports.executeX402Payment = executeX402Payment;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const audit_js_1 = require("../security/audit.js");
|
|
7
|
+
const ap2_js_1 = require("./ap2.js");
|
|
8
|
+
const wallet_js_1 = require("./wallet.js");
|
|
9
|
+
const router_js_1 = require("./router.js");
|
|
10
|
+
const receipt_js_1 = require("./receipt.js");
|
|
11
|
+
const bureau_js_1 = require("../../lib/credit/bureau.js");
|
|
12
|
+
const pricing_js_1 = require("../registry/pricing.js");
|
|
13
|
+
exports.PaymentConfigSchema = zod_1.z.object({
|
|
14
|
+
price: zod_1.z.string().regex(/^\d+(\.\d+)?$/),
|
|
15
|
+
currency: zod_1.z.enum(['USDC', 'RLUSD']),
|
|
16
|
+
toolName: zod_1.z.string(),
|
|
17
|
+
walletAddress: zod_1.z.string().optional(),
|
|
18
|
+
});
|
|
19
|
+
const AUTO_APPROVE_THRESHOLD = parseFloat(process.env['AUTO_APPROVE_THRESHOLD_USD'] ?? '1.0');
|
|
20
|
+
const DAILY_SPEND_CAP = parseFloat(process.env['DAILY_SPEND_CAP_USD'] ?? '50.0');
|
|
21
|
+
const dailySpend = new Map();
|
|
22
|
+
function getTodayKey() {
|
|
23
|
+
return new Date().toISOString().slice(0, 10);
|
|
24
|
+
}
|
|
25
|
+
function getDailySpend(wallet) {
|
|
26
|
+
const today = getTodayKey();
|
|
27
|
+
const entry = dailySpend.get(wallet);
|
|
28
|
+
if (!entry || entry.date !== today)
|
|
29
|
+
return 0;
|
|
30
|
+
return entry.amount;
|
|
31
|
+
}
|
|
32
|
+
function addDailySpend(wallet, amount) {
|
|
33
|
+
const today = getTodayKey();
|
|
34
|
+
const current = getDailySpend(wallet);
|
|
35
|
+
dailySpend.set(wallet, { amount: current + amount, date: today });
|
|
36
|
+
}
|
|
37
|
+
async function executeX402Payment(config) {
|
|
38
|
+
const audit = audit_js_1.AuditLogger.getInstance();
|
|
39
|
+
const wallet = await wallet_js_1.WalletManager.getInstance().getOrCreateWallet();
|
|
40
|
+
const walletAddress = wallet.address;
|
|
41
|
+
// Enforce daily spend cap (N9)
|
|
42
|
+
const priceNum = parseFloat(config.price);
|
|
43
|
+
const currentSpend = getDailySpend(walletAddress);
|
|
44
|
+
if (currentSpend + priceNum > DAILY_SPEND_CAP) {
|
|
45
|
+
audit.warn('spend_cap_exceeded', {
|
|
46
|
+
wallet: walletAddress,
|
|
47
|
+
current: currentSpend,
|
|
48
|
+
requested: priceNum,
|
|
49
|
+
cap: DAILY_SPEND_CAP,
|
|
50
|
+
});
|
|
51
|
+
throw new Error(`Daily spend cap of $${DAILY_SPEND_CAP} exceeded. Current: $${currentSpend.toFixed(4)}`);
|
|
52
|
+
}
|
|
53
|
+
// Verify price cache freshness (N12)
|
|
54
|
+
const cachedPrice = await pricing_js_1.PriceRegistry.getInstance().getPrice(config.toolName);
|
|
55
|
+
if (!cachedPrice) {
|
|
56
|
+
throw new Error('Price data stale or unavailable. Rejecting payment.');
|
|
57
|
+
}
|
|
58
|
+
if (cachedPrice !== config.price) {
|
|
59
|
+
throw new Error(`Price mismatch: expected ${cachedPrice}, got ${config.price}. Cache may be stale.`);
|
|
60
|
+
}
|
|
61
|
+
// Credit Bureau check (N8)
|
|
62
|
+
const score = await bureau_js_1.CreditBureau.getInstance().getScore(walletAddress);
|
|
63
|
+
const autoApprove = priceNum <= AUTO_APPROVE_THRESHOLD && score >= 300;
|
|
64
|
+
audit.info('payment_attempt', {
|
|
65
|
+
tool: config.toolName,
|
|
66
|
+
price: config.price,
|
|
67
|
+
currency: config.currency,
|
|
68
|
+
wallet: walletAddress,
|
|
69
|
+
bureauScore: score,
|
|
70
|
+
autoApprove,
|
|
71
|
+
});
|
|
72
|
+
if (!autoApprove && score < 300) {
|
|
73
|
+
throw new Error(`Credit Bureau score ${score} below minimum 300. Payment requires manual approval.`);
|
|
74
|
+
}
|
|
75
|
+
// AP2 mandate verification (N6)
|
|
76
|
+
const ap2 = ap2_js_1.AP2Client.getInstance();
|
|
77
|
+
const mandateValid = await ap2.verifyMandate(walletAddress, {
|
|
78
|
+
maxAmount: config.price,
|
|
79
|
+
currency: config.currency,
|
|
80
|
+
toolName: config.toolName,
|
|
81
|
+
});
|
|
82
|
+
if (!mandateValid) {
|
|
83
|
+
audit.warn('ap2_mandate_rejected', { wallet: walletAddress, tool: config.toolName });
|
|
84
|
+
throw new Error('AP2 mandate verification failed. Agent not authorized for this payment.');
|
|
85
|
+
}
|
|
86
|
+
// Route payment to cheapest/fastest chain (N13)
|
|
87
|
+
const router = router_js_1.ChainRouter.getInstance();
|
|
88
|
+
const txResult = await router.route({
|
|
89
|
+
amount: config.price,
|
|
90
|
+
currency: config.currency,
|
|
91
|
+
from: walletAddress,
|
|
92
|
+
to: process.env['SML_PAYMENT_RECEIVER'] ?? '',
|
|
93
|
+
timeoutMs: 500,
|
|
94
|
+
});
|
|
95
|
+
addDailySpend(walletAddress, priceNum);
|
|
96
|
+
// Generate 402Proof receipt (N7)
|
|
97
|
+
const receipt = await receipt_js_1.ReceiptStore.getInstance().create({
|
|
98
|
+
txHash: txResult.txHash,
|
|
99
|
+
chain: txResult.chain,
|
|
100
|
+
amount: config.price,
|
|
101
|
+
currency: config.currency,
|
|
102
|
+
tool: config.toolName,
|
|
103
|
+
wallet: walletAddress,
|
|
104
|
+
});
|
|
105
|
+
audit.info('payment_success', {
|
|
106
|
+
receiptId: receipt.id,
|
|
107
|
+
txHash: txResult.txHash,
|
|
108
|
+
chain: txResult.chain,
|
|
109
|
+
tool: config.toolName,
|
|
110
|
+
wallet: walletAddress,
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
receiptId: receipt.id,
|
|
114
|
+
txHash: txResult.txHash,
|
|
115
|
+
chain: txResult.chain,
|
|
116
|
+
amountPaid: config.price,
|
|
117
|
+
currency: config.currency,
|
|
118
|
+
timestamp: Date.now(),
|
|
119
|
+
walletAddress,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=x402.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x402.js","sourceRoot":"","sources":["../../../src/server/payments/x402.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ToolMeta {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
price: string;
|
|
5
|
+
currency: 'USDC' | 'RLUSD';
|
|
6
|
+
freeTier?: string;
|
|
7
|
+
ap2Required: boolean;
|
|
8
|
+
cacheTtl?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const CATALOG: ToolMeta[];
|
|
11
|
+
export declare function getToolMeta(name: string): ToolMeta | undefined;
|
|
12
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../src/server/registry/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,OAAO,EAAE,QAAQ,EA8C7B,CAAC;AAEF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAE9D"}
|