@x402janus/sdk 0.1.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 ADDED
@@ -0,0 +1,94 @@
1
+ # @x402janus/sdk
2
+
3
+ Wallet security for AI agents. One API call. Forensic wallet analysis. Deterministic risk score.
4
+
5
+ **x402-native** — no API keys, no accounts. Your agent pays per scan with USDC on Base.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @x402janus/sdk
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { JanusClient } from "@x402janus/sdk";
17
+
18
+ const janus = new JanusClient({
19
+ privateKey: process.env.PRIVATE_KEY, // Agent wallet key
20
+ });
21
+
22
+ const result = await janus.scan("0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18");
23
+
24
+ if (result.safe) {
25
+ // proceed with transaction
26
+ } else {
27
+ console.log("Blocked:", result.findings);
28
+ console.log("Revoke txs:", result.revokeTxs);
29
+ }
30
+ ```
31
+
32
+ ## How Payment Works
33
+
34
+ 1. Your agent calls `janus.scan(address)`
35
+ 2. The SDK hits the x402janus API, which returns HTTP 402 with payment requirements
36
+ 3. The SDK signs an EIP-3009 `TransferWithAuthorization` for the required USDC amount
37
+ 4. The signed payment is sent in the `X-PAYMENT` header on retry
38
+ 5. The Thirdweb facilitator verifies and settles USDC on Base
39
+ 6. Scan results are returned
40
+
41
+ **Your agent needs:**
42
+ - A private key (for signing — never sent to the API)
43
+ - USDC on Base (for scan payments)
44
+
45
+ ## API
46
+
47
+ ### `new JanusClient(config?)`
48
+
49
+ | Option | Type | Default | Description |
50
+ |--------|------|---------|-------------|
51
+ | `privateKey` | `string` | `process.env.PRIVATE_KEY` | Agent wallet private key |
52
+ | `baseUrl` | `string` | `https://x402janus.com` | API endpoint |
53
+ | `defaultTier` | `"quick" \| "standard" \| "deep"` | `"quick"` | Default scan tier |
54
+
55
+ ### `janus.scan(address, options?)`
56
+
57
+ Scan a wallet for security risks.
58
+
59
+ ```typescript
60
+ const result = await janus.scan("0x...", { tier: "deep" });
61
+ // result: { scanId, safe, risk, findings, revokeTxs }
62
+ ```
63
+
64
+ ### `janus.approvals(address)`
65
+
66
+ List active token approvals with risk assessment.
67
+
68
+ ### `janus.revoke(address)`
69
+
70
+ Get pre-built revoke transactions for dangerous approvals.
71
+
72
+ ### `janus.health()`
73
+
74
+ Check API health status.
75
+
76
+ ## Scan Tiers
77
+
78
+ | Tier | Price | Response Time | Coverage |
79
+ |------|-------|---------------|----------|
80
+ | `quick` | $0.01 | <3s | Deterministic risk score, approval list |
81
+ | `standard` | $0.05 | <10s | + AI threat analysis |
82
+ | `deep` | $0.25 | <30s | + Full graph analysis, drainer fingerprinting |
83
+
84
+ ## Types
85
+
86
+ All types are exported with Zod schemas for runtime validation:
87
+
88
+ ```typescript
89
+ import { ScanResult, ScanResultSchema, Finding, RevokeTx } from "@x402janus/sdk";
90
+ ```
91
+
92
+ ## License
93
+
94
+ MIT
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @module client
3
+ * JanusClient — the main entry point for @x402janus/sdk.
4
+ *
5
+ * Performs wallet security scans via the x402janus API with x402 micropayment.
6
+ */
7
+ import { type ScanResult, type ApprovalsResult, type RevokeTx, type HealthResult, type JanusClientConfig, type ScanOptions } from "./types.js";
8
+ /**
9
+ * JanusClient — scan wallets for security risks via x402janus.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { JanusClient } from "@x402janus/sdk";
14
+ *
15
+ * const janus = new JanusClient({ privateKey: process.env.PRIVATE_KEY });
16
+ * const result = await janus.scan("0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18");
17
+ *
18
+ * if (result.safe) {
19
+ * // proceed with transaction
20
+ * } else {
21
+ * console.log("Blocked:", result.findings);
22
+ * }
23
+ * ```
24
+ */
25
+ export declare class JanusClient {
26
+ private readonly baseUrl;
27
+ private readonly privateKey;
28
+ private readonly defaultTier;
29
+ private readonly facilitatorUrl;
30
+ constructor(config?: JanusClientConfig);
31
+ /**
32
+ * Scan a wallet for security risks.
33
+ *
34
+ * @param address - Ethereum wallet address (0x...)
35
+ * @param options - Optional scan configuration
36
+ * @returns Structured scan result with risk score, findings, and revoke transactions
37
+ * @throws If the address is invalid, payment fails, or the API returns an error
38
+ */
39
+ scan(address: string, options?: ScanOptions): Promise<ScanResult>;
40
+ /**
41
+ * List all active token approvals for a wallet.
42
+ *
43
+ * @param address - Ethereum wallet address (0x...)
44
+ * @returns List of approvals with risk assessment
45
+ */
46
+ approvals(address: string): Promise<ApprovalsResult>;
47
+ /**
48
+ * Build revoke transactions for dangerous approvals.
49
+ *
50
+ * @param address - Ethereum wallet address (0x...)
51
+ * @returns Array of pre-built revoke transactions
52
+ */
53
+ revoke(address: string): Promise<RevokeTx[]>;
54
+ /**
55
+ * Check API health status.
56
+ *
57
+ * @returns Health status of the x402janus API
58
+ */
59
+ health(): Promise<HealthResult>;
60
+ /**
61
+ * Handle the x402 payment flow: parse 402 requirements, sign, retry.
62
+ */
63
+ private handlePaymentFlow;
64
+ /**
65
+ * Extract payment requirements from a 402 response body.
66
+ */
67
+ private extractPaymentRequirements;
68
+ /**
69
+ * Validate a scan result, enforcing the safety invariant.
70
+ *
71
+ * @param paid - Whether this response came after a verified payment.
72
+ * If false, `safe` is forced to `false` as a security measure.
73
+ */
74
+ private validateScanResult;
75
+ /**
76
+ * Validate an Ethereum address.
77
+ * @throws If the address is not a valid 0x-prefixed hex string
78
+ */
79
+ private validateAddress;
80
+ }
81
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EASL,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AASpB;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,MAAM,GAAE,iBAAsB;IAgB1C;;;;;;;OAOG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IA2BvE;;;;;OAKG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA6B1D;;;;;OAKG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKlD;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC;IAWrC;;OAEG;YACW,iBAAiB;IA6D/B;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAclC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;;OAGG;IACH,OAAO,CAAC,eAAe;CAKxB"}
package/dist/client.js ADDED
@@ -0,0 +1,212 @@
1
+ /**
2
+ * @module client
3
+ * JanusClient — the main entry point for @x402janus/sdk.
4
+ *
5
+ * Performs wallet security scans via the x402janus API with x402 micropayment.
6
+ */
7
+ import { ScanTierSchema, ScanResultSchema, ApprovalsResultSchema, HealthResultSchema, PaymentRequirementsSchema, TIER_PRICES, } from "./types.js";
8
+ import { signX402Payment } from "./payment.js";
9
+ /** Ethereum address regex (0x + 40 hex chars) */
10
+ const ETH_ADDRESS = /^0x[a-fA-F0-9]{40}$/;
11
+ /** Maximum retry-after sleep (30 seconds) — prevents unbounded waits */
12
+ const MAX_RETRY_SLEEP_MS = 30_000;
13
+ /**
14
+ * JanusClient — scan wallets for security risks via x402janus.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { JanusClient } from "@x402janus/sdk";
19
+ *
20
+ * const janus = new JanusClient({ privateKey: process.env.PRIVATE_KEY });
21
+ * const result = await janus.scan("0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18");
22
+ *
23
+ * if (result.safe) {
24
+ * // proceed with transaction
25
+ * } else {
26
+ * console.log("Blocked:", result.findings);
27
+ * }
28
+ * ```
29
+ */
30
+ export class JanusClient {
31
+ baseUrl;
32
+ privateKey;
33
+ defaultTier;
34
+ facilitatorUrl;
35
+ constructor(config = {}) {
36
+ this.baseUrl = (config.baseUrl ?? "https://x402janus.com").replace(/\/$/, "");
37
+ this.defaultTier = config.defaultTier ?? "quick";
38
+ this.facilitatorUrl =
39
+ config.facilitatorUrl ??
40
+ process.env.FACILITATOR_URL ??
41
+ "https://x402.org";
42
+ // Resolve private key — never expose in errors
43
+ const pk = config.privateKey ?? process.env.PRIVATE_KEY;
44
+ this.privateKey = pk || undefined;
45
+ // Validate default tier
46
+ ScanTierSchema.parse(this.defaultTier);
47
+ }
48
+ /**
49
+ * Scan a wallet for security risks.
50
+ *
51
+ * @param address - Ethereum wallet address (0x...)
52
+ * @param options - Optional scan configuration
53
+ * @returns Structured scan result with risk score, findings, and revoke transactions
54
+ * @throws If the address is invalid, payment fails, or the API returns an error
55
+ */
56
+ async scan(address, options) {
57
+ this.validateAddress(address);
58
+ const tier = options?.tier ?? this.defaultTier;
59
+ ScanTierSchema.parse(tier);
60
+ const url = `${this.baseUrl}/api/guardian/scan/${address}?tier=${tier}`;
61
+ // First request — expect 402 with payment requirements
62
+ const initial = await fetch(url, {
63
+ method: "POST",
64
+ headers: { "Content-Type": "application/json" },
65
+ });
66
+ if (initial.status === 402) {
67
+ // Parse payment requirements and sign
68
+ return this.handlePaymentFlow(url, initial, tier);
69
+ }
70
+ if (initial.ok) {
71
+ // Free tier or already paid — parse and validate
72
+ const data = await initial.json();
73
+ return this.validateScanResult(data);
74
+ }
75
+ throw new Error(`Scan failed: HTTP ${initial.status} ${initial.statusText}`);
76
+ }
77
+ /**
78
+ * List all active token approvals for a wallet.
79
+ *
80
+ * @param address - Ethereum wallet address (0x...)
81
+ * @returns List of approvals with risk assessment
82
+ */
83
+ async approvals(address) {
84
+ this.validateAddress(address);
85
+ const url = `${this.baseUrl}/api/guardian/scan/${address}?tier=quick&mode=approvals`;
86
+ const initial = await fetch(url, {
87
+ method: "POST",
88
+ headers: { "Content-Type": "application/json" },
89
+ });
90
+ if (initial.status === 402 && this.privateKey) {
91
+ const paymentResult = await this.handlePaymentFlow(url, initial, "quick");
92
+ // Map scan result to approvals format
93
+ return {
94
+ wallet: address,
95
+ approvals: [],
96
+ riskCount: { low: 0, medium: 0, high: 0, critical: 0 },
97
+ ...paymentResult,
98
+ };
99
+ }
100
+ if (initial.ok) {
101
+ const data = await initial.json();
102
+ return ApprovalsResultSchema.parse(data);
103
+ }
104
+ throw new Error(`Approvals failed: HTTP ${initial.status}`);
105
+ }
106
+ /**
107
+ * Build revoke transactions for dangerous approvals.
108
+ *
109
+ * @param address - Ethereum wallet address (0x...)
110
+ * @returns Array of pre-built revoke transactions
111
+ */
112
+ async revoke(address) {
113
+ const result = await this.scan(address, { tier: "standard" });
114
+ return result.revokeTxs;
115
+ }
116
+ /**
117
+ * Check API health status.
118
+ *
119
+ * @returns Health status of the x402janus API
120
+ */
121
+ async health() {
122
+ const resp = await fetch(`${this.baseUrl}/api/health`);
123
+ if (!resp.ok) {
124
+ throw new Error(`Health check failed: HTTP ${resp.status}`);
125
+ }
126
+ const data = await resp.json();
127
+ return HealthResultSchema.parse(data);
128
+ }
129
+ // ─── Private helpers ─────────────────────────────────────────────────────
130
+ /**
131
+ * Handle the x402 payment flow: parse 402 requirements, sign, retry.
132
+ */
133
+ async handlePaymentFlow(url, response, tier) {
134
+ if (!this.privateKey) {
135
+ throw new Error(`Scan tier "${tier}" (${TIER_PRICES[tier].dollars}) requires a private key for x402 payment. ` +
136
+ `Pass privateKey in config or set PRIVATE_KEY env var.`);
137
+ }
138
+ // Parse payment requirements from 402 response
139
+ const body = await response.json();
140
+ const requirements = this.extractPaymentRequirements(body);
141
+ // Sign the payment
142
+ const paymentHeader = await signX402Payment(this.privateKey, requirements);
143
+ // Retry with payment header
144
+ const paid = await fetch(url, {
145
+ method: "POST",
146
+ headers: {
147
+ "Content-Type": "application/json",
148
+ "X-PAYMENT": paymentHeader,
149
+ },
150
+ });
151
+ // Handle retry-after (rate limiting)
152
+ if (paid.status === 429) {
153
+ const retryAfter = paid.headers.get("retry-after");
154
+ const sleepMs = Math.min((retryAfter ? parseInt(retryAfter, 10) * 1000 : 5000), MAX_RETRY_SLEEP_MS);
155
+ await new Promise((r) => setTimeout(r, sleepMs));
156
+ const retry = await fetch(url, {
157
+ method: "POST",
158
+ headers: {
159
+ "Content-Type": "application/json",
160
+ "X-PAYMENT": paymentHeader,
161
+ },
162
+ });
163
+ if (!retry.ok) {
164
+ throw new Error(`Scan failed after retry: HTTP ${retry.status}`);
165
+ }
166
+ const data = await retry.json();
167
+ return this.validateScanResult(data, true);
168
+ }
169
+ if (!paid.ok) {
170
+ throw new Error(`Scan failed after payment: HTTP ${paid.status} ${paid.statusText}`);
171
+ }
172
+ const data = await paid.json();
173
+ return this.validateScanResult(data, true);
174
+ }
175
+ /**
176
+ * Extract payment requirements from a 402 response body.
177
+ */
178
+ extractPaymentRequirements(body) {
179
+ if (typeof body !== "object" || body === null) {
180
+ throw new Error("Invalid 402 response: no payment requirements");
181
+ }
182
+ const obj = body;
183
+ const reqs = obj.paymentRequirements ?? obj.requirements ?? obj;
184
+ // Handle array format (take first)
185
+ const single = Array.isArray(reqs) ? reqs[0] : reqs;
186
+ return PaymentRequirementsSchema.parse(single);
187
+ }
188
+ /**
189
+ * Validate a scan result, enforcing the safety invariant.
190
+ *
191
+ * @param paid - Whether this response came after a verified payment.
192
+ * If false, `safe` is forced to `false` as a security measure.
193
+ */
194
+ validateScanResult(data, paid = false) {
195
+ const result = ScanResultSchema.parse(data);
196
+ // Security invariant: never return safe=true without payment verification
197
+ if (!paid && result.safe) {
198
+ return { ...result, safe: false };
199
+ }
200
+ return result;
201
+ }
202
+ /**
203
+ * Validate an Ethereum address.
204
+ * @throws If the address is not a valid 0x-prefixed hex string
205
+ */
206
+ validateAddress(address) {
207
+ if (!ETH_ADDRESS.test(address)) {
208
+ throw new Error(`Invalid Ethereum address: ${address.slice(0, 10)}...`);
209
+ }
210
+ }
211
+ }
212
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EAErB,kBAAkB,EAClB,yBAAyB,EACzB,WAAW,GAQZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,iDAAiD;AACjD,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAE1C,wEAAwE;AACxE,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,WAAW;IACL,OAAO,CAAS;IAChB,UAAU,CAAqB;IAC/B,WAAW,CAAW;IACtB,cAAc,CAAS;IAExC,YAAY,SAA4B,EAAE;QACxC,IAAI,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,OAAO,CAAC;QACjD,IAAI,CAAC,cAAc;YACjB,MAAM,CAAC,cAAc;gBACrB,OAAO,CAAC,GAAG,CAAC,eAAe;gBAC3B,kBAAkB,CAAC;QAErB,+CAA+C;QAC/C,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACxD,IAAI,CAAC,UAAU,GAAG,EAAE,IAAI,SAAS,CAAC;QAElC,wBAAwB;QACxB,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CAAC,OAAe,EAAE,OAAqB;QAC/C,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;QAC/C,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE3B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,sBAAsB,OAAO,SAAS,IAAI,EAAE,CAAC;QAExE,uDAAuD;QACvD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC/B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;SAChD,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC3B,sCAAsC;YACtC,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,iDAAiD;YACjD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,SAAS,CAAC,OAAe;QAC7B,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAE9B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,sBAAsB,OAAO,4BAA4B,CAAC;QAErF,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC/B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;SAChD,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC9C,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAC1E,sCAAsC;YACtC,OAAO;gBACL,MAAM,EAAE,OAAO;gBACf,SAAS,EAAE,EAAE;gBACb,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;gBACtD,GAAG,aAAa;aACa,CAAC;QAClC,CAAC;QAED,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,0BAA0B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,aAAa,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,OAAO,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,4EAA4E;IAE5E;;OAEG;IACK,KAAK,CAAC,iBAAiB,CAC7B,GAAW,EACX,QAAkB,EAClB,IAAc;QAEd,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,cAAc,IAAI,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,6CAA6C;gBAC9F,uDAAuD,CACxD,CAAC;QACJ,CAAC;QAED,+CAA+C;QAC/C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,YAAY,GAAG,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC;QAE3D,mBAAmB;QACnB,MAAM,aAAa,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,UAA2B,EAAE,YAAY,CAAC,CAAC;QAE5F,4BAA4B;QAC5B,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC5B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,aAAa;aAC3B;SACF,CAAC,CAAC;QAEH,qCAAqC;QACrC,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACxB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EACrD,kBAAkB,CACnB,CAAC;YACF,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YAEjD,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC7B,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,WAAW,EAAE,aAAa;iBAC3B;aACF,CAAC,CAAC;YAEH,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YACnE,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACvF,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACK,0BAA0B,CAAC,IAAa;QAC9C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,GAAG,GAAG,IAA+B,CAAC;QAC5C,MAAM,IAAI,GAAG,GAAG,CAAC,mBAAmB,IAAI,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC;QAEhE,mCAAmC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAEpD,OAAO,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACK,kBAAkB,CAAC,IAAa,EAAE,IAAI,GAAG,KAAK;QACpD,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE5C,0EAA0E;QAC1E,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YACzB,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACpC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACK,eAAe,CAAC,OAAe;QACrC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,6BAA6B,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @x402janus/sdk — AI wallet security for agents.
3
+ *
4
+ * One API call. Forensic wallet analysis. Deterministic risk score.
5
+ * x402-native pay-per-scan on Base.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { JanusClient } from "@x402janus/sdk";
10
+ *
11
+ * const janus = new JanusClient({ privateKey: process.env.PRIVATE_KEY });
12
+ * const result = await janus.scan("0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18");
13
+ *
14
+ * if (result.safe) {
15
+ * // proceed with transaction
16
+ * } else {
17
+ * console.log("Blocked:", result.findings);
18
+ * }
19
+ * ```
20
+ *
21
+ * @packageDocumentation
22
+ */
23
+ export { JanusClient } from "./client.js";
24
+ export type { ScanTier, ScanResult, Finding, FindingSeverity, RevokeTx, Approval, ApprovalsResult, HealthResult, JanusClientConfig, ScanOptions, PaymentRequirements, } from "./types.js";
25
+ export { ScanTierSchema, ScanResultSchema, FindingSchema, RevokeTxSchema, ApprovalSchema, ApprovalsResultSchema, HealthResultSchema, PaymentRequirementsSchema, TIER_PRICES, } from "./types.js";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,YAAY,EACV,QAAQ,EACR,UAAU,EACV,OAAO,EACP,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,yBAAyB,EACzB,WAAW,GACZ,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @x402janus/sdk — AI wallet security for agents.
3
+ *
4
+ * One API call. Forensic wallet analysis. Deterministic risk score.
5
+ * x402-native pay-per-scan on Base.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { JanusClient } from "@x402janus/sdk";
10
+ *
11
+ * const janus = new JanusClient({ privateKey: process.env.PRIVATE_KEY });
12
+ * const result = await janus.scan("0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18");
13
+ *
14
+ * if (result.safe) {
15
+ * // proceed with transaction
16
+ * } else {
17
+ * console.log("Blocked:", result.findings);
18
+ * }
19
+ * ```
20
+ *
21
+ * @packageDocumentation
22
+ */
23
+ export { JanusClient } from "./client.js";
24
+ // Re-export schemas for runtime validation
25
+ export { ScanTierSchema, ScanResultSchema, FindingSchema, RevokeTxSchema, ApprovalSchema, ApprovalsResultSchema, HealthResultSchema, PaymentRequirementsSchema, TIER_PRICES, } from "./types.js";
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB1C,2CAA2C;AAC3C,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,yBAAyB,EACzB,WAAW,GACZ,MAAM,YAAY,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @module payment
3
+ * x402 micropayment signing for @x402janus/sdk.
4
+ *
5
+ * Implements EIP-3009 TransferWithAuthorization — the standard used by
6
+ * Circle's USDC on Base. Signs the authorization using the agent's private
7
+ * key and encodes it as a base64 payload for the PAYMENT-SIGNATURE header.
8
+ *
9
+ * **Security**: The private key is used only within this module for signing.
10
+ * It is never included in return values, error messages, or console output.
11
+ */
12
+ import type { PaymentRequirements } from "./types.js";
13
+ /**
14
+ * Sign an x402 payment using EIP-3009 TransferWithAuthorization.
15
+ *
16
+ * This implements the client side of the x402 payment protocol:
17
+ * 1. Builds the authorization parameters (from, to, value, validity window, nonce)
18
+ * 2. Signs them with the agent's private key via EIP-712
19
+ * 3. Encodes the signed payload as base64 for the `PAYMENT-SIGNATURE` header
20
+ *
21
+ * The function defaults to `TransferWithAuthorization` (EIP-3009) which is
22
+ * what Circle's USDC on Base supports. If the server's extra field specifies
23
+ * `primaryType: "Permit"`, an EIP-2612 Permit signature is used instead.
24
+ *
25
+ * @param privateKey - The payer's private key. **Never logged or thrown.**
26
+ * @param requirements - Payment requirements from the server's 402 response
27
+ * @returns Base64-encoded signed payment payload string
28
+ * @throws {Error} If scheme is unsupported or signing fails (key never exposed)
29
+ */
30
+ export declare function signX402Payment(privateKey: `0x${string}`, requirements: PaymentRequirements): Promise<string>;
31
+ //# sourceMappingURL=payment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment.d.ts","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAkEtD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,YAAY,EAAE,mBAAmB,GAChC,OAAO,CAAC,MAAM,CAAC,CAgHjB"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * @module payment
3
+ * x402 micropayment signing for @x402janus/sdk.
4
+ *
5
+ * Implements EIP-3009 TransferWithAuthorization — the standard used by
6
+ * Circle's USDC on Base. Signs the authorization using the agent's private
7
+ * key and encodes it as a base64 payload for the PAYMENT-SIGNATURE header.
8
+ *
9
+ * **Security**: The private key is used only within this module for signing.
10
+ * It is never included in return values, error messages, or console output.
11
+ */
12
+ import { privateKeyToAccount } from "viem/accounts";
13
+ import { toHex } from "viem";
14
+ // ─── Constants ───────────────────────────────────────────────────────────────
15
+ /** x402 protocol version supported by this SDK */
16
+ const X402_VERSION = 2;
17
+ /** x402 schemes we can handle */
18
+ const SUPPORTED_SCHEMES = new Set(["exact"]);
19
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
20
+ /**
21
+ * Parse an EVM chain ID from a CAIP-2 network identifier.
22
+ * @param network - e.g. "eip155:8453"
23
+ * @returns The chain ID as a number (e.g. 8453)
24
+ * @throws {Error} If the format is unrecognised
25
+ */
26
+ function parseChainId(network) {
27
+ const match = /^eip155:(\d+)$/.exec(network);
28
+ if (!match || !match[1]) {
29
+ throw new Error(`Unsupported network format: "${network}". Expected "eip155:<chainId>".`);
30
+ }
31
+ return parseInt(match[1], 10);
32
+ }
33
+ /**
34
+ * Generate a cryptographically random 32-byte nonce for EIP-3009.
35
+ * Uses the Web Crypto API (available natively in Node.js 18+).
36
+ *
37
+ * EIP-3009 nonces are non-sequential bytes32 values; once used,
38
+ * the contract marks them as spent to prevent replay attacks.
39
+ */
40
+ async function generateNonce() {
41
+ const bytes = new Uint8Array(32);
42
+ if (typeof globalThis !== "undefined" &&
43
+ typeof globalThis.crypto !== "undefined" &&
44
+ typeof globalThis.crypto.getRandomValues === "function") {
45
+ globalThis.crypto.getRandomValues(bytes);
46
+ }
47
+ else {
48
+ // Node.js without globalThis.crypto (older Node versions)
49
+ const { webcrypto } = await import("node:crypto");
50
+ webcrypto.getRandomValues(bytes);
51
+ }
52
+ return toHex(bytes);
53
+ }
54
+ /**
55
+ * Base64-encode a string (works in both Node.js and browser environments).
56
+ */
57
+ function encodeBase64(data) {
58
+ if (typeof Buffer !== "undefined") {
59
+ return Buffer.from(data, "utf-8").toString("base64");
60
+ }
61
+ // Browser / edge runtime
62
+ return btoa(data);
63
+ }
64
+ // ─── Core signing function ────────────────────────────────────────────────────
65
+ /**
66
+ * Sign an x402 payment using EIP-3009 TransferWithAuthorization.
67
+ *
68
+ * This implements the client side of the x402 payment protocol:
69
+ * 1. Builds the authorization parameters (from, to, value, validity window, nonce)
70
+ * 2. Signs them with the agent's private key via EIP-712
71
+ * 3. Encodes the signed payload as base64 for the `PAYMENT-SIGNATURE` header
72
+ *
73
+ * The function defaults to `TransferWithAuthorization` (EIP-3009) which is
74
+ * what Circle's USDC on Base supports. If the server's extra field specifies
75
+ * `primaryType: "Permit"`, an EIP-2612 Permit signature is used instead.
76
+ *
77
+ * @param privateKey - The payer's private key. **Never logged or thrown.**
78
+ * @param requirements - Payment requirements from the server's 402 response
79
+ * @returns Base64-encoded signed payment payload string
80
+ * @throws {Error} If scheme is unsupported or signing fails (key never exposed)
81
+ */
82
+ export async function signX402Payment(privateKey, requirements) {
83
+ if (!SUPPORTED_SCHEMES.has(requirements.scheme)) {
84
+ throw new Error(`Unsupported x402 scheme: "${requirements.scheme}". Supported: ${[...SUPPORTED_SCHEMES].join(", ")}`);
85
+ }
86
+ const chainId = parseChainId(requirements.network);
87
+ // Build account from private key — key stays inside this closure
88
+ const account = privateKeyToAccount(privateKey);
89
+ const now = Math.floor(Date.now() / 1000);
90
+ // Allow 24 hours retroactive validity to smooth over clock skew
91
+ const validAfterBigInt = BigInt(now - 86_400);
92
+ // Upper bound: current time + server-specified timeout
93
+ const validBeforeBigInt = BigInt(now + requirements.maxTimeoutSeconds);
94
+ const nonce = await generateNonce();
95
+ const extra = requirements.extra;
96
+ const tokenName = extra?.["name"] ?? "USD Coin";
97
+ const tokenVersion = extra?.["version"] ?? "2";
98
+ const primaryType = extra?.["primaryType"] ?? "TransferWithAuthorization";
99
+ let signature;
100
+ try {
101
+ if (primaryType === "Permit") {
102
+ // EIP-2612 Permit (for tokens that don't support EIP-3009)
103
+ signature = await account.signTypedData({
104
+ domain: {
105
+ name: tokenName,
106
+ version: tokenVersion,
107
+ chainId,
108
+ verifyingContract: requirements.asset,
109
+ },
110
+ types: {
111
+ Permit: [
112
+ { name: "owner", type: "address" },
113
+ { name: "spender", type: "address" },
114
+ { name: "value", type: "uint256" },
115
+ { name: "nonce", type: "uint256" },
116
+ { name: "deadline", type: "uint256" },
117
+ ],
118
+ },
119
+ primaryType: "Permit",
120
+ message: {
121
+ owner: account.address,
122
+ spender: requirements.payTo,
123
+ value: BigInt(requirements.maxAmountRequired),
124
+ // For Permit, nonce would normally be fetched on-chain. Here we use 0
125
+ // as a placeholder — real deployments should fetch via nonces(owner).
126
+ nonce: 0n,
127
+ deadline: validBeforeBigInt,
128
+ },
129
+ });
130
+ }
131
+ else {
132
+ // EIP-3009 TransferWithAuthorization (default — USDC on Base)
133
+ signature = await account.signTypedData({
134
+ domain: {
135
+ name: tokenName,
136
+ version: tokenVersion,
137
+ chainId,
138
+ verifyingContract: requirements.asset,
139
+ },
140
+ types: {
141
+ TransferWithAuthorization: [
142
+ { name: "from", type: "address" },
143
+ { name: "to", type: "address" },
144
+ { name: "value", type: "uint256" },
145
+ { name: "validAfter", type: "uint256" },
146
+ { name: "validBefore", type: "uint256" },
147
+ { name: "nonce", type: "bytes32" },
148
+ ],
149
+ },
150
+ primaryType: "TransferWithAuthorization",
151
+ message: {
152
+ from: account.address,
153
+ to: requirements.payTo,
154
+ value: BigInt(requirements.maxAmountRequired),
155
+ validAfter: validAfterBigInt,
156
+ validBefore: validBeforeBigInt,
157
+ nonce,
158
+ },
159
+ });
160
+ }
161
+ }
162
+ catch (err) {
163
+ // Catch and re-throw without any key material
164
+ const msg = err instanceof Error ? err.message : "Unknown signing error";
165
+ throw new Error(`x402 payment signing failed: ${msg}`);
166
+ }
167
+ // Build the payment payload (x402 v2 format)
168
+ const payload = {
169
+ x402Version: X402_VERSION,
170
+ scheme: requirements.scheme,
171
+ network: requirements.network,
172
+ payload: {
173
+ signature,
174
+ authorization: {
175
+ from: account.address,
176
+ to: requirements.payTo,
177
+ value: requirements.maxAmountRequired,
178
+ validAfter: validAfterBigInt.toString(),
179
+ validBefore: validBeforeBigInt.toString(),
180
+ nonce,
181
+ },
182
+ },
183
+ };
184
+ return encodeBase64(JSON.stringify(payload));
185
+ }
186
+ //# sourceMappingURL=payment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment.js","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,412 @@
1
+ /**
2
+ * @module types
3
+ * All public types and Zod schemas for @x402janus/sdk.
4
+ */
5
+ import { z } from "zod";
6
+ /**
7
+ * Scan tier controlling analysis depth and x402 micropayment amount.
8
+ *
9
+ * | Tier | Price | Description |
10
+ * |----------|--------|-----------------------------------------------------|
11
+ * | quick | $0.01 | Fast heuristic scan — known drainers & risk signals |
12
+ * | standard | $0.05 | Graph analysis + threat-intel correlation |
13
+ * | deep | $0.25 | Full forensic scan + approval chain tracing |
14
+ */
15
+ export declare const ScanTierSchema: z.ZodEnum<["quick", "standard", "deep"]>;
16
+ /** @see {@link ScanTierSchema} */
17
+ export type ScanTier = z.infer<typeof ScanTierSchema>;
18
+ /**
19
+ * USDC pricing for each scan tier (6-decimal precision, Base mainnet).
20
+ * `units` is the raw USDC atomic value passed in the x402 payment header.
21
+ */
22
+ export declare const TIER_PRICES: Readonly<Record<ScanTier, {
23
+ dollars: string;
24
+ units: string;
25
+ }>>;
26
+ /**
27
+ * Severity level for a security finding.
28
+ */
29
+ export type FindingSeverity = "critical" | "high" | "medium" | "low" | "info";
30
+ /**
31
+ * A single security finding returned in a wallet scan.
32
+ */
33
+ export declare const FindingSchema: z.ZodObject<{
34
+ /** Machine-readable finding type (e.g. "unlimited_approval", "known_drainer") */
35
+ type: z.ZodString;
36
+ /** Severity of the finding */
37
+ severity: z.ZodEnum<["critical", "high", "medium", "low", "info"]>;
38
+ /** Human-readable description */
39
+ description: z.ZodString;
40
+ /** Relevant contract or counterparty address, if applicable */
41
+ address: z.ZodOptional<z.ZodString>;
42
+ /** Protocol name associated with the finding, if known */
43
+ protocol: z.ZodOptional<z.ZodString>;
44
+ /** Token amount at risk (human-readable), if applicable */
45
+ amount: z.ZodOptional<z.ZodString>;
46
+ }, "strip", z.ZodTypeAny, {
47
+ type: string;
48
+ severity: "critical" | "high" | "medium" | "low" | "info";
49
+ description: string;
50
+ address?: string | undefined;
51
+ protocol?: string | undefined;
52
+ amount?: string | undefined;
53
+ }, {
54
+ type: string;
55
+ severity: "critical" | "high" | "medium" | "low" | "info";
56
+ description: string;
57
+ address?: string | undefined;
58
+ protocol?: string | undefined;
59
+ amount?: string | undefined;
60
+ }>;
61
+ /** @see {@link FindingSchema} */
62
+ export type Finding = z.infer<typeof FindingSchema>;
63
+ /**
64
+ * A revoke transaction that the agent can sign and submit to remove a risky approval.
65
+ * Transactions are pre-built by the x402janus API — submit them as-is.
66
+ */
67
+ export declare const RevokeTxSchema: z.ZodObject<{
68
+ /** Target contract address (the token contract) */
69
+ to: z.ZodString;
70
+ /** ABI-encoded calldata (e.g., `approve(spender, 0)`) */
71
+ data: z.ZodString;
72
+ /** EVM chain ID (e.g., 8453 for Base) */
73
+ chainId: z.ZodNumber;
74
+ /** Human-readable description of what this revoke does */
75
+ description: z.ZodString;
76
+ }, "strip", z.ZodTypeAny, {
77
+ description: string;
78
+ to: string;
79
+ data: string;
80
+ chainId: number;
81
+ }, {
82
+ description: string;
83
+ to: string;
84
+ data: string;
85
+ chainId: number;
86
+ }>;
87
+ /** @see {@link RevokeTxSchema} */
88
+ export type RevokeTx = z.infer<typeof RevokeTxSchema>;
89
+ /**
90
+ * Full result of a wallet security scan.
91
+ *
92
+ * **Security invariant**: `safe` is always `false` when payment was not
93
+ * successfully verified. Never trust `safe: true` from an unpaid response.
94
+ */
95
+ export declare const ScanResultSchema: z.ZodObject<{
96
+ /** Unique identifier for this scan (for audit/logging) */
97
+ scanId: z.ZodString;
98
+ /**
99
+ * Whether the wallet is considered safe.
100
+ * This value is overridden to `false` if payment was not verified.
101
+ */
102
+ safe: z.ZodBoolean;
103
+ /** Risk score from 0 (clean) to 100 (critical risk) */
104
+ risk: z.ZodNumber;
105
+ /** List of security findings */
106
+ findings: z.ZodArray<z.ZodObject<{
107
+ /** Machine-readable finding type (e.g. "unlimited_approval", "known_drainer") */
108
+ type: z.ZodString;
109
+ /** Severity of the finding */
110
+ severity: z.ZodEnum<["critical", "high", "medium", "low", "info"]>;
111
+ /** Human-readable description */
112
+ description: z.ZodString;
113
+ /** Relevant contract or counterparty address, if applicable */
114
+ address: z.ZodOptional<z.ZodString>;
115
+ /** Protocol name associated with the finding, if known */
116
+ protocol: z.ZodOptional<z.ZodString>;
117
+ /** Token amount at risk (human-readable), if applicable */
118
+ amount: z.ZodOptional<z.ZodString>;
119
+ }, "strip", z.ZodTypeAny, {
120
+ type: string;
121
+ severity: "critical" | "high" | "medium" | "low" | "info";
122
+ description: string;
123
+ address?: string | undefined;
124
+ protocol?: string | undefined;
125
+ amount?: string | undefined;
126
+ }, {
127
+ type: string;
128
+ severity: "critical" | "high" | "medium" | "low" | "info";
129
+ description: string;
130
+ address?: string | undefined;
131
+ protocol?: string | undefined;
132
+ amount?: string | undefined;
133
+ }>, "many">;
134
+ /** Pre-built revoke transactions for risky approvals */
135
+ revokeTxs: z.ZodArray<z.ZodObject<{
136
+ /** Target contract address (the token contract) */
137
+ to: z.ZodString;
138
+ /** ABI-encoded calldata (e.g., `approve(spender, 0)`) */
139
+ data: z.ZodString;
140
+ /** EVM chain ID (e.g., 8453 for Base) */
141
+ chainId: z.ZodNumber;
142
+ /** Human-readable description of what this revoke does */
143
+ description: z.ZodString;
144
+ }, "strip", z.ZodTypeAny, {
145
+ description: string;
146
+ to: string;
147
+ data: string;
148
+ chainId: number;
149
+ }, {
150
+ description: string;
151
+ to: string;
152
+ data: string;
153
+ chainId: number;
154
+ }>, "many">;
155
+ }, "strip", z.ZodTypeAny, {
156
+ scanId: string;
157
+ safe: boolean;
158
+ risk: number;
159
+ findings: {
160
+ type: string;
161
+ severity: "critical" | "high" | "medium" | "low" | "info";
162
+ description: string;
163
+ address?: string | undefined;
164
+ protocol?: string | undefined;
165
+ amount?: string | undefined;
166
+ }[];
167
+ revokeTxs: {
168
+ description: string;
169
+ to: string;
170
+ data: string;
171
+ chainId: number;
172
+ }[];
173
+ }, {
174
+ scanId: string;
175
+ safe: boolean;
176
+ risk: number;
177
+ findings: {
178
+ type: string;
179
+ severity: "critical" | "high" | "medium" | "low" | "info";
180
+ description: string;
181
+ address?: string | undefined;
182
+ protocol?: string | undefined;
183
+ amount?: string | undefined;
184
+ }[];
185
+ revokeTxs: {
186
+ description: string;
187
+ to: string;
188
+ data: string;
189
+ chainId: number;
190
+ }[];
191
+ }>;
192
+ /** @see {@link ScanResultSchema} */
193
+ export type ScanResult = z.infer<typeof ScanResultSchema>;
194
+ /**
195
+ * A single ERC-20 token approval with risk assessment.
196
+ */
197
+ export declare const ApprovalSchema: z.ZodObject<{
198
+ /** Address that has been approved to spend tokens */
199
+ spender: z.ZodString;
200
+ /** Token contract address */
201
+ token: z.ZodString;
202
+ /** Token symbol (e.g., "USDC"), if known */
203
+ tokenSymbol: z.ZodOptional<z.ZodString>;
204
+ /** Approved allowance amount (as string to handle large values) */
205
+ allowance: z.ZodString;
206
+ /** Risk level of this approval */
207
+ risk: z.ZodEnum<["low", "medium", "high", "critical"]>;
208
+ /** Human-readable details about why this is risky */
209
+ details: z.ZodOptional<z.ZodString>;
210
+ }, "strip", z.ZodTypeAny, {
211
+ risk: "critical" | "high" | "medium" | "low";
212
+ spender: string;
213
+ token: string;
214
+ allowance: string;
215
+ tokenSymbol?: string | undefined;
216
+ details?: string | undefined;
217
+ }, {
218
+ risk: "critical" | "high" | "medium" | "low";
219
+ spender: string;
220
+ token: string;
221
+ allowance: string;
222
+ tokenSymbol?: string | undefined;
223
+ details?: string | undefined;
224
+ }>;
225
+ /** @see {@link ApprovalSchema} */
226
+ export type Approval = z.infer<typeof ApprovalSchema>;
227
+ /**
228
+ * Aggregated approvals result for a wallet.
229
+ */
230
+ export declare const ApprovalsResultSchema: z.ZodObject<{
231
+ /** The wallet address that was queried */
232
+ wallet: z.ZodString;
233
+ /** All active token approvals */
234
+ approvals: z.ZodArray<z.ZodObject<{
235
+ /** Address that has been approved to spend tokens */
236
+ spender: z.ZodString;
237
+ /** Token contract address */
238
+ token: z.ZodString;
239
+ /** Token symbol (e.g., "USDC"), if known */
240
+ tokenSymbol: z.ZodOptional<z.ZodString>;
241
+ /** Approved allowance amount (as string to handle large values) */
242
+ allowance: z.ZodString;
243
+ /** Risk level of this approval */
244
+ risk: z.ZodEnum<["low", "medium", "high", "critical"]>;
245
+ /** Human-readable details about why this is risky */
246
+ details: z.ZodOptional<z.ZodString>;
247
+ }, "strip", z.ZodTypeAny, {
248
+ risk: "critical" | "high" | "medium" | "low";
249
+ spender: string;
250
+ token: string;
251
+ allowance: string;
252
+ tokenSymbol?: string | undefined;
253
+ details?: string | undefined;
254
+ }, {
255
+ risk: "critical" | "high" | "medium" | "low";
256
+ spender: string;
257
+ token: string;
258
+ allowance: string;
259
+ tokenSymbol?: string | undefined;
260
+ details?: string | undefined;
261
+ }>, "many">;
262
+ /** Count of approvals at each risk level */
263
+ riskCount: z.ZodObject<{
264
+ low: z.ZodNumber;
265
+ medium: z.ZodNumber;
266
+ high: z.ZodNumber;
267
+ critical: z.ZodNumber;
268
+ }, "strip", z.ZodTypeAny, {
269
+ critical: number;
270
+ high: number;
271
+ medium: number;
272
+ low: number;
273
+ }, {
274
+ critical: number;
275
+ high: number;
276
+ medium: number;
277
+ low: number;
278
+ }>;
279
+ }, "strip", z.ZodTypeAny, {
280
+ wallet: string;
281
+ approvals: {
282
+ risk: "critical" | "high" | "medium" | "low";
283
+ spender: string;
284
+ token: string;
285
+ allowance: string;
286
+ tokenSymbol?: string | undefined;
287
+ details?: string | undefined;
288
+ }[];
289
+ riskCount: {
290
+ critical: number;
291
+ high: number;
292
+ medium: number;
293
+ low: number;
294
+ };
295
+ }, {
296
+ wallet: string;
297
+ approvals: {
298
+ risk: "critical" | "high" | "medium" | "low";
299
+ spender: string;
300
+ token: string;
301
+ allowance: string;
302
+ tokenSymbol?: string | undefined;
303
+ details?: string | undefined;
304
+ }[];
305
+ riskCount: {
306
+ critical: number;
307
+ high: number;
308
+ medium: number;
309
+ low: number;
310
+ };
311
+ }>;
312
+ /** @see {@link ApprovalsResultSchema} */
313
+ export type ApprovalsResult = z.infer<typeof ApprovalsResultSchema>;
314
+ /**
315
+ * API health status.
316
+ */
317
+ export declare const HealthResultSchema: z.ZodObject<{
318
+ /** Service health status */
319
+ status: z.ZodEnum<["ok", "degraded", "down"]>;
320
+ /** API version string, if available */
321
+ version: z.ZodOptional<z.ZodString>;
322
+ /** Process uptime in seconds, if available */
323
+ uptime: z.ZodOptional<z.ZodNumber>;
324
+ }, "strip", z.ZodTypeAny, {
325
+ status: "ok" | "degraded" | "down";
326
+ version?: string | undefined;
327
+ uptime?: number | undefined;
328
+ }, {
329
+ status: "ok" | "degraded" | "down";
330
+ version?: string | undefined;
331
+ uptime?: number | undefined;
332
+ }>;
333
+ /** @see {@link HealthResultSchema} */
334
+ export type HealthResult = z.infer<typeof HealthResultSchema>;
335
+ /**
336
+ * Payment requirements parsed from a 402 response.
337
+ * Used internally by JanusClient to build the payment signature.
338
+ */
339
+ export declare const PaymentRequirementsSchema: z.ZodObject<{
340
+ /** Payment scheme (currently only "exact" is supported) */
341
+ scheme: z.ZodString;
342
+ /** CAIP-2 network identifier (e.g., "eip155:8453") */
343
+ network: z.ZodString;
344
+ /** Maximum amount required in token atomic units */
345
+ maxAmountRequired: z.ZodString;
346
+ /** Payment token contract address (Base USDC) */
347
+ asset: z.ZodString;
348
+ /** Payment recipient address */
349
+ payTo: z.ZodString;
350
+ /** Maximum seconds the payment authorization is valid for */
351
+ maxTimeoutSeconds: z.ZodNumber;
352
+ /** Extra EIP-712 domain metadata (name, version, etc.) */
353
+ extra: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
354
+ }, "strip", z.ZodTypeAny, {
355
+ scheme: string;
356
+ network: string;
357
+ maxAmountRequired: string;
358
+ asset: string;
359
+ payTo: string;
360
+ maxTimeoutSeconds: number;
361
+ extra?: Record<string, unknown> | undefined;
362
+ }, {
363
+ scheme: string;
364
+ network: string;
365
+ maxAmountRequired: string;
366
+ asset: string;
367
+ payTo: string;
368
+ maxTimeoutSeconds: number;
369
+ extra?: Record<string, unknown> | undefined;
370
+ }>;
371
+ /** @see {@link PaymentRequirementsSchema} */
372
+ export type PaymentRequirements = z.infer<typeof PaymentRequirementsSchema>;
373
+ /**
374
+ * Configuration for {@link JanusClient}.
375
+ */
376
+ export interface JanusClientConfig {
377
+ /**
378
+ * Base URL for the x402janus API.
379
+ * @default "https://x402janus.com"
380
+ */
381
+ baseUrl?: string | undefined;
382
+ /**
383
+ * Agent's private key for signing x402 micropayments.
384
+ * Required for paid tiers (standard, deep).
385
+ * Falls back to `process.env.PRIVATE_KEY` if not set.
386
+ *
387
+ * **Security**: The private key is stored in memory only and never
388
+ * exposed in error messages, logs, or API responses.
389
+ */
390
+ privateKey?: string | undefined;
391
+ /**
392
+ * Default scan tier when not specified per-call.
393
+ * @default "quick"
394
+ */
395
+ defaultTier?: ScanTier | undefined;
396
+ /**
397
+ * Thirdweb/x402 facilitator URL for payment verification.
398
+ * Falls back to `process.env.FACILITATOR_URL` then the Thirdweb default.
399
+ * @default "https://api.thirdweb.com/v1/payments/x402"
400
+ */
401
+ facilitatorUrl?: string | undefined;
402
+ }
403
+ /**
404
+ * Options for a single wallet scan call.
405
+ */
406
+ export interface ScanOptions {
407
+ /**
408
+ * Override the default tier for this scan.
409
+ */
410
+ tier?: ScanTier | undefined;
411
+ }
412
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @module types
3
+ * All public types and Zod schemas for @x402janus/sdk.
4
+ */
5
+ import { z } from "zod";
6
+ // ─── Tier ────────────────────────────────────────────────────────────────────
7
+ /**
8
+ * Scan tier controlling analysis depth and x402 micropayment amount.
9
+ *
10
+ * | Tier | Price | Description |
11
+ * |----------|--------|-----------------------------------------------------|
12
+ * | quick | $0.01 | Fast heuristic scan — known drainers & risk signals |
13
+ * | standard | $0.05 | Graph analysis + threat-intel correlation |
14
+ * | deep | $0.25 | Full forensic scan + approval chain tracing |
15
+ */
16
+ export const ScanTierSchema = z.enum(["quick", "standard", "deep"]);
17
+ /**
18
+ * USDC pricing for each scan tier (6-decimal precision, Base mainnet).
19
+ * `units` is the raw USDC atomic value passed in the x402 payment header.
20
+ */
21
+ export const TIER_PRICES = {
22
+ quick: { dollars: "$0.01", units: "10000" },
23
+ standard: { dollars: "$0.05", units: "50000" },
24
+ deep: { dollars: "$0.25", units: "250000" },
25
+ };
26
+ /**
27
+ * A single security finding returned in a wallet scan.
28
+ */
29
+ export const FindingSchema = z.object({
30
+ /** Machine-readable finding type (e.g. "unlimited_approval", "known_drainer") */
31
+ type: z.string(),
32
+ /** Severity of the finding */
33
+ severity: z.enum(["critical", "high", "medium", "low", "info"]),
34
+ /** Human-readable description */
35
+ description: z.string(),
36
+ /** Relevant contract or counterparty address, if applicable */
37
+ address: z.string().optional(),
38
+ /** Protocol name associated with the finding, if known */
39
+ protocol: z.string().optional(),
40
+ /** Token amount at risk (human-readable), if applicable */
41
+ amount: z.string().optional(),
42
+ });
43
+ // ─── RevokeTx ────────────────────────────────────────────────────────────────
44
+ /**
45
+ * A revoke transaction that the agent can sign and submit to remove a risky approval.
46
+ * Transactions are pre-built by the x402janus API — submit them as-is.
47
+ */
48
+ export const RevokeTxSchema = z.object({
49
+ /** Target contract address (the token contract) */
50
+ to: z.string(),
51
+ /** ABI-encoded calldata (e.g., `approve(spender, 0)`) */
52
+ data: z.string(),
53
+ /** EVM chain ID (e.g., 8453 for Base) */
54
+ chainId: z.number().int().positive(),
55
+ /** Human-readable description of what this revoke does */
56
+ description: z.string(),
57
+ });
58
+ // ─── ScanResult ──────────────────────────────────────────────────────────────
59
+ /**
60
+ * Full result of a wallet security scan.
61
+ *
62
+ * **Security invariant**: `safe` is always `false` when payment was not
63
+ * successfully verified. Never trust `safe: true` from an unpaid response.
64
+ */
65
+ export const ScanResultSchema = z.object({
66
+ /** Unique identifier for this scan (for audit/logging) */
67
+ scanId: z.string(),
68
+ /**
69
+ * Whether the wallet is considered safe.
70
+ * This value is overridden to `false` if payment was not verified.
71
+ */
72
+ safe: z.boolean(),
73
+ /** Risk score from 0 (clean) to 100 (critical risk) */
74
+ risk: z.number().min(0).max(100),
75
+ /** List of security findings */
76
+ findings: z.array(FindingSchema),
77
+ /** Pre-built revoke transactions for risky approvals */
78
+ revokeTxs: z.array(RevokeTxSchema),
79
+ });
80
+ // ─── Approvals ───────────────────────────────────────────────────────────────
81
+ /**
82
+ * A single ERC-20 token approval with risk assessment.
83
+ */
84
+ export const ApprovalSchema = z.object({
85
+ /** Address that has been approved to spend tokens */
86
+ spender: z.string(),
87
+ /** Token contract address */
88
+ token: z.string(),
89
+ /** Token symbol (e.g., "USDC"), if known */
90
+ tokenSymbol: z.string().optional(),
91
+ /** Approved allowance amount (as string to handle large values) */
92
+ allowance: z.string(),
93
+ /** Risk level of this approval */
94
+ risk: z.enum(["low", "medium", "high", "critical"]),
95
+ /** Human-readable details about why this is risky */
96
+ details: z.string().optional(),
97
+ });
98
+ /**
99
+ * Aggregated approvals result for a wallet.
100
+ */
101
+ export const ApprovalsResultSchema = z.object({
102
+ /** The wallet address that was queried */
103
+ wallet: z.string(),
104
+ /** All active token approvals */
105
+ approvals: z.array(ApprovalSchema),
106
+ /** Count of approvals at each risk level */
107
+ riskCount: z.object({
108
+ low: z.number().int().min(0),
109
+ medium: z.number().int().min(0),
110
+ high: z.number().int().min(0),
111
+ critical: z.number().int().min(0),
112
+ }),
113
+ });
114
+ // ─── Health ──────────────────────────────────────────────────────────────────
115
+ /**
116
+ * API health status.
117
+ */
118
+ export const HealthResultSchema = z.object({
119
+ /** Service health status */
120
+ status: z.enum(["ok", "degraded", "down"]),
121
+ /** API version string, if available */
122
+ version: z.string().optional(),
123
+ /** Process uptime in seconds, if available */
124
+ uptime: z.number().optional(),
125
+ });
126
+ // ─── x402 Payment Requirements ───────────────────────────────────────────────
127
+ /**
128
+ * Payment requirements parsed from a 402 response.
129
+ * Used internally by JanusClient to build the payment signature.
130
+ */
131
+ export const PaymentRequirementsSchema = z.object({
132
+ /** Payment scheme (currently only "exact" is supported) */
133
+ scheme: z.string(),
134
+ /** CAIP-2 network identifier (e.g., "eip155:8453") */
135
+ network: z.string(),
136
+ /** Maximum amount required in token atomic units */
137
+ maxAmountRequired: z.string().regex(/^\d+$/, "must be a decimal integer string"),
138
+ /** Payment token contract address (Base USDC) */
139
+ asset: z.string(),
140
+ /** Payment recipient address */
141
+ payTo: z.string(),
142
+ /** Maximum seconds the payment authorization is valid for */
143
+ maxTimeoutSeconds: z.number().int().positive(),
144
+ /** Extra EIP-712 domain metadata (name, version, etc.) */
145
+ extra: z.record(z.unknown()).optional(),
146
+ });
147
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@x402janus/sdk",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for x402janus wallet security scans with automatic x402 micropayment handling",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "type-check": "tsc --noEmit",
21
+ "clean": "rm -rf dist"
22
+ },
23
+ "dependencies": {
24
+ "viem": "^2.21.0",
25
+ "zod": "^3.22.0"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "registry": "https://registry.npmjs.org/"
30
+ },
31
+ "keywords": [
32
+ "x402",
33
+ "wallet",
34
+ "security",
35
+ "scan",
36
+ "base",
37
+ "ethereum",
38
+ "drainer",
39
+ "approvals",
40
+ "ai-agent"
41
+ ],
42
+ "license": "MIT",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/x402janus/sdk"
46
+ },
47
+ "devDependencies": {
48
+ "typescript": "^5.9.3"
49
+ }
50
+ }